value-prof.c (tree_stringops_transform): New.
[gcc.git] / gcc / builtins.c
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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.
11
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.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
50 #include "tree-flow.h"
51
52 #ifndef PAD_VARARGS_DOWN
53 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
54 #endif
55
56 /* Define the names of the builtin function types and codes. */
57 const char *const built_in_class_names[4]
58 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59
60 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
61 const char * built_in_names[(int) END_BUILTINS] =
62 {
63 #include "builtins.def"
64 };
65 #undef DEF_BUILTIN
66
67 /* Setup an array of _DECL trees, make sure each element is
68 initialized to NULL_TREE. */
69 tree built_in_decls[(int) END_BUILTINS];
70 /* Declarations used when constructing the builtin implicitly in the compiler.
71 It may be NULL_TREE when this is invalid (for instance runtime is not
72 required to implement the function call in all cases). */
73 tree implicit_built_in_decls[(int) END_BUILTINS];
74
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static void expand_builtin_update_setjmp_buf (rtx);
85 static void expand_builtin_prefetch (tree);
86 static rtx expand_builtin_apply_args (void);
87 static rtx expand_builtin_apply_args_1 (void);
88 static rtx expand_builtin_apply (rtx, rtx, rtx);
89 static void expand_builtin_return (rtx);
90 static enum type_class type_to_class (tree);
91 static rtx expand_builtin_classify_type (tree);
92 static void expand_errno_check (tree, rtx);
93 static rtx expand_builtin_mathfn (tree, rtx, rtx);
94 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
96 static rtx expand_builtin_sincos (tree);
97 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
98 static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
122 static rtx expand_builtin_bzero (tree);
123 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, rtx);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static rtx expand_builtin_fputs (tree, rtx, bool);
132 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135 static tree stabilize_va_list (tree, int);
136 static rtx expand_builtin_expect (tree, rtx);
137 static tree fold_builtin_constant_p (tree);
138 static tree fold_builtin_classify_type (tree);
139 static tree fold_builtin_strlen (tree);
140 static tree fold_builtin_inf (tree, int);
141 static tree fold_builtin_nan (tree, tree, int);
142 static bool integer_valued_real_p (tree);
143 static tree fold_trunc_transparent_mathfn (tree, tree);
144 static bool readonly_data_expr (tree);
145 static rtx expand_builtin_fabs (tree, rtx, rtx);
146 static rtx expand_builtin_signbit (tree, rtx);
147 static tree fold_builtin_sqrt (tree, tree);
148 static tree fold_builtin_cbrt (tree, tree);
149 static tree fold_builtin_pow (tree, tree, tree);
150 static tree fold_builtin_powi (tree, tree, tree);
151 static tree fold_builtin_cos (tree, tree, tree);
152 static tree fold_builtin_cosh (tree, tree, tree);
153 static tree fold_builtin_tan (tree, tree);
154 static tree fold_builtin_trunc (tree, tree);
155 static tree fold_builtin_floor (tree, tree);
156 static tree fold_builtin_ceil (tree, tree);
157 static tree fold_builtin_round (tree, tree);
158 static tree fold_builtin_int_roundingfn (tree, tree);
159 static tree fold_builtin_bitop (tree, tree);
160 static tree fold_builtin_memory_op (tree, tree, bool, int);
161 static tree fold_builtin_strchr (tree, tree);
162 static tree fold_builtin_memcmp (tree);
163 static tree fold_builtin_strcmp (tree);
164 static tree fold_builtin_strncmp (tree);
165 static tree fold_builtin_signbit (tree, tree);
166 static tree fold_builtin_copysign (tree, tree, tree);
167 static tree fold_builtin_isascii (tree);
168 static tree fold_builtin_toascii (tree);
169 static tree fold_builtin_isdigit (tree);
170 static tree fold_builtin_fabs (tree, tree);
171 static tree fold_builtin_abs (tree, tree);
172 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
173 enum tree_code);
174 static tree fold_builtin_1 (tree, tree, bool);
175
176 static tree fold_builtin_strpbrk (tree, tree);
177 static tree fold_builtin_strstr (tree, tree);
178 static tree fold_builtin_strrchr (tree, tree);
179 static tree fold_builtin_strcat (tree);
180 static tree fold_builtin_strncat (tree);
181 static tree fold_builtin_strspn (tree);
182 static tree fold_builtin_strcspn (tree);
183 static tree fold_builtin_sprintf (tree, int);
184
185 static rtx expand_builtin_object_size (tree);
186 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
187 enum built_in_function);
188 static void maybe_emit_chk_warning (tree, enum built_in_function);
189 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
190 static tree fold_builtin_object_size (tree);
191 static tree fold_builtin_strcat_chk (tree, tree);
192 static tree fold_builtin_strncat_chk (tree, tree);
193 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
194 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
195 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
196 static bool init_target_chars (void);
197
198 static unsigned HOST_WIDE_INT target_newline;
199 static unsigned HOST_WIDE_INT target_percent;
200 static unsigned HOST_WIDE_INT target_c;
201 static unsigned HOST_WIDE_INT target_s;
202 static char target_percent_c[3];
203 static char target_percent_s[3];
204 static char target_percent_s_newline[4];
205 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
206 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
207 static tree do_mpfr_arg2 (tree, tree, tree,
208 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
209 static tree do_mpfr_arg3 (tree, tree, tree, tree,
210 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
211 static tree do_mpfr_sincos (tree, tree, tree);
212
213 /* Return true if NODE should be considered for inline expansion regardless
214 of the optimization level. This means whenever a function is invoked with
215 its "internal" name, which normally contains the prefix "__builtin". */
216
217 static bool called_as_built_in (tree node)
218 {
219 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
220 if (strncmp (name, "__builtin_", 10) == 0)
221 return true;
222 if (strncmp (name, "__sync_", 7) == 0)
223 return true;
224 return false;
225 }
226
227 /* Return the alignment in bits of EXP, a pointer valued expression.
228 But don't return more than MAX_ALIGN no matter what.
229 The alignment returned is, by default, the alignment of the thing that
230 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231
232 Otherwise, look at the expression to see if we can do better, i.e., if the
233 expression is actually pointing at an object whose alignment is tighter. */
234
235 int
236 get_pointer_alignment (tree exp, unsigned int max_align)
237 {
238 unsigned int align, inner;
239
240 /* We rely on TER to compute accurate alignment information. */
241 if (!(optimize && flag_tree_ter))
242 return 0;
243
244 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
245 return 0;
246
247 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
248 align = MIN (align, max_align);
249
250 while (1)
251 {
252 switch (TREE_CODE (exp))
253 {
254 case NOP_EXPR:
255 case CONVERT_EXPR:
256 case NON_LVALUE_EXPR:
257 exp = TREE_OPERAND (exp, 0);
258 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
259 return align;
260
261 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
262 align = MIN (inner, max_align);
263 break;
264
265 case PLUS_EXPR:
266 /* If sum of pointer + int, restrict our maximum alignment to that
267 imposed by the integer. If not, we can't do any better than
268 ALIGN. */
269 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
270 return align;
271
272 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
273 & (max_align / BITS_PER_UNIT - 1))
274 != 0)
275 max_align >>= 1;
276
277 exp = TREE_OPERAND (exp, 0);
278 break;
279
280 case ADDR_EXPR:
281 /* See what we are pointing at and look at its alignment. */
282 exp = TREE_OPERAND (exp, 0);
283 inner = max_align;
284 if (handled_component_p (exp))
285 {
286 HOST_WIDE_INT bitsize, bitpos;
287 tree offset;
288 enum machine_mode mode;
289 int unsignedp, volatilep;
290
291 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
292 &mode, &unsignedp, &volatilep, true);
293 if (bitpos)
294 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
295 if (offset && TREE_CODE (offset) == PLUS_EXPR
296 && host_integerp (TREE_OPERAND (offset, 1), 1))
297 {
298 /* Any overflow in calculating offset_bits won't change
299 the alignment. */
300 unsigned offset_bits
301 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
302 * BITS_PER_UNIT);
303
304 if (offset_bits)
305 inner = MIN (inner, (offset_bits & -offset_bits));
306 offset = TREE_OPERAND (offset, 0);
307 }
308 if (offset && TREE_CODE (offset) == MULT_EXPR
309 && host_integerp (TREE_OPERAND (offset, 1), 1))
310 {
311 /* Any overflow in calculating offset_factor won't change
312 the alignment. */
313 unsigned offset_factor
314 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
315 * BITS_PER_UNIT);
316
317 if (offset_factor)
318 inner = MIN (inner, (offset_factor & -offset_factor));
319 }
320 else if (offset)
321 inner = MIN (inner, BITS_PER_UNIT);
322 }
323 if (TREE_CODE (exp) == FUNCTION_DECL)
324 align = FUNCTION_BOUNDARY;
325 else if (DECL_P (exp))
326 align = MIN (inner, DECL_ALIGN (exp));
327 #ifdef CONSTANT_ALIGNMENT
328 else if (CONSTANT_CLASS_P (exp))
329 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
330 #endif
331 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
332 || TREE_CODE (exp) == INDIRECT_REF)
333 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
334 else
335 align = MIN (align, inner);
336 return MIN (align, max_align);
337
338 default:
339 return align;
340 }
341 }
342 }
343
344 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
345 way, because it could contain a zero byte in the middle.
346 TREE_STRING_LENGTH is the size of the character array, not the string.
347
348 ONLY_VALUE should be nonzero if the result is not going to be emitted
349 into the instruction stream and zero if it is going to be expanded.
350 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
351 is returned, otherwise NULL, since
352 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
353 evaluate the side-effects.
354
355 The value returned is of type `ssizetype'.
356
357 Unfortunately, string_constant can't access the values of const char
358 arrays with initializers, so neither can we do so here. */
359
360 tree
361 c_strlen (tree src, int only_value)
362 {
363 tree offset_node;
364 HOST_WIDE_INT offset;
365 int max;
366 const char *ptr;
367
368 STRIP_NOPS (src);
369 if (TREE_CODE (src) == COND_EXPR
370 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
371 {
372 tree len1, len2;
373
374 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
375 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
376 if (tree_int_cst_equal (len1, len2))
377 return len1;
378 }
379
380 if (TREE_CODE (src) == COMPOUND_EXPR
381 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
382 return c_strlen (TREE_OPERAND (src, 1), only_value);
383
384 src = string_constant (src, &offset_node);
385 if (src == 0)
386 return 0;
387
388 max = TREE_STRING_LENGTH (src) - 1;
389 ptr = TREE_STRING_POINTER (src);
390
391 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
392 {
393 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
394 compute the offset to the following null if we don't know where to
395 start searching for it. */
396 int i;
397
398 for (i = 0; i < max; i++)
399 if (ptr[i] == 0)
400 return 0;
401
402 /* We don't know the starting offset, but we do know that the string
403 has no internal zero bytes. We can assume that the offset falls
404 within the bounds of the string; otherwise, the programmer deserves
405 what he gets. Subtract the offset from the length of the string,
406 and return that. This would perhaps not be valid if we were dealing
407 with named arrays in addition to literal string constants. */
408
409 return size_diffop (size_int (max), offset_node);
410 }
411
412 /* We have a known offset into the string. Start searching there for
413 a null character if we can represent it as a single HOST_WIDE_INT. */
414 if (offset_node == 0)
415 offset = 0;
416 else if (! host_integerp (offset_node, 0))
417 offset = -1;
418 else
419 offset = tree_low_cst (offset_node, 0);
420
421 /* If the offset is known to be out of bounds, warn, and call strlen at
422 runtime. */
423 if (offset < 0 || offset > max)
424 {
425 warning (0, "offset outside bounds of constant string");
426 return 0;
427 }
428
429 /* Use strlen to search for the first zero byte. Since any strings
430 constructed with build_string will have nulls appended, we win even
431 if we get handed something like (char[4])"abcd".
432
433 Since OFFSET is our starting index into the string, no further
434 calculation is needed. */
435 return ssize_int (strlen (ptr + offset));
436 }
437
438 /* Return a char pointer for a C string if it is a string constant
439 or sum of string constant and integer constant. */
440
441 static const char *
442 c_getstr (tree src)
443 {
444 tree offset_node;
445
446 src = string_constant (src, &offset_node);
447 if (src == 0)
448 return 0;
449
450 if (offset_node == 0)
451 return TREE_STRING_POINTER (src);
452 else if (!host_integerp (offset_node, 1)
453 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
454 return 0;
455
456 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
457 }
458
459 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
460 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
461
462 static rtx
463 c_readstr (const char *str, enum machine_mode mode)
464 {
465 HOST_WIDE_INT c[2];
466 HOST_WIDE_INT ch;
467 unsigned int i, j;
468
469 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
470
471 c[0] = 0;
472 c[1] = 0;
473 ch = 1;
474 for (i = 0; i < GET_MODE_SIZE (mode); i++)
475 {
476 j = i;
477 if (WORDS_BIG_ENDIAN)
478 j = GET_MODE_SIZE (mode) - i - 1;
479 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
480 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
481 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
482 j *= BITS_PER_UNIT;
483 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
484
485 if (ch)
486 ch = (unsigned char) str[i];
487 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
488 }
489 return immed_double_const (c[0], c[1], mode);
490 }
491
492 /* Cast a target constant CST to target CHAR and if that value fits into
493 host char type, return zero and put that value into variable pointed to by
494 P. */
495
496 static int
497 target_char_cast (tree cst, char *p)
498 {
499 unsigned HOST_WIDE_INT val, hostval;
500
501 if (!host_integerp (cst, 1)
502 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
503 return 1;
504
505 val = tree_low_cst (cst, 1);
506 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
507 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
508
509 hostval = val;
510 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
511 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
512
513 if (val != hostval)
514 return 1;
515
516 *p = hostval;
517 return 0;
518 }
519
520 /* Similar to save_expr, but assumes that arbitrary code is not executed
521 in between the multiple evaluations. In particular, we assume that a
522 non-addressable local variable will not be modified. */
523
524 static tree
525 builtin_save_expr (tree exp)
526 {
527 if (TREE_ADDRESSABLE (exp) == 0
528 && (TREE_CODE (exp) == PARM_DECL
529 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
530 return exp;
531
532 return save_expr (exp);
533 }
534
535 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
536 times to get the address of either a higher stack frame, or a return
537 address located within it (depending on FNDECL_CODE). */
538
539 static rtx
540 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
541 {
542 int i;
543
544 #ifdef INITIAL_FRAME_ADDRESS_RTX
545 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
546 #else
547 rtx tem;
548
549 /* For a zero count with __builtin_return_address, we don't care what
550 frame address we return, because target-specific definitions will
551 override us. Therefore frame pointer elimination is OK, and using
552 the soft frame pointer is OK.
553
554 For a nonzero count, or a zero count with __builtin_frame_address,
555 we require a stable offset from the current frame pointer to the
556 previous one, so we must use the hard frame pointer, and
557 we must disable frame pointer elimination. */
558 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
559 tem = frame_pointer_rtx;
560 else
561 {
562 tem = hard_frame_pointer_rtx;
563
564 /* Tell reload not to eliminate the frame pointer. */
565 current_function_accesses_prior_frames = 1;
566 }
567 #endif
568
569 /* Some machines need special handling before we can access
570 arbitrary frames. For example, on the SPARC, we must first flush
571 all register windows to the stack. */
572 #ifdef SETUP_FRAME_ADDRESSES
573 if (count > 0)
574 SETUP_FRAME_ADDRESSES ();
575 #endif
576
577 /* On the SPARC, the return address is not in the frame, it is in a
578 register. There is no way to access it off of the current frame
579 pointer, but it can be accessed off the previous frame pointer by
580 reading the value from the register window save area. */
581 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
582 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
583 count--;
584 #endif
585
586 /* Scan back COUNT frames to the specified frame. */
587 for (i = 0; i < count; i++)
588 {
589 /* Assume the dynamic chain pointer is in the word that the
590 frame address points to, unless otherwise specified. */
591 #ifdef DYNAMIC_CHAIN_ADDRESS
592 tem = DYNAMIC_CHAIN_ADDRESS (tem);
593 #endif
594 tem = memory_address (Pmode, tem);
595 tem = gen_frame_mem (Pmode, tem);
596 tem = copy_to_reg (tem);
597 }
598
599 /* For __builtin_frame_address, return what we've got. But, on
600 the SPARC for example, we may have to add a bias. */
601 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
602 #ifdef FRAME_ADDR_RTX
603 return FRAME_ADDR_RTX (tem);
604 #else
605 return tem;
606 #endif
607
608 /* For __builtin_return_address, get the return address from that frame. */
609 #ifdef RETURN_ADDR_RTX
610 tem = RETURN_ADDR_RTX (count, tem);
611 #else
612 tem = memory_address (Pmode,
613 plus_constant (tem, GET_MODE_SIZE (Pmode)));
614 tem = gen_frame_mem (Pmode, tem);
615 #endif
616 return tem;
617 }
618
619 /* Alias set used for setjmp buffer. */
620 static HOST_WIDE_INT setjmp_alias_set = -1;
621
622 /* Construct the leading half of a __builtin_setjmp call. Control will
623 return to RECEIVER_LABEL. This is also called directly by the SJLJ
624 exception handling code. */
625
626 void
627 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
628 {
629 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
630 rtx stack_save;
631 rtx mem;
632
633 if (setjmp_alias_set == -1)
634 setjmp_alias_set = new_alias_set ();
635
636 buf_addr = convert_memory_address (Pmode, buf_addr);
637
638 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
639
640 /* We store the frame pointer and the address of receiver_label in
641 the buffer and use the rest of it for the stack save area, which
642 is machine-dependent. */
643
644 mem = gen_rtx_MEM (Pmode, buf_addr);
645 set_mem_alias_set (mem, setjmp_alias_set);
646 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
647
648 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
649 set_mem_alias_set (mem, setjmp_alias_set);
650
651 emit_move_insn (validize_mem (mem),
652 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
653
654 stack_save = gen_rtx_MEM (sa_mode,
655 plus_constant (buf_addr,
656 2 * GET_MODE_SIZE (Pmode)));
657 set_mem_alias_set (stack_save, setjmp_alias_set);
658 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
659
660 /* If there is further processing to do, do it. */
661 #ifdef HAVE_builtin_setjmp_setup
662 if (HAVE_builtin_setjmp_setup)
663 emit_insn (gen_builtin_setjmp_setup (buf_addr));
664 #endif
665
666 /* Tell optimize_save_area_alloca that extra work is going to
667 need to go on during alloca. */
668 current_function_calls_setjmp = 1;
669
670 /* Set this so all the registers get saved in our frame; we need to be
671 able to copy the saved values for any registers from frames we unwind. */
672 current_function_has_nonlocal_label = 1;
673 }
674
675 /* Construct the trailing part of a __builtin_setjmp call. This is
676 also called directly by the SJLJ exception handling code. */
677
678 void
679 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
680 {
681 /* Clobber the FP when we get here, so we have to make sure it's
682 marked as used by this function. */
683 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
684
685 /* Mark the static chain as clobbered here so life information
686 doesn't get messed up for it. */
687 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
688
689 /* Now put in the code to restore the frame pointer, and argument
690 pointer, if needed. */
691 #ifdef HAVE_nonlocal_goto
692 if (! HAVE_nonlocal_goto)
693 #endif
694 {
695 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
696 /* This might change the hard frame pointer in ways that aren't
697 apparent to early optimization passes, so force a clobber. */
698 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
699 }
700
701 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
702 if (fixed_regs[ARG_POINTER_REGNUM])
703 {
704 #ifdef ELIMINABLE_REGS
705 size_t i;
706 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
707
708 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
709 if (elim_regs[i].from == ARG_POINTER_REGNUM
710 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
711 break;
712
713 if (i == ARRAY_SIZE (elim_regs))
714 #endif
715 {
716 /* Now restore our arg pointer from the address at which it
717 was saved in our stack frame. */
718 emit_move_insn (virtual_incoming_args_rtx,
719 copy_to_reg (get_arg_pointer_save_area (cfun)));
720 }
721 }
722 #endif
723
724 #ifdef HAVE_builtin_setjmp_receiver
725 if (HAVE_builtin_setjmp_receiver)
726 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
727 else
728 #endif
729 #ifdef HAVE_nonlocal_goto_receiver
730 if (HAVE_nonlocal_goto_receiver)
731 emit_insn (gen_nonlocal_goto_receiver ());
732 else
733 #endif
734 { /* Nothing */ }
735
736 /* @@@ This is a kludge. Not all machine descriptions define a blockage
737 insn, but we must not allow the code we just generated to be reordered
738 by scheduling. Specifically, the update of the frame pointer must
739 happen immediately, not later. So emit an ASM_INPUT to act as blockage
740 insn. */
741 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
742 }
743
744 /* __builtin_longjmp is passed a pointer to an array of five words (not
745 all will be used on all machines). It operates similarly to the C
746 library function of the same name, but is more efficient. Much of
747 the code below is copied from the handling of non-local gotos. */
748
749 static void
750 expand_builtin_longjmp (rtx buf_addr, rtx value)
751 {
752 rtx fp, lab, stack, insn, last;
753 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
754
755 if (setjmp_alias_set == -1)
756 setjmp_alias_set = new_alias_set ();
757
758 buf_addr = convert_memory_address (Pmode, buf_addr);
759
760 buf_addr = force_reg (Pmode, buf_addr);
761
762 /* We used to store value in static_chain_rtx, but that fails if pointers
763 are smaller than integers. We instead require that the user must pass
764 a second argument of 1, because that is what builtin_setjmp will
765 return. This also makes EH slightly more efficient, since we are no
766 longer copying around a value that we don't care about. */
767 gcc_assert (value == const1_rtx);
768
769 last = get_last_insn ();
770 #ifdef HAVE_builtin_longjmp
771 if (HAVE_builtin_longjmp)
772 emit_insn (gen_builtin_longjmp (buf_addr));
773 else
774 #endif
775 {
776 fp = gen_rtx_MEM (Pmode, buf_addr);
777 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
778 GET_MODE_SIZE (Pmode)));
779
780 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
781 2 * GET_MODE_SIZE (Pmode)));
782 set_mem_alias_set (fp, setjmp_alias_set);
783 set_mem_alias_set (lab, setjmp_alias_set);
784 set_mem_alias_set (stack, setjmp_alias_set);
785
786 /* Pick up FP, label, and SP from the block and jump. This code is
787 from expand_goto in stmt.c; see there for detailed comments. */
788 #ifdef HAVE_nonlocal_goto
789 if (HAVE_nonlocal_goto)
790 /* We have to pass a value to the nonlocal_goto pattern that will
791 get copied into the static_chain pointer, but it does not matter
792 what that value is, because builtin_setjmp does not use it. */
793 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
794 else
795 #endif
796 {
797 lab = copy_to_reg (lab);
798
799 emit_insn (gen_rtx_CLOBBER (VOIDmode,
800 gen_rtx_MEM (BLKmode,
801 gen_rtx_SCRATCH (VOIDmode))));
802 emit_insn (gen_rtx_CLOBBER (VOIDmode,
803 gen_rtx_MEM (BLKmode,
804 hard_frame_pointer_rtx)));
805
806 emit_move_insn (hard_frame_pointer_rtx, fp);
807 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
808
809 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
810 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
811 emit_indirect_jump (lab);
812 }
813 }
814
815 /* Search backwards and mark the jump insn as a non-local goto.
816 Note that this precludes the use of __builtin_longjmp to a
817 __builtin_setjmp target in the same function. However, we've
818 already cautioned the user that these functions are for
819 internal exception handling use only. */
820 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
821 {
822 gcc_assert (insn != last);
823
824 if (JUMP_P (insn))
825 {
826 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
827 REG_NOTES (insn));
828 break;
829 }
830 else if (CALL_P (insn))
831 break;
832 }
833 }
834
835 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
836 and the address of the save area. */
837
838 static rtx
839 expand_builtin_nonlocal_goto (tree arglist)
840 {
841 tree t_label, t_save_area;
842 rtx r_label, r_save_area, r_fp, r_sp, insn;
843
844 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
845 return NULL_RTX;
846
847 t_label = TREE_VALUE (arglist);
848 arglist = TREE_CHAIN (arglist);
849 t_save_area = TREE_VALUE (arglist);
850
851 r_label = expand_normal (t_label);
852 r_label = convert_memory_address (Pmode, r_label);
853 r_save_area = expand_normal (t_save_area);
854 r_save_area = convert_memory_address (Pmode, r_save_area);
855 r_fp = gen_rtx_MEM (Pmode, r_save_area);
856 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
857 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
858
859 current_function_has_nonlocal_goto = 1;
860
861 #ifdef HAVE_nonlocal_goto
862 /* ??? We no longer need to pass the static chain value, afaik. */
863 if (HAVE_nonlocal_goto)
864 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
865 else
866 #endif
867 {
868 r_label = copy_to_reg (r_label);
869
870 emit_insn (gen_rtx_CLOBBER (VOIDmode,
871 gen_rtx_MEM (BLKmode,
872 gen_rtx_SCRATCH (VOIDmode))));
873
874 emit_insn (gen_rtx_CLOBBER (VOIDmode,
875 gen_rtx_MEM (BLKmode,
876 hard_frame_pointer_rtx)));
877
878 /* Restore frame pointer for containing function.
879 This sets the actual hard register used for the frame pointer
880 to the location of the function's incoming static chain info.
881 The non-local goto handler will then adjust it to contain the
882 proper value and reload the argument pointer, if needed. */
883 emit_move_insn (hard_frame_pointer_rtx, r_fp);
884 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
885
886 /* USE of hard_frame_pointer_rtx added for consistency;
887 not clear if really needed. */
888 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
889 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
890 emit_indirect_jump (r_label);
891 }
892
893 /* Search backwards to the jump insn and mark it as a
894 non-local goto. */
895 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
896 {
897 if (JUMP_P (insn))
898 {
899 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
900 const0_rtx, REG_NOTES (insn));
901 break;
902 }
903 else if (CALL_P (insn))
904 break;
905 }
906
907 return const0_rtx;
908 }
909
910 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
911 (not all will be used on all machines) that was passed to __builtin_setjmp.
912 It updates the stack pointer in that block to correspond to the current
913 stack pointer. */
914
915 static void
916 expand_builtin_update_setjmp_buf (rtx buf_addr)
917 {
918 enum machine_mode sa_mode = Pmode;
919 rtx stack_save;
920
921
922 #ifdef HAVE_save_stack_nonlocal
923 if (HAVE_save_stack_nonlocal)
924 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
925 #endif
926 #ifdef STACK_SAVEAREA_MODE
927 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
928 #endif
929
930 stack_save
931 = gen_rtx_MEM (sa_mode,
932 memory_address
933 (sa_mode,
934 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
935
936 #ifdef HAVE_setjmp
937 if (HAVE_setjmp)
938 emit_insn (gen_setjmp ());
939 #endif
940
941 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
942 }
943
944 /* Expand a call to __builtin_prefetch. For a target that does not support
945 data prefetch, evaluate the memory address argument in case it has side
946 effects. */
947
948 static void
949 expand_builtin_prefetch (tree arglist)
950 {
951 tree arg0, arg1, arg2;
952 rtx op0, op1, op2;
953
954 if (!validate_arglist (arglist, POINTER_TYPE, 0))
955 return;
956
957 arg0 = TREE_VALUE (arglist);
958 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
959 zero (read) and argument 2 (locality) defaults to 3 (high degree of
960 locality). */
961 if (TREE_CHAIN (arglist))
962 {
963 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
964 if (TREE_CHAIN (TREE_CHAIN (arglist)))
965 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
966 else
967 arg2 = build_int_cst (NULL_TREE, 3);
968 }
969 else
970 {
971 arg1 = integer_zero_node;
972 arg2 = build_int_cst (NULL_TREE, 3);
973 }
974
975 /* Argument 0 is an address. */
976 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
977
978 /* Argument 1 (read/write flag) must be a compile-time constant int. */
979 if (TREE_CODE (arg1) != INTEGER_CST)
980 {
981 error ("second argument to %<__builtin_prefetch%> must be a constant");
982 arg1 = integer_zero_node;
983 }
984 op1 = expand_normal (arg1);
985 /* Argument 1 must be either zero or one. */
986 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
987 {
988 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
989 " using zero");
990 op1 = const0_rtx;
991 }
992
993 /* Argument 2 (locality) must be a compile-time constant int. */
994 if (TREE_CODE (arg2) != INTEGER_CST)
995 {
996 error ("third argument to %<__builtin_prefetch%> must be a constant");
997 arg2 = integer_zero_node;
998 }
999 op2 = expand_normal (arg2);
1000 /* Argument 2 must be 0, 1, 2, or 3. */
1001 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1002 {
1003 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1004 op2 = const0_rtx;
1005 }
1006
1007 #ifdef HAVE_prefetch
1008 if (HAVE_prefetch)
1009 {
1010 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1011 (op0,
1012 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1013 || (GET_MODE (op0) != Pmode))
1014 {
1015 op0 = convert_memory_address (Pmode, op0);
1016 op0 = force_reg (Pmode, op0);
1017 }
1018 emit_insn (gen_prefetch (op0, op1, op2));
1019 }
1020 #endif
1021
1022 /* Don't do anything with direct references to volatile memory, but
1023 generate code to handle other side effects. */
1024 if (!MEM_P (op0) && side_effects_p (op0))
1025 emit_insn (op0);
1026 }
1027
1028 /* Get a MEM rtx for expression EXP which is the address of an operand
1029 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1030 the maximum length of the block of memory that might be accessed or
1031 NULL if unknown. */
1032
1033 static rtx
1034 get_memory_rtx (tree exp, tree len)
1035 {
1036 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1037 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1038
1039 /* Get an expression we can use to find the attributes to assign to MEM.
1040 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1041 we can. First remove any nops. */
1042 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1043 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1044 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1045 exp = TREE_OPERAND (exp, 0);
1046
1047 if (TREE_CODE (exp) == ADDR_EXPR)
1048 exp = TREE_OPERAND (exp, 0);
1049 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1050 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1051 else
1052 exp = NULL;
1053
1054 /* Honor attributes derived from exp, except for the alias set
1055 (as builtin stringops may alias with anything) and the size
1056 (as stringops may access multiple array elements). */
1057 if (exp)
1058 {
1059 set_mem_attributes (mem, exp, 0);
1060
1061 /* Allow the string and memory builtins to overflow from one
1062 field into another, see http://gcc.gnu.org/PR23561.
1063 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1064 memory accessed by the string or memory builtin will fit
1065 within the field. */
1066 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1067 {
1068 tree mem_expr = MEM_EXPR (mem);
1069 HOST_WIDE_INT offset = -1, length = -1;
1070 tree inner = exp;
1071
1072 while (TREE_CODE (inner) == ARRAY_REF
1073 || TREE_CODE (inner) == NOP_EXPR
1074 || TREE_CODE (inner) == CONVERT_EXPR
1075 || TREE_CODE (inner) == NON_LVALUE_EXPR
1076 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1077 || TREE_CODE (inner) == SAVE_EXPR)
1078 inner = TREE_OPERAND (inner, 0);
1079
1080 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1081
1082 if (MEM_OFFSET (mem)
1083 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1084 offset = INTVAL (MEM_OFFSET (mem));
1085
1086 if (offset >= 0 && len && host_integerp (len, 0))
1087 length = tree_low_cst (len, 0);
1088
1089 while (TREE_CODE (inner) == COMPONENT_REF)
1090 {
1091 tree field = TREE_OPERAND (inner, 1);
1092 gcc_assert (! DECL_BIT_FIELD (field));
1093 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1094 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1095
1096 if (length >= 0
1097 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1098 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1099 {
1100 HOST_WIDE_INT size
1101 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1102 /* If we can prove the memory starting at XEXP (mem, 0)
1103 and ending at XEXP (mem, 0) + LENGTH will fit into
1104 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1105 if (offset <= size
1106 && length <= size
1107 && offset + length <= size)
1108 break;
1109 }
1110
1111 if (offset >= 0
1112 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1113 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1114 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1115 / BITS_PER_UNIT;
1116 else
1117 {
1118 offset = -1;
1119 length = -1;
1120 }
1121
1122 mem_expr = TREE_OPERAND (mem_expr, 0);
1123 inner = TREE_OPERAND (inner, 0);
1124 }
1125
1126 if (mem_expr == NULL)
1127 offset = -1;
1128 if (mem_expr != MEM_EXPR (mem))
1129 {
1130 set_mem_expr (mem, mem_expr);
1131 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1132 }
1133 }
1134 set_mem_alias_set (mem, 0);
1135 set_mem_size (mem, NULL_RTX);
1136 }
1137
1138 return mem;
1139 }
1140 \f
1141 /* Built-in functions to perform an untyped call and return. */
1142
1143 /* For each register that may be used for calling a function, this
1144 gives a mode used to copy the register's value. VOIDmode indicates
1145 the register is not used for calling a function. If the machine
1146 has register windows, this gives only the outbound registers.
1147 INCOMING_REGNO gives the corresponding inbound register. */
1148 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1149
1150 /* For each register that may be used for returning values, this gives
1151 a mode used to copy the register's value. VOIDmode indicates the
1152 register is not used for returning values. If the machine has
1153 register windows, this gives only the outbound registers.
1154 INCOMING_REGNO gives the corresponding inbound register. */
1155 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1156
1157 /* For each register that may be used for calling a function, this
1158 gives the offset of that register into the block returned by
1159 __builtin_apply_args. 0 indicates that the register is not
1160 used for calling a function. */
1161 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1162
1163 /* Return the size required for the block returned by __builtin_apply_args,
1164 and initialize apply_args_mode. */
1165
1166 static int
1167 apply_args_size (void)
1168 {
1169 static int size = -1;
1170 int align;
1171 unsigned int regno;
1172 enum machine_mode mode;
1173
1174 /* The values computed by this function never change. */
1175 if (size < 0)
1176 {
1177 /* The first value is the incoming arg-pointer. */
1178 size = GET_MODE_SIZE (Pmode);
1179
1180 /* The second value is the structure value address unless this is
1181 passed as an "invisible" first argument. */
1182 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1183 size += GET_MODE_SIZE (Pmode);
1184
1185 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1186 if (FUNCTION_ARG_REGNO_P (regno))
1187 {
1188 mode = reg_raw_mode[regno];
1189
1190 gcc_assert (mode != VOIDmode);
1191
1192 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1193 if (size % align != 0)
1194 size = CEIL (size, align) * align;
1195 apply_args_reg_offset[regno] = size;
1196 size += GET_MODE_SIZE (mode);
1197 apply_args_mode[regno] = mode;
1198 }
1199 else
1200 {
1201 apply_args_mode[regno] = VOIDmode;
1202 apply_args_reg_offset[regno] = 0;
1203 }
1204 }
1205 return size;
1206 }
1207
1208 /* Return the size required for the block returned by __builtin_apply,
1209 and initialize apply_result_mode. */
1210
1211 static int
1212 apply_result_size (void)
1213 {
1214 static int size = -1;
1215 int align, regno;
1216 enum machine_mode mode;
1217
1218 /* The values computed by this function never change. */
1219 if (size < 0)
1220 {
1221 size = 0;
1222
1223 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1224 if (FUNCTION_VALUE_REGNO_P (regno))
1225 {
1226 mode = reg_raw_mode[regno];
1227
1228 gcc_assert (mode != VOIDmode);
1229
1230 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1231 if (size % align != 0)
1232 size = CEIL (size, align) * align;
1233 size += GET_MODE_SIZE (mode);
1234 apply_result_mode[regno] = mode;
1235 }
1236 else
1237 apply_result_mode[regno] = VOIDmode;
1238
1239 /* Allow targets that use untyped_call and untyped_return to override
1240 the size so that machine-specific information can be stored here. */
1241 #ifdef APPLY_RESULT_SIZE
1242 size = APPLY_RESULT_SIZE;
1243 #endif
1244 }
1245 return size;
1246 }
1247
1248 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1249 /* Create a vector describing the result block RESULT. If SAVEP is true,
1250 the result block is used to save the values; otherwise it is used to
1251 restore the values. */
1252
1253 static rtx
1254 result_vector (int savep, rtx result)
1255 {
1256 int regno, size, align, nelts;
1257 enum machine_mode mode;
1258 rtx reg, mem;
1259 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1260
1261 size = nelts = 0;
1262 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1263 if ((mode = apply_result_mode[regno]) != VOIDmode)
1264 {
1265 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1266 if (size % align != 0)
1267 size = CEIL (size, align) * align;
1268 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1269 mem = adjust_address (result, mode, size);
1270 savevec[nelts++] = (savep
1271 ? gen_rtx_SET (VOIDmode, mem, reg)
1272 : gen_rtx_SET (VOIDmode, reg, mem));
1273 size += GET_MODE_SIZE (mode);
1274 }
1275 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1276 }
1277 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1278
1279 /* Save the state required to perform an untyped call with the same
1280 arguments as were passed to the current function. */
1281
1282 static rtx
1283 expand_builtin_apply_args_1 (void)
1284 {
1285 rtx registers, tem;
1286 int size, align, regno;
1287 enum machine_mode mode;
1288 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1289
1290 /* Create a block where the arg-pointer, structure value address,
1291 and argument registers can be saved. */
1292 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1293
1294 /* Walk past the arg-pointer and structure value address. */
1295 size = GET_MODE_SIZE (Pmode);
1296 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1297 size += GET_MODE_SIZE (Pmode);
1298
1299 /* Save each register used in calling a function to the block. */
1300 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1301 if ((mode = apply_args_mode[regno]) != VOIDmode)
1302 {
1303 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1304 if (size % align != 0)
1305 size = CEIL (size, align) * align;
1306
1307 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1308
1309 emit_move_insn (adjust_address (registers, mode, size), tem);
1310 size += GET_MODE_SIZE (mode);
1311 }
1312
1313 /* Save the arg pointer to the block. */
1314 tem = copy_to_reg (virtual_incoming_args_rtx);
1315 #ifdef STACK_GROWS_DOWNWARD
1316 /* We need the pointer as the caller actually passed them to us, not
1317 as we might have pretended they were passed. Make sure it's a valid
1318 operand, as emit_move_insn isn't expected to handle a PLUS. */
1319 tem
1320 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1321 NULL_RTX);
1322 #endif
1323 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1324
1325 size = GET_MODE_SIZE (Pmode);
1326
1327 /* Save the structure value address unless this is passed as an
1328 "invisible" first argument. */
1329 if (struct_incoming_value)
1330 {
1331 emit_move_insn (adjust_address (registers, Pmode, size),
1332 copy_to_reg (struct_incoming_value));
1333 size += GET_MODE_SIZE (Pmode);
1334 }
1335
1336 /* Return the address of the block. */
1337 return copy_addr_to_reg (XEXP (registers, 0));
1338 }
1339
1340 /* __builtin_apply_args returns block of memory allocated on
1341 the stack into which is stored the arg pointer, structure
1342 value address, static chain, and all the registers that might
1343 possibly be used in performing a function call. The code is
1344 moved to the start of the function so the incoming values are
1345 saved. */
1346
1347 static rtx
1348 expand_builtin_apply_args (void)
1349 {
1350 /* Don't do __builtin_apply_args more than once in a function.
1351 Save the result of the first call and reuse it. */
1352 if (apply_args_value != 0)
1353 return apply_args_value;
1354 {
1355 /* When this function is called, it means that registers must be
1356 saved on entry to this function. So we migrate the
1357 call to the first insn of this function. */
1358 rtx temp;
1359 rtx seq;
1360
1361 start_sequence ();
1362 temp = expand_builtin_apply_args_1 ();
1363 seq = get_insns ();
1364 end_sequence ();
1365
1366 apply_args_value = temp;
1367
1368 /* Put the insns after the NOTE that starts the function.
1369 If this is inside a start_sequence, make the outer-level insn
1370 chain current, so the code is placed at the start of the
1371 function. */
1372 push_topmost_sequence ();
1373 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1374 pop_topmost_sequence ();
1375 return temp;
1376 }
1377 }
1378
1379 /* Perform an untyped call and save the state required to perform an
1380 untyped return of whatever value was returned by the given function. */
1381
1382 static rtx
1383 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1384 {
1385 int size, align, regno;
1386 enum machine_mode mode;
1387 rtx incoming_args, result, reg, dest, src, call_insn;
1388 rtx old_stack_level = 0;
1389 rtx call_fusage = 0;
1390 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1391
1392 arguments = convert_memory_address (Pmode, arguments);
1393
1394 /* Create a block where the return registers can be saved. */
1395 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1396
1397 /* Fetch the arg pointer from the ARGUMENTS block. */
1398 incoming_args = gen_reg_rtx (Pmode);
1399 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1400 #ifndef STACK_GROWS_DOWNWARD
1401 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1402 incoming_args, 0, OPTAB_LIB_WIDEN);
1403 #endif
1404
1405 /* Push a new argument block and copy the arguments. Do not allow
1406 the (potential) memcpy call below to interfere with our stack
1407 manipulations. */
1408 do_pending_stack_adjust ();
1409 NO_DEFER_POP;
1410
1411 /* Save the stack with nonlocal if available. */
1412 #ifdef HAVE_save_stack_nonlocal
1413 if (HAVE_save_stack_nonlocal)
1414 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1415 else
1416 #endif
1417 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1418
1419 /* Allocate a block of memory onto the stack and copy the memory
1420 arguments to the outgoing arguments address. */
1421 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1422 dest = virtual_outgoing_args_rtx;
1423 #ifndef STACK_GROWS_DOWNWARD
1424 if (GET_CODE (argsize) == CONST_INT)
1425 dest = plus_constant (dest, -INTVAL (argsize));
1426 else
1427 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1428 #endif
1429 dest = gen_rtx_MEM (BLKmode, dest);
1430 set_mem_align (dest, PARM_BOUNDARY);
1431 src = gen_rtx_MEM (BLKmode, incoming_args);
1432 set_mem_align (src, PARM_BOUNDARY);
1433 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1434
1435 /* Refer to the argument block. */
1436 apply_args_size ();
1437 arguments = gen_rtx_MEM (BLKmode, arguments);
1438 set_mem_align (arguments, PARM_BOUNDARY);
1439
1440 /* Walk past the arg-pointer and structure value address. */
1441 size = GET_MODE_SIZE (Pmode);
1442 if (struct_value)
1443 size += GET_MODE_SIZE (Pmode);
1444
1445 /* Restore each of the registers previously saved. Make USE insns
1446 for each of these registers for use in making the call. */
1447 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1448 if ((mode = apply_args_mode[regno]) != VOIDmode)
1449 {
1450 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1451 if (size % align != 0)
1452 size = CEIL (size, align) * align;
1453 reg = gen_rtx_REG (mode, regno);
1454 emit_move_insn (reg, adjust_address (arguments, mode, size));
1455 use_reg (&call_fusage, reg);
1456 size += GET_MODE_SIZE (mode);
1457 }
1458
1459 /* Restore the structure value address unless this is passed as an
1460 "invisible" first argument. */
1461 size = GET_MODE_SIZE (Pmode);
1462 if (struct_value)
1463 {
1464 rtx value = gen_reg_rtx (Pmode);
1465 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1466 emit_move_insn (struct_value, value);
1467 if (REG_P (struct_value))
1468 use_reg (&call_fusage, struct_value);
1469 size += GET_MODE_SIZE (Pmode);
1470 }
1471
1472 /* All arguments and registers used for the call are set up by now! */
1473 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1474
1475 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1476 and we don't want to load it into a register as an optimization,
1477 because prepare_call_address already did it if it should be done. */
1478 if (GET_CODE (function) != SYMBOL_REF)
1479 function = memory_address (FUNCTION_MODE, function);
1480
1481 /* Generate the actual call instruction and save the return value. */
1482 #ifdef HAVE_untyped_call
1483 if (HAVE_untyped_call)
1484 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1485 result, result_vector (1, result)));
1486 else
1487 #endif
1488 #ifdef HAVE_call_value
1489 if (HAVE_call_value)
1490 {
1491 rtx valreg = 0;
1492
1493 /* Locate the unique return register. It is not possible to
1494 express a call that sets more than one return register using
1495 call_value; use untyped_call for that. In fact, untyped_call
1496 only needs to save the return registers in the given block. */
1497 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1498 if ((mode = apply_result_mode[regno]) != VOIDmode)
1499 {
1500 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1501
1502 valreg = gen_rtx_REG (mode, regno);
1503 }
1504
1505 emit_call_insn (GEN_CALL_VALUE (valreg,
1506 gen_rtx_MEM (FUNCTION_MODE, function),
1507 const0_rtx, NULL_RTX, const0_rtx));
1508
1509 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1510 }
1511 else
1512 #endif
1513 gcc_unreachable ();
1514
1515 /* Find the CALL insn we just emitted, and attach the register usage
1516 information. */
1517 call_insn = last_call_insn ();
1518 add_function_usage_to (call_insn, call_fusage);
1519
1520 /* Restore the stack. */
1521 #ifdef HAVE_save_stack_nonlocal
1522 if (HAVE_save_stack_nonlocal)
1523 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1524 else
1525 #endif
1526 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1527
1528 OK_DEFER_POP;
1529
1530 /* Return the address of the result block. */
1531 result = copy_addr_to_reg (XEXP (result, 0));
1532 return convert_memory_address (ptr_mode, result);
1533 }
1534
1535 /* Perform an untyped return. */
1536
1537 static void
1538 expand_builtin_return (rtx result)
1539 {
1540 int size, align, regno;
1541 enum machine_mode mode;
1542 rtx reg;
1543 rtx call_fusage = 0;
1544
1545 result = convert_memory_address (Pmode, result);
1546
1547 apply_result_size ();
1548 result = gen_rtx_MEM (BLKmode, result);
1549
1550 #ifdef HAVE_untyped_return
1551 if (HAVE_untyped_return)
1552 {
1553 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1554 emit_barrier ();
1555 return;
1556 }
1557 #endif
1558
1559 /* Restore the return value and note that each value is used. */
1560 size = 0;
1561 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1562 if ((mode = apply_result_mode[regno]) != VOIDmode)
1563 {
1564 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1565 if (size % align != 0)
1566 size = CEIL (size, align) * align;
1567 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1568 emit_move_insn (reg, adjust_address (result, mode, size));
1569
1570 push_to_sequence (call_fusage);
1571 emit_insn (gen_rtx_USE (VOIDmode, reg));
1572 call_fusage = get_insns ();
1573 end_sequence ();
1574 size += GET_MODE_SIZE (mode);
1575 }
1576
1577 /* Put the USE insns before the return. */
1578 emit_insn (call_fusage);
1579
1580 /* Return whatever values was restored by jumping directly to the end
1581 of the function. */
1582 expand_naked_return ();
1583 }
1584
1585 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1586
1587 static enum type_class
1588 type_to_class (tree type)
1589 {
1590 switch (TREE_CODE (type))
1591 {
1592 case VOID_TYPE: return void_type_class;
1593 case INTEGER_TYPE: return integer_type_class;
1594 case ENUMERAL_TYPE: return enumeral_type_class;
1595 case BOOLEAN_TYPE: return boolean_type_class;
1596 case POINTER_TYPE: return pointer_type_class;
1597 case REFERENCE_TYPE: return reference_type_class;
1598 case OFFSET_TYPE: return offset_type_class;
1599 case REAL_TYPE: return real_type_class;
1600 case COMPLEX_TYPE: return complex_type_class;
1601 case FUNCTION_TYPE: return function_type_class;
1602 case METHOD_TYPE: return method_type_class;
1603 case RECORD_TYPE: return record_type_class;
1604 case UNION_TYPE:
1605 case QUAL_UNION_TYPE: return union_type_class;
1606 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1607 ? string_type_class : array_type_class);
1608 case LANG_TYPE: return lang_type_class;
1609 default: return no_type_class;
1610 }
1611 }
1612
1613 /* Expand a call to __builtin_classify_type with arguments found in
1614 ARGLIST. */
1615
1616 static rtx
1617 expand_builtin_classify_type (tree arglist)
1618 {
1619 if (arglist != 0)
1620 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1621 return GEN_INT (no_type_class);
1622 }
1623
1624 /* This helper macro, meant to be used in mathfn_built_in below,
1625 determines which among a set of three builtin math functions is
1626 appropriate for a given type mode. The `F' and `L' cases are
1627 automatically generated from the `double' case. */
1628 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1629 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1630 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1631 fcodel = BUILT_IN_MATHFN##L ; break;
1632
1633 /* Return mathematic function equivalent to FN but operating directly
1634 on TYPE, if available. If we can't do the conversion, return zero. */
1635 tree
1636 mathfn_built_in (tree type, enum built_in_function fn)
1637 {
1638 enum built_in_function fcode, fcodef, fcodel;
1639
1640 switch (fn)
1641 {
1642 CASE_MATHFN (BUILT_IN_ACOS)
1643 CASE_MATHFN (BUILT_IN_ACOSH)
1644 CASE_MATHFN (BUILT_IN_ASIN)
1645 CASE_MATHFN (BUILT_IN_ASINH)
1646 CASE_MATHFN (BUILT_IN_ATAN)
1647 CASE_MATHFN (BUILT_IN_ATAN2)
1648 CASE_MATHFN (BUILT_IN_ATANH)
1649 CASE_MATHFN (BUILT_IN_CBRT)
1650 CASE_MATHFN (BUILT_IN_CEIL)
1651 CASE_MATHFN (BUILT_IN_COPYSIGN)
1652 CASE_MATHFN (BUILT_IN_COS)
1653 CASE_MATHFN (BUILT_IN_COSH)
1654 CASE_MATHFN (BUILT_IN_DREM)
1655 CASE_MATHFN (BUILT_IN_ERF)
1656 CASE_MATHFN (BUILT_IN_ERFC)
1657 CASE_MATHFN (BUILT_IN_EXP)
1658 CASE_MATHFN (BUILT_IN_EXP10)
1659 CASE_MATHFN (BUILT_IN_EXP2)
1660 CASE_MATHFN (BUILT_IN_EXPM1)
1661 CASE_MATHFN (BUILT_IN_FABS)
1662 CASE_MATHFN (BUILT_IN_FDIM)
1663 CASE_MATHFN (BUILT_IN_FLOOR)
1664 CASE_MATHFN (BUILT_IN_FMA)
1665 CASE_MATHFN (BUILT_IN_FMAX)
1666 CASE_MATHFN (BUILT_IN_FMIN)
1667 CASE_MATHFN (BUILT_IN_FMOD)
1668 CASE_MATHFN (BUILT_IN_FREXP)
1669 CASE_MATHFN (BUILT_IN_GAMMA)
1670 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1671 CASE_MATHFN (BUILT_IN_HYPOT)
1672 CASE_MATHFN (BUILT_IN_ILOGB)
1673 CASE_MATHFN (BUILT_IN_INF)
1674 CASE_MATHFN (BUILT_IN_J0)
1675 CASE_MATHFN (BUILT_IN_J1)
1676 CASE_MATHFN (BUILT_IN_JN)
1677 CASE_MATHFN (BUILT_IN_LCEIL)
1678 CASE_MATHFN (BUILT_IN_LDEXP)
1679 CASE_MATHFN (BUILT_IN_LFLOOR)
1680 CASE_MATHFN (BUILT_IN_LGAMMA)
1681 CASE_MATHFN (BUILT_IN_LLCEIL)
1682 CASE_MATHFN (BUILT_IN_LLFLOOR)
1683 CASE_MATHFN (BUILT_IN_LLRINT)
1684 CASE_MATHFN (BUILT_IN_LLROUND)
1685 CASE_MATHFN (BUILT_IN_LOG)
1686 CASE_MATHFN (BUILT_IN_LOG10)
1687 CASE_MATHFN (BUILT_IN_LOG1P)
1688 CASE_MATHFN (BUILT_IN_LOG2)
1689 CASE_MATHFN (BUILT_IN_LOGB)
1690 CASE_MATHFN (BUILT_IN_LRINT)
1691 CASE_MATHFN (BUILT_IN_LROUND)
1692 CASE_MATHFN (BUILT_IN_MODF)
1693 CASE_MATHFN (BUILT_IN_NAN)
1694 CASE_MATHFN (BUILT_IN_NANS)
1695 CASE_MATHFN (BUILT_IN_NEARBYINT)
1696 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1697 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1698 CASE_MATHFN (BUILT_IN_POW)
1699 CASE_MATHFN (BUILT_IN_POWI)
1700 CASE_MATHFN (BUILT_IN_POW10)
1701 CASE_MATHFN (BUILT_IN_REMAINDER)
1702 CASE_MATHFN (BUILT_IN_REMQUO)
1703 CASE_MATHFN (BUILT_IN_RINT)
1704 CASE_MATHFN (BUILT_IN_ROUND)
1705 CASE_MATHFN (BUILT_IN_SCALB)
1706 CASE_MATHFN (BUILT_IN_SCALBLN)
1707 CASE_MATHFN (BUILT_IN_SCALBN)
1708 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1709 CASE_MATHFN (BUILT_IN_SIN)
1710 CASE_MATHFN (BUILT_IN_SINCOS)
1711 CASE_MATHFN (BUILT_IN_SINH)
1712 CASE_MATHFN (BUILT_IN_SQRT)
1713 CASE_MATHFN (BUILT_IN_TAN)
1714 CASE_MATHFN (BUILT_IN_TANH)
1715 CASE_MATHFN (BUILT_IN_TGAMMA)
1716 CASE_MATHFN (BUILT_IN_TRUNC)
1717 CASE_MATHFN (BUILT_IN_Y0)
1718 CASE_MATHFN (BUILT_IN_Y1)
1719 CASE_MATHFN (BUILT_IN_YN)
1720
1721 default:
1722 return 0;
1723 }
1724
1725 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1726 return implicit_built_in_decls[fcode];
1727 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1728 return implicit_built_in_decls[fcodef];
1729 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1730 return implicit_built_in_decls[fcodel];
1731 else
1732 return 0;
1733 }
1734
1735 /* If errno must be maintained, expand the RTL to check if the result,
1736 TARGET, of a built-in function call, EXP, is NaN, and if so set
1737 errno to EDOM. */
1738
1739 static void
1740 expand_errno_check (tree exp, rtx target)
1741 {
1742 rtx lab = gen_label_rtx ();
1743
1744 /* Test the result; if it is NaN, set errno=EDOM because
1745 the argument was not in the domain. */
1746 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1747 0, lab);
1748
1749 #ifdef TARGET_EDOM
1750 /* If this built-in doesn't throw an exception, set errno directly. */
1751 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1752 {
1753 #ifdef GEN_ERRNO_RTX
1754 rtx errno_rtx = GEN_ERRNO_RTX;
1755 #else
1756 rtx errno_rtx
1757 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1758 #endif
1759 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1760 emit_label (lab);
1761 return;
1762 }
1763 #endif
1764
1765 /* We can't set errno=EDOM directly; let the library call do it.
1766 Pop the arguments right away in case the call gets deleted. */
1767 NO_DEFER_POP;
1768 expand_call (exp, target, 0);
1769 OK_DEFER_POP;
1770 emit_label (lab);
1771 }
1772
1773
1774 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1775 Return 0 if a normal call should be emitted rather than expanding the
1776 function in-line. EXP is the expression that is a call to the builtin
1777 function; if convenient, the result should be placed in TARGET.
1778 SUBTARGET may be used as the target for computing one of EXP's operands. */
1779
1780 static rtx
1781 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1782 {
1783 optab builtin_optab;
1784 rtx op0, insns, before_call;
1785 tree fndecl = get_callee_fndecl (exp);
1786 tree arglist = TREE_OPERAND (exp, 1);
1787 enum machine_mode mode;
1788 bool errno_set = false;
1789 tree arg, narg;
1790
1791 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1792 return 0;
1793
1794 arg = TREE_VALUE (arglist);
1795
1796 switch (DECL_FUNCTION_CODE (fndecl))
1797 {
1798 CASE_FLT_FN (BUILT_IN_SQRT):
1799 errno_set = ! tree_expr_nonnegative_p (arg);
1800 builtin_optab = sqrt_optab;
1801 break;
1802 CASE_FLT_FN (BUILT_IN_EXP):
1803 errno_set = true; builtin_optab = exp_optab; break;
1804 CASE_FLT_FN (BUILT_IN_EXP10):
1805 CASE_FLT_FN (BUILT_IN_POW10):
1806 errno_set = true; builtin_optab = exp10_optab; break;
1807 CASE_FLT_FN (BUILT_IN_EXP2):
1808 errno_set = true; builtin_optab = exp2_optab; break;
1809 CASE_FLT_FN (BUILT_IN_EXPM1):
1810 errno_set = true; builtin_optab = expm1_optab; break;
1811 CASE_FLT_FN (BUILT_IN_LOGB):
1812 errno_set = true; builtin_optab = logb_optab; break;
1813 CASE_FLT_FN (BUILT_IN_ILOGB):
1814 errno_set = true; builtin_optab = ilogb_optab; break;
1815 CASE_FLT_FN (BUILT_IN_LOG):
1816 errno_set = true; builtin_optab = log_optab; break;
1817 CASE_FLT_FN (BUILT_IN_LOG10):
1818 errno_set = true; builtin_optab = log10_optab; break;
1819 CASE_FLT_FN (BUILT_IN_LOG2):
1820 errno_set = true; builtin_optab = log2_optab; break;
1821 CASE_FLT_FN (BUILT_IN_LOG1P):
1822 errno_set = true; builtin_optab = log1p_optab; break;
1823 CASE_FLT_FN (BUILT_IN_ASIN):
1824 builtin_optab = asin_optab; break;
1825 CASE_FLT_FN (BUILT_IN_ACOS):
1826 builtin_optab = acos_optab; break;
1827 CASE_FLT_FN (BUILT_IN_TAN):
1828 builtin_optab = tan_optab; break;
1829 CASE_FLT_FN (BUILT_IN_ATAN):
1830 builtin_optab = atan_optab; break;
1831 CASE_FLT_FN (BUILT_IN_FLOOR):
1832 builtin_optab = floor_optab; break;
1833 CASE_FLT_FN (BUILT_IN_CEIL):
1834 builtin_optab = ceil_optab; break;
1835 CASE_FLT_FN (BUILT_IN_TRUNC):
1836 builtin_optab = btrunc_optab; break;
1837 CASE_FLT_FN (BUILT_IN_ROUND):
1838 builtin_optab = round_optab; break;
1839 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1840 builtin_optab = nearbyint_optab;
1841 if (flag_trapping_math)
1842 break;
1843 /* Else fallthrough and expand as rint. */
1844 CASE_FLT_FN (BUILT_IN_RINT):
1845 builtin_optab = rint_optab; break;
1846 default:
1847 gcc_unreachable ();
1848 }
1849
1850 /* Make a suitable register to place result in. */
1851 mode = TYPE_MODE (TREE_TYPE (exp));
1852
1853 if (! flag_errno_math || ! HONOR_NANS (mode))
1854 errno_set = false;
1855
1856 /* Before working hard, check whether the instruction is available. */
1857 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1858 {
1859 target = gen_reg_rtx (mode);
1860
1861 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1862 need to expand the argument again. This way, we will not perform
1863 side-effects more the once. */
1864 narg = builtin_save_expr (arg);
1865 if (narg != arg)
1866 {
1867 arg = narg;
1868 arglist = build_tree_list (NULL_TREE, arg);
1869 exp = build_function_call_expr (fndecl, arglist);
1870 }
1871
1872 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1873
1874 start_sequence ();
1875
1876 /* Compute into TARGET.
1877 Set TARGET to wherever the result comes back. */
1878 target = expand_unop (mode, builtin_optab, op0, target, 0);
1879
1880 if (target != 0)
1881 {
1882 if (errno_set)
1883 expand_errno_check (exp, target);
1884
1885 /* Output the entire sequence. */
1886 insns = get_insns ();
1887 end_sequence ();
1888 emit_insn (insns);
1889 return target;
1890 }
1891
1892 /* If we were unable to expand via the builtin, stop the sequence
1893 (without outputting the insns) and call to the library function
1894 with the stabilized argument list. */
1895 end_sequence ();
1896 }
1897
1898 before_call = get_last_insn ();
1899
1900 target = expand_call (exp, target, target == const0_rtx);
1901
1902 /* If this is a sqrt operation and we don't care about errno, try to
1903 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1904 This allows the semantics of the libcall to be visible to the RTL
1905 optimizers. */
1906 if (builtin_optab == sqrt_optab && !errno_set)
1907 {
1908 /* Search backwards through the insns emitted by expand_call looking
1909 for the instruction with the REG_RETVAL note. */
1910 rtx last = get_last_insn ();
1911 while (last != before_call)
1912 {
1913 if (find_reg_note (last, REG_RETVAL, NULL))
1914 {
1915 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1916 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1917 two elements, i.e. symbol_ref(sqrt) and the operand. */
1918 if (note
1919 && GET_CODE (note) == EXPR_LIST
1920 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1921 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1922 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1923 {
1924 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1925 /* Check operand is a register with expected mode. */
1926 if (operand
1927 && REG_P (operand)
1928 && GET_MODE (operand) == mode)
1929 {
1930 /* Replace the REG_EQUAL note with a SQRT rtx. */
1931 rtx equiv = gen_rtx_SQRT (mode, operand);
1932 set_unique_reg_note (last, REG_EQUAL, equiv);
1933 }
1934 }
1935 break;
1936 }
1937 last = PREV_INSN (last);
1938 }
1939 }
1940
1941 return target;
1942 }
1943
1944 /* Expand a call to the builtin binary math functions (pow and atan2).
1945 Return 0 if a normal call should be emitted rather than expanding the
1946 function in-line. EXP is the expression that is a call to the builtin
1947 function; if convenient, the result should be placed in TARGET.
1948 SUBTARGET may be used as the target for computing one of EXP's
1949 operands. */
1950
1951 static rtx
1952 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1953 {
1954 optab builtin_optab;
1955 rtx op0, op1, insns;
1956 int op1_type = REAL_TYPE;
1957 tree fndecl = get_callee_fndecl (exp);
1958 tree arglist = TREE_OPERAND (exp, 1);
1959 tree arg0, arg1, temp, narg;
1960 enum machine_mode mode;
1961 bool errno_set = true;
1962 bool stable = true;
1963
1964 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1965 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1966 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1967 op1_type = INTEGER_TYPE;
1968
1969 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1970 return 0;
1971
1972 arg0 = TREE_VALUE (arglist);
1973 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1974
1975 switch (DECL_FUNCTION_CODE (fndecl))
1976 {
1977 CASE_FLT_FN (BUILT_IN_POW):
1978 builtin_optab = pow_optab; break;
1979 CASE_FLT_FN (BUILT_IN_ATAN2):
1980 builtin_optab = atan2_optab; break;
1981 CASE_FLT_FN (BUILT_IN_LDEXP):
1982 builtin_optab = ldexp_optab; break;
1983 CASE_FLT_FN (BUILT_IN_FMOD):
1984 builtin_optab = fmod_optab; break;
1985 CASE_FLT_FN (BUILT_IN_REMAINDER):
1986 CASE_FLT_FN (BUILT_IN_DREM):
1987 builtin_optab = remainder_optab; break;
1988 default:
1989 gcc_unreachable ();
1990 }
1991
1992 /* Make a suitable register to place result in. */
1993 mode = TYPE_MODE (TREE_TYPE (exp));
1994
1995 /* Before working hard, check whether the instruction is available. */
1996 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1997 return 0;
1998
1999 target = gen_reg_rtx (mode);
2000
2001 if (! flag_errno_math || ! HONOR_NANS (mode))
2002 errno_set = false;
2003
2004 /* Always stabilize the argument list. */
2005 narg = builtin_save_expr (arg1);
2006 if (narg != arg1)
2007 {
2008 arg1 = narg;
2009 temp = build_tree_list (NULL_TREE, narg);
2010 stable = false;
2011 }
2012 else
2013 temp = TREE_CHAIN (arglist);
2014
2015 narg = builtin_save_expr (arg0);
2016 if (narg != arg0)
2017 {
2018 arg0 = narg;
2019 arglist = tree_cons (NULL_TREE, narg, temp);
2020 stable = false;
2021 }
2022 else if (! stable)
2023 arglist = tree_cons (NULL_TREE, arg0, temp);
2024
2025 if (! stable)
2026 exp = build_function_call_expr (fndecl, arglist);
2027
2028 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2029 op1 = expand_normal (arg1);
2030
2031 start_sequence ();
2032
2033 /* Compute into TARGET.
2034 Set TARGET to wherever the result comes back. */
2035 target = expand_binop (mode, builtin_optab, op0, op1,
2036 target, 0, OPTAB_DIRECT);
2037
2038 /* If we were unable to expand via the builtin, stop the sequence
2039 (without outputting the insns) and call to the library function
2040 with the stabilized argument list. */
2041 if (target == 0)
2042 {
2043 end_sequence ();
2044 return expand_call (exp, target, target == const0_rtx);
2045 }
2046
2047 if (errno_set)
2048 expand_errno_check (exp, target);
2049
2050 /* Output the entire sequence. */
2051 insns = get_insns ();
2052 end_sequence ();
2053 emit_insn (insns);
2054
2055 return target;
2056 }
2057
2058 /* Expand a call to the builtin sin and cos math functions.
2059 Return 0 if a normal call should be emitted rather than expanding the
2060 function in-line. EXP is the expression that is a call to the builtin
2061 function; if convenient, the result should be placed in TARGET.
2062 SUBTARGET may be used as the target for computing one of EXP's
2063 operands. */
2064
2065 static rtx
2066 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2067 {
2068 optab builtin_optab;
2069 rtx op0, insns;
2070 tree fndecl = get_callee_fndecl (exp);
2071 tree arglist = TREE_OPERAND (exp, 1);
2072 enum machine_mode mode;
2073 tree arg, narg;
2074
2075 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2076 return 0;
2077
2078 arg = TREE_VALUE (arglist);
2079
2080 switch (DECL_FUNCTION_CODE (fndecl))
2081 {
2082 CASE_FLT_FN (BUILT_IN_SIN):
2083 CASE_FLT_FN (BUILT_IN_COS):
2084 builtin_optab = sincos_optab; break;
2085 default:
2086 gcc_unreachable ();
2087 }
2088
2089 /* Make a suitable register to place result in. */
2090 mode = TYPE_MODE (TREE_TYPE (exp));
2091
2092 /* Check if sincos insn is available, otherwise fallback
2093 to sin or cos insn. */
2094 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2095 switch (DECL_FUNCTION_CODE (fndecl))
2096 {
2097 CASE_FLT_FN (BUILT_IN_SIN):
2098 builtin_optab = sin_optab; break;
2099 CASE_FLT_FN (BUILT_IN_COS):
2100 builtin_optab = cos_optab; break;
2101 default:
2102 gcc_unreachable ();
2103 }
2104
2105 /* Before working hard, check whether the instruction is available. */
2106 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2107 {
2108 target = gen_reg_rtx (mode);
2109
2110 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2111 need to expand the argument again. This way, we will not perform
2112 side-effects more the once. */
2113 narg = save_expr (arg);
2114 if (narg != arg)
2115 {
2116 arg = narg;
2117 arglist = build_tree_list (NULL_TREE, arg);
2118 exp = build_function_call_expr (fndecl, arglist);
2119 }
2120
2121 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2122
2123 start_sequence ();
2124
2125 /* Compute into TARGET.
2126 Set TARGET to wherever the result comes back. */
2127 if (builtin_optab == sincos_optab)
2128 {
2129 int result;
2130
2131 switch (DECL_FUNCTION_CODE (fndecl))
2132 {
2133 CASE_FLT_FN (BUILT_IN_SIN):
2134 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2135 break;
2136 CASE_FLT_FN (BUILT_IN_COS):
2137 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2138 break;
2139 default:
2140 gcc_unreachable ();
2141 }
2142 gcc_assert (result);
2143 }
2144 else
2145 {
2146 target = expand_unop (mode, builtin_optab, op0, target, 0);
2147 }
2148
2149 if (target != 0)
2150 {
2151 /* Output the entire sequence. */
2152 insns = get_insns ();
2153 end_sequence ();
2154 emit_insn (insns);
2155 return target;
2156 }
2157
2158 /* If we were unable to expand via the builtin, stop the sequence
2159 (without outputting the insns) and call to the library function
2160 with the stabilized argument list. */
2161 end_sequence ();
2162 }
2163
2164 target = expand_call (exp, target, target == const0_rtx);
2165
2166 return target;
2167 }
2168
2169 /* Expand a call to the builtin sincos math function.
2170 Return 0 if a normal call should be emitted rather than expanding the
2171 function in-line. EXP is the expression that is a call to the builtin
2172 function. */
2173
2174 static rtx
2175 expand_builtin_sincos (tree exp)
2176 {
2177 rtx op0, op1, op2, target1, target2;
2178 tree arglist = TREE_OPERAND (exp, 1);
2179 enum machine_mode mode;
2180 tree arg, sinp, cosp;
2181 int result;
2182
2183 if (!validate_arglist (arglist, REAL_TYPE,
2184 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2185 return 0;
2186
2187 arg = TREE_VALUE (arglist);
2188 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2189 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2190
2191 /* Make a suitable register to place result in. */
2192 mode = TYPE_MODE (TREE_TYPE (arg));
2193
2194 /* Check if sincos insn is available, otherwise emit the call. */
2195 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2196 return NULL_RTX;
2197
2198 target1 = gen_reg_rtx (mode);
2199 target2 = gen_reg_rtx (mode);
2200
2201 op0 = expand_normal (arg);
2202 op1 = expand_normal (build_fold_indirect_ref (sinp));
2203 op2 = expand_normal (build_fold_indirect_ref (cosp));
2204
2205 /* Compute into target1 and target2.
2206 Set TARGET to wherever the result comes back. */
2207 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2208 gcc_assert (result);
2209
2210 /* Move target1 and target2 to the memory locations indicated
2211 by op1 and op2. */
2212 emit_move_insn (op1, target1);
2213 emit_move_insn (op2, target2);
2214
2215 return const0_rtx;
2216 }
2217
2218 /* Expand a call to one of the builtin rounding functions gcc defines
2219 as an extension (lfloor and lceil). As these are gcc extensions we
2220 do not need to worry about setting errno to EDOM.
2221 If expanding via optab fails, lower expression to (int)(floor(x)).
2222 EXP is the expression that is a call to the builtin function;
2223 if convenient, the result should be placed in TARGET. SUBTARGET may
2224 be used as the target for computing one of EXP's operands. */
2225
2226 static rtx
2227 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2228 {
2229 convert_optab builtin_optab;
2230 rtx op0, insns, tmp;
2231 tree fndecl = get_callee_fndecl (exp);
2232 tree arglist = TREE_OPERAND (exp, 1);
2233 enum built_in_function fallback_fn;
2234 tree fallback_fndecl;
2235 enum machine_mode mode;
2236 tree arg, narg;
2237
2238 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2239 gcc_unreachable ();
2240
2241 arg = TREE_VALUE (arglist);
2242
2243 switch (DECL_FUNCTION_CODE (fndecl))
2244 {
2245 CASE_FLT_FN (BUILT_IN_LCEIL):
2246 CASE_FLT_FN (BUILT_IN_LLCEIL):
2247 builtin_optab = lceil_optab;
2248 fallback_fn = BUILT_IN_CEIL;
2249 break;
2250
2251 CASE_FLT_FN (BUILT_IN_LFLOOR):
2252 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2253 builtin_optab = lfloor_optab;
2254 fallback_fn = BUILT_IN_FLOOR;
2255 break;
2256
2257 default:
2258 gcc_unreachable ();
2259 }
2260
2261 /* Make a suitable register to place result in. */
2262 mode = TYPE_MODE (TREE_TYPE (exp));
2263
2264 target = gen_reg_rtx (mode);
2265
2266 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2267 need to expand the argument again. This way, we will not perform
2268 side-effects more the once. */
2269 narg = builtin_save_expr (arg);
2270 if (narg != arg)
2271 {
2272 arg = narg;
2273 arglist = build_tree_list (NULL_TREE, arg);
2274 exp = build_function_call_expr (fndecl, arglist);
2275 }
2276
2277 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2278
2279 start_sequence ();
2280
2281 /* Compute into TARGET. */
2282 if (expand_sfix_optab (target, op0, builtin_optab))
2283 {
2284 /* Output the entire sequence. */
2285 insns = get_insns ();
2286 end_sequence ();
2287 emit_insn (insns);
2288 return target;
2289 }
2290
2291 /* If we were unable to expand via the builtin, stop the sequence
2292 (without outputting the insns). */
2293 end_sequence ();
2294
2295 /* Fall back to floating point rounding optab. */
2296 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2297 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2298 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2299 gcc_assert (fallback_fndecl != NULL_TREE);
2300 exp = build_function_call_expr (fallback_fndecl, arglist);
2301
2302 tmp = expand_normal (exp);
2303
2304 /* Truncate the result of floating point optab to integer
2305 via expand_fix (). */
2306 target = gen_reg_rtx (mode);
2307 expand_fix (target, tmp, 0);
2308
2309 return target;
2310 }
2311
2312 /* Expand a call to one of the builtin math functions doing integer
2313 conversion (lrint).
2314 Return 0 if a normal call should be emitted rather than expanding the
2315 function in-line. EXP is the expression that is a call to the builtin
2316 function; if convenient, the result should be placed in TARGET.
2317 SUBTARGET may be used as the target for computing one of EXP's operands. */
2318
2319 static rtx
2320 expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
2321 {
2322 convert_optab builtin_optab;
2323 rtx op0, insns;
2324 tree fndecl = get_callee_fndecl (exp);
2325 tree arglist = TREE_OPERAND (exp, 1);
2326 enum machine_mode mode;
2327 tree arg, narg;
2328
2329 /* There's no easy way to detect the case we need to set EDOM. */
2330 if (flag_errno_math)
2331 return NULL_RTX;
2332
2333 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2334 return NULL_RTX;
2335
2336 arg = TREE_VALUE (arglist);
2337
2338 switch (DECL_FUNCTION_CODE (fndecl))
2339 {
2340 CASE_FLT_FN (BUILT_IN_LRINT):
2341 CASE_FLT_FN (BUILT_IN_LLRINT):
2342 builtin_optab = lrint_optab; break;
2343 CASE_FLT_FN (BUILT_IN_LROUND):
2344 CASE_FLT_FN (BUILT_IN_LLROUND):
2345 builtin_optab = lround_optab; break;
2346 default:
2347 gcc_unreachable ();
2348 }
2349
2350 /* Make a suitable register to place result in. */
2351 mode = TYPE_MODE (TREE_TYPE (exp));
2352
2353 target = gen_reg_rtx (mode);
2354
2355 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2356 need to expand the argument again. This way, we will not perform
2357 side-effects more the once. */
2358 narg = builtin_save_expr (arg);
2359 if (narg != arg)
2360 {
2361 arg = narg;
2362 arglist = build_tree_list (NULL_TREE, arg);
2363 exp = build_function_call_expr (fndecl, arglist);
2364 }
2365
2366 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2367
2368 start_sequence ();
2369
2370 if (expand_sfix_optab (target, op0, builtin_optab))
2371 {
2372 /* Output the entire sequence. */
2373 insns = get_insns ();
2374 end_sequence ();
2375 emit_insn (insns);
2376 return target;
2377 }
2378
2379 /* If we were unable to expand via the builtin, stop the sequence
2380 (without outputting the insns) and call to the library function
2381 with the stabilized argument list. */
2382 end_sequence ();
2383
2384 target = expand_call (exp, target, target == const0_rtx);
2385
2386 return target;
2387 }
2388
2389 /* To evaluate powi(x,n), the floating point value x raised to the
2390 constant integer exponent n, we use a hybrid algorithm that
2391 combines the "window method" with look-up tables. For an
2392 introduction to exponentiation algorithms and "addition chains",
2393 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2394 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2395 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2396 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2397
2398 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2399 multiplications to inline before calling the system library's pow
2400 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2401 so this default never requires calling pow, powf or powl. */
2402
2403 #ifndef POWI_MAX_MULTS
2404 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2405 #endif
2406
2407 /* The size of the "optimal power tree" lookup table. All
2408 exponents less than this value are simply looked up in the
2409 powi_table below. This threshold is also used to size the
2410 cache of pseudo registers that hold intermediate results. */
2411 #define POWI_TABLE_SIZE 256
2412
2413 /* The size, in bits of the window, used in the "window method"
2414 exponentiation algorithm. This is equivalent to a radix of
2415 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2416 #define POWI_WINDOW_SIZE 3
2417
2418 /* The following table is an efficient representation of an
2419 "optimal power tree". For each value, i, the corresponding
2420 value, j, in the table states than an optimal evaluation
2421 sequence for calculating pow(x,i) can be found by evaluating
2422 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2423 100 integers is given in Knuth's "Seminumerical algorithms". */
2424
2425 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2426 {
2427 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2428 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2429 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2430 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2431 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2432 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2433 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2434 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2435 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2436 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2437 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2438 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2439 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2440 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2441 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2442 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2443 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2444 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2445 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2446 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2447 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2448 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2449 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2450 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2451 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2452 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2453 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2454 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2455 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2456 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2457 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2458 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2459 };
2460
2461
2462 /* Return the number of multiplications required to calculate
2463 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2464 subroutine of powi_cost. CACHE is an array indicating
2465 which exponents have already been calculated. */
2466
2467 static int
2468 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2469 {
2470 /* If we've already calculated this exponent, then this evaluation
2471 doesn't require any additional multiplications. */
2472 if (cache[n])
2473 return 0;
2474
2475 cache[n] = true;
2476 return powi_lookup_cost (n - powi_table[n], cache)
2477 + powi_lookup_cost (powi_table[n], cache) + 1;
2478 }
2479
2480 /* Return the number of multiplications required to calculate
2481 powi(x,n) for an arbitrary x, given the exponent N. This
2482 function needs to be kept in sync with expand_powi below. */
2483
2484 static int
2485 powi_cost (HOST_WIDE_INT n)
2486 {
2487 bool cache[POWI_TABLE_SIZE];
2488 unsigned HOST_WIDE_INT digit;
2489 unsigned HOST_WIDE_INT val;
2490 int result;
2491
2492 if (n == 0)
2493 return 0;
2494
2495 /* Ignore the reciprocal when calculating the cost. */
2496 val = (n < 0) ? -n : n;
2497
2498 /* Initialize the exponent cache. */
2499 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2500 cache[1] = true;
2501
2502 result = 0;
2503
2504 while (val >= POWI_TABLE_SIZE)
2505 {
2506 if (val & 1)
2507 {
2508 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2509 result += powi_lookup_cost (digit, cache)
2510 + POWI_WINDOW_SIZE + 1;
2511 val >>= POWI_WINDOW_SIZE;
2512 }
2513 else
2514 {
2515 val >>= 1;
2516 result++;
2517 }
2518 }
2519
2520 return result + powi_lookup_cost (val, cache);
2521 }
2522
2523 /* Recursive subroutine of expand_powi. This function takes the array,
2524 CACHE, of already calculated exponents and an exponent N and returns
2525 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2526
2527 static rtx
2528 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2529 {
2530 unsigned HOST_WIDE_INT digit;
2531 rtx target, result;
2532 rtx op0, op1;
2533
2534 if (n < POWI_TABLE_SIZE)
2535 {
2536 if (cache[n])
2537 return cache[n];
2538
2539 target = gen_reg_rtx (mode);
2540 cache[n] = target;
2541
2542 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2543 op1 = expand_powi_1 (mode, powi_table[n], cache);
2544 }
2545 else if (n & 1)
2546 {
2547 target = gen_reg_rtx (mode);
2548 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2549 op0 = expand_powi_1 (mode, n - digit, cache);
2550 op1 = expand_powi_1 (mode, digit, cache);
2551 }
2552 else
2553 {
2554 target = gen_reg_rtx (mode);
2555 op0 = expand_powi_1 (mode, n >> 1, cache);
2556 op1 = op0;
2557 }
2558
2559 result = expand_mult (mode, op0, op1, target, 0);
2560 if (result != target)
2561 emit_move_insn (target, result);
2562 return target;
2563 }
2564
2565 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2566 floating point operand in mode MODE, and N is the exponent. This
2567 function needs to be kept in sync with powi_cost above. */
2568
2569 static rtx
2570 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2571 {
2572 unsigned HOST_WIDE_INT val;
2573 rtx cache[POWI_TABLE_SIZE];
2574 rtx result;
2575
2576 if (n == 0)
2577 return CONST1_RTX (mode);
2578
2579 val = (n < 0) ? -n : n;
2580
2581 memset (cache, 0, sizeof (cache));
2582 cache[1] = x;
2583
2584 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2585
2586 /* If the original exponent was negative, reciprocate the result. */
2587 if (n < 0)
2588 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2589 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2590
2591 return result;
2592 }
2593
2594 /* Expand a call to the pow built-in mathematical function. Return 0 if
2595 a normal call should be emitted rather than expanding the function
2596 in-line. EXP is the expression that is a call to the builtin
2597 function; if convenient, the result should be placed in TARGET. */
2598
2599 static rtx
2600 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2601 {
2602 tree arg0, arg1, fn, narg0, narglist;
2603 tree arglist = TREE_OPERAND (exp, 1);
2604 tree type = TREE_TYPE (exp);
2605 REAL_VALUE_TYPE cint, c, c2;
2606 HOST_WIDE_INT n;
2607 rtx op, op2;
2608 enum machine_mode mode = TYPE_MODE (type);
2609
2610 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2611 return 0;
2612
2613 arg0 = TREE_VALUE (arglist);
2614 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2615
2616 if (TREE_CODE (arg1) != REAL_CST
2617 || TREE_CONSTANT_OVERFLOW (arg1))
2618 return expand_builtin_mathfn_2 (exp, target, subtarget);
2619
2620 /* Handle constant exponents. */
2621
2622 /* For integer valued exponents we can expand to an optimal multiplication
2623 sequence using expand_powi. */
2624 c = TREE_REAL_CST (arg1);
2625 n = real_to_integer (&c);
2626 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2627 if (real_identical (&c, &cint)
2628 && ((n >= -1 && n <= 2)
2629 || (flag_unsafe_math_optimizations
2630 && !optimize_size
2631 && powi_cost (n) <= POWI_MAX_MULTS)))
2632 {
2633 op = expand_expr (arg0, subtarget, VOIDmode, 0);
2634 if (n != 1)
2635 {
2636 op = force_reg (mode, op);
2637 op = expand_powi (op, mode, n);
2638 }
2639 return op;
2640 }
2641
2642 narg0 = builtin_save_expr (arg0);
2643 narglist = build_tree_list (NULL_TREE, narg0);
2644
2645 /* If the exponent is not integer valued, check if it is half of an integer.
2646 In this case we can expand to sqrt (x) * x**(n/2). */
2647 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2648 if (fn != NULL_TREE)
2649 {
2650 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2651 n = real_to_integer (&c2);
2652 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2653 if (real_identical (&c2, &cint)
2654 && ((flag_unsafe_math_optimizations
2655 && !optimize_size
2656 && powi_cost (n/2) <= POWI_MAX_MULTS)
2657 || n == 1))
2658 {
2659 tree call_expr = build_function_call_expr (fn, narglist);
2660 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2661 if (n != 1)
2662 {
2663 op2 = expand_expr (narg0, subtarget, VOIDmode, 0);
2664 op2 = force_reg (mode, op2);
2665 op2 = expand_powi (op2, mode, abs (n / 2));
2666 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2667 0, OPTAB_LIB_WIDEN);
2668 /* If the original exponent was negative, reciprocate the
2669 result. */
2670 if (n < 0)
2671 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2672 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2673 }
2674 return op;
2675 }
2676 }
2677
2678 /* Try if the exponent is a third of an integer. In this case
2679 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
2680 different from pow (x, 1./3.) due to rounding and behavior
2681 with negative x we need to constrain this transformation to
2682 unsafe math and positive x or finite math. */
2683 fn = mathfn_built_in (type, BUILT_IN_CBRT);
2684 if (fn != NULL_TREE
2685 && flag_unsafe_math_optimizations
2686 && (tree_expr_nonnegative_p (arg0)
2687 || !HONOR_NANS (mode)))
2688 {
2689 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2690 real_round (&c2, mode, &c2);
2691 n = real_to_integer (&c2);
2692 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2693 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2694 real_convert (&c2, mode, &c2);
2695 if (real_identical (&c2, &c)
2696 && ((!optimize_size
2697 && powi_cost (n/3) <= POWI_MAX_MULTS)
2698 || n == 1))
2699 {
2700 tree call_expr = build_function_call_expr (fn, narglist);
2701 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2702 if (abs (n) % 3 == 2)
2703 op = expand_simple_binop (mode, MULT, op, op, op,
2704 0, OPTAB_LIB_WIDEN);
2705 if (n != 1)
2706 {
2707 op2 = expand_expr (narg0, subtarget, VOIDmode, 0);
2708 op2 = force_reg (mode, op2);
2709 op2 = expand_powi (op2, mode, abs (n / 3));
2710 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2711 0, OPTAB_LIB_WIDEN);
2712 /* If the original exponent was negative, reciprocate the
2713 result. */
2714 if (n < 0)
2715 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2716 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2717 }
2718 return op;
2719 }
2720 }
2721
2722 /* Fall back to optab expansion. */
2723 return expand_builtin_mathfn_2 (exp, target, subtarget);
2724 }
2725
2726 /* Expand a call to the powi built-in mathematical function. Return 0 if
2727 a normal call should be emitted rather than expanding the function
2728 in-line. EXP is the expression that is a call to the builtin
2729 function; if convenient, the result should be placed in TARGET. */
2730
2731 static rtx
2732 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2733 {
2734 tree arglist = TREE_OPERAND (exp, 1);
2735 tree arg0, arg1;
2736 rtx op0, op1;
2737 enum machine_mode mode;
2738 enum machine_mode mode2;
2739
2740 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2741 return 0;
2742
2743 arg0 = TREE_VALUE (arglist);
2744 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2745 mode = TYPE_MODE (TREE_TYPE (exp));
2746
2747 /* Handle constant power. */
2748
2749 if (TREE_CODE (arg1) == INTEGER_CST
2750 && ! TREE_CONSTANT_OVERFLOW (arg1))
2751 {
2752 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2753
2754 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2755 Otherwise, check the number of multiplications required. */
2756 if ((TREE_INT_CST_HIGH (arg1) == 0
2757 || TREE_INT_CST_HIGH (arg1) == -1)
2758 && ((n >= -1 && n <= 2)
2759 || (! optimize_size
2760 && powi_cost (n) <= POWI_MAX_MULTS)))
2761 {
2762 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2763 op0 = force_reg (mode, op0);
2764 return expand_powi (op0, mode, n);
2765 }
2766 }
2767
2768 /* Emit a libcall to libgcc. */
2769
2770 /* Mode of the 2nd argument must match that of an int. */
2771 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2772
2773 if (target == NULL_RTX)
2774 target = gen_reg_rtx (mode);
2775
2776 op0 = expand_expr (arg0, subtarget, mode, 0);
2777 if (GET_MODE (op0) != mode)
2778 op0 = convert_to_mode (mode, op0, 0);
2779 op1 = expand_expr (arg1, 0, mode2, 0);
2780 if (GET_MODE (op1) != mode2)
2781 op1 = convert_to_mode (mode2, op1, 0);
2782
2783 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2784 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2785 op0, mode, op1, mode2);
2786
2787 return target;
2788 }
2789
2790 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2791 if we failed the caller should emit a normal call, otherwise
2792 try to get the result in TARGET, if convenient. */
2793
2794 static rtx
2795 expand_builtin_strlen (tree arglist, rtx target,
2796 enum machine_mode target_mode)
2797 {
2798 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2799 return 0;
2800 else
2801 {
2802 rtx pat;
2803 tree len, src = TREE_VALUE (arglist);
2804 rtx result, src_reg, char_rtx, before_strlen;
2805 enum machine_mode insn_mode = target_mode, char_mode;
2806 enum insn_code icode = CODE_FOR_nothing;
2807 int align;
2808
2809 /* If the length can be computed at compile-time, return it. */
2810 len = c_strlen (src, 0);
2811 if (len)
2812 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2813
2814 /* If the length can be computed at compile-time and is constant
2815 integer, but there are side-effects in src, evaluate
2816 src for side-effects, then return len.
2817 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2818 can be optimized into: i++; x = 3; */
2819 len = c_strlen (src, 1);
2820 if (len && TREE_CODE (len) == INTEGER_CST)
2821 {
2822 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2823 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2824 }
2825
2826 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2827
2828 /* If SRC is not a pointer type, don't do this operation inline. */
2829 if (align == 0)
2830 return 0;
2831
2832 /* Bail out if we can't compute strlen in the right mode. */
2833 while (insn_mode != VOIDmode)
2834 {
2835 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2836 if (icode != CODE_FOR_nothing)
2837 break;
2838
2839 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2840 }
2841 if (insn_mode == VOIDmode)
2842 return 0;
2843
2844 /* Make a place to write the result of the instruction. */
2845 result = target;
2846 if (! (result != 0
2847 && REG_P (result)
2848 && GET_MODE (result) == insn_mode
2849 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2850 result = gen_reg_rtx (insn_mode);
2851
2852 /* Make a place to hold the source address. We will not expand
2853 the actual source until we are sure that the expansion will
2854 not fail -- there are trees that cannot be expanded twice. */
2855 src_reg = gen_reg_rtx (Pmode);
2856
2857 /* Mark the beginning of the strlen sequence so we can emit the
2858 source operand later. */
2859 before_strlen = get_last_insn ();
2860
2861 char_rtx = const0_rtx;
2862 char_mode = insn_data[(int) icode].operand[2].mode;
2863 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2864 char_mode))
2865 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2866
2867 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2868 char_rtx, GEN_INT (align));
2869 if (! pat)
2870 return 0;
2871 emit_insn (pat);
2872
2873 /* Now that we are assured of success, expand the source. */
2874 start_sequence ();
2875 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2876 if (pat != src_reg)
2877 emit_move_insn (src_reg, pat);
2878 pat = get_insns ();
2879 end_sequence ();
2880
2881 if (before_strlen)
2882 emit_insn_after (pat, before_strlen);
2883 else
2884 emit_insn_before (pat, get_insns ());
2885
2886 /* Return the value in the proper mode for this function. */
2887 if (GET_MODE (result) == target_mode)
2888 target = result;
2889 else if (target != 0)
2890 convert_move (target, result, 0);
2891 else
2892 target = convert_to_mode (target_mode, result, 0);
2893
2894 return target;
2895 }
2896 }
2897
2898 /* Expand a call to the strstr builtin. Return 0 if we failed the
2899 caller should emit a normal call, otherwise try to get the result
2900 in TARGET, if convenient (and in mode MODE if that's convenient). */
2901
2902 static rtx
2903 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2904 {
2905 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2906 {
2907 tree result = fold_builtin_strstr (arglist, type);
2908 if (result)
2909 return expand_expr (result, target, mode, EXPAND_NORMAL);
2910 }
2911 return 0;
2912 }
2913
2914 /* Expand a call to the strchr builtin. Return 0 if we failed the
2915 caller should emit a normal call, otherwise try to get the result
2916 in TARGET, if convenient (and in mode MODE if that's convenient). */
2917
2918 static rtx
2919 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2920 {
2921 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2922 {
2923 tree result = fold_builtin_strchr (arglist, type);
2924 if (result)
2925 return expand_expr (result, target, mode, EXPAND_NORMAL);
2926
2927 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2928 }
2929 return 0;
2930 }
2931
2932 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2933 caller should emit a normal call, otherwise try to get the result
2934 in TARGET, if convenient (and in mode MODE if that's convenient). */
2935
2936 static rtx
2937 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2938 {
2939 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2940 {
2941 tree result = fold_builtin_strrchr (arglist, type);
2942 if (result)
2943 return expand_expr (result, target, mode, EXPAND_NORMAL);
2944 }
2945 return 0;
2946 }
2947
2948 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2949 caller should emit a normal call, otherwise try to get the result
2950 in TARGET, if convenient (and in mode MODE if that's convenient). */
2951
2952 static rtx
2953 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2954 {
2955 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2956 {
2957 tree result = fold_builtin_strpbrk (arglist, type);
2958 if (result)
2959 return expand_expr (result, target, mode, EXPAND_NORMAL);
2960 }
2961 return 0;
2962 }
2963
2964 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2965 bytes from constant string DATA + OFFSET and return it as target
2966 constant. */
2967
2968 static rtx
2969 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2970 enum machine_mode mode)
2971 {
2972 const char *str = (const char *) data;
2973
2974 gcc_assert (offset >= 0
2975 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2976 <= strlen (str) + 1));
2977
2978 return c_readstr (str + offset, mode);
2979 }
2980
2981 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2982 Return 0 if we failed, the caller should emit a normal call,
2983 otherwise try to get the result in TARGET, if convenient (and in
2984 mode MODE if that's convenient). */
2985 static rtx
2986 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2987 {
2988 tree fndecl = get_callee_fndecl (exp);
2989 tree arglist = TREE_OPERAND (exp, 1);
2990 if (!validate_arglist (arglist,
2991 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2992 return 0;
2993 else
2994 {
2995 tree dest = TREE_VALUE (arglist);
2996 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2997 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2998 const char *src_str;
2999 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3000 unsigned int dest_align
3001 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3002 rtx dest_mem, src_mem, dest_addr, len_rtx;
3003 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
3004 false, /*endp=*/0);
3005
3006 if (result)
3007 {
3008 while (TREE_CODE (result) == COMPOUND_EXPR)
3009 {
3010 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3011 EXPAND_NORMAL);
3012 result = TREE_OPERAND (result, 1);
3013 }
3014 return expand_expr (result, target, mode, EXPAND_NORMAL);
3015 }
3016
3017 /* If DEST is not a pointer type, call the normal function. */
3018 if (dest_align == 0)
3019 return 0;
3020
3021 /* If either SRC is not a pointer type, don't do this
3022 operation in-line. */
3023 if (src_align == 0)
3024 return 0;
3025
3026 dest_mem = get_memory_rtx (dest, len);
3027 set_mem_align (dest_mem, dest_align);
3028 len_rtx = expand_normal (len);
3029 src_str = c_getstr (src);
3030
3031 /* If SRC is a string constant and block move would be done
3032 by pieces, we can avoid loading the string from memory
3033 and only stored the computed constants. */
3034 if (src_str
3035 && GET_CODE (len_rtx) == CONST_INT
3036 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3037 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3038 (void *) src_str, dest_align))
3039 {
3040 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3041 builtin_memcpy_read_str,
3042 (void *) src_str, dest_align, 0);
3043 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3044 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3045 return dest_mem;
3046 }
3047
3048 src_mem = get_memory_rtx (src, len);
3049 set_mem_align (src_mem, src_align);
3050
3051 /* Copy word part most expediently. */
3052 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
3053 CALL_EXPR_TAILCALL (exp)
3054 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3055
3056 if (dest_addr == 0)
3057 {
3058 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3059 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3060 }
3061 return dest_addr;
3062 }
3063 }
3064
3065 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
3066 Return 0 if we failed; the caller should emit a normal call,
3067 otherwise try to get the result in TARGET, if convenient (and in
3068 mode MODE if that's convenient). If ENDP is 0 return the
3069 destination pointer, if ENDP is 1 return the end pointer ala
3070 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3071 stpcpy. */
3072
3073 static rtx
3074 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
3075 int endp)
3076 {
3077 if (!validate_arglist (arglist,
3078 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3079 return 0;
3080 /* If return value is ignored, transform mempcpy into memcpy. */
3081 else if (target == const0_rtx)
3082 {
3083 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3084
3085 if (!fn)
3086 return 0;
3087
3088 return expand_expr (build_function_call_expr (fn, arglist),
3089 target, mode, EXPAND_NORMAL);
3090 }
3091 else
3092 {
3093 tree dest = TREE_VALUE (arglist);
3094 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3095 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3096 const char *src_str;
3097 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3098 unsigned int dest_align
3099 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3100 rtx dest_mem, src_mem, len_rtx;
3101 tree result = fold_builtin_memory_op (arglist, type, false, endp);
3102
3103 if (result)
3104 {
3105 while (TREE_CODE (result) == COMPOUND_EXPR)
3106 {
3107 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3108 EXPAND_NORMAL);
3109 result = TREE_OPERAND (result, 1);
3110 }
3111 return expand_expr (result, target, mode, EXPAND_NORMAL);
3112 }
3113
3114 /* If either SRC or DEST is not a pointer type, don't do this
3115 operation in-line. */
3116 if (dest_align == 0 || src_align == 0)
3117 return 0;
3118
3119 /* If LEN is not constant, call the normal function. */
3120 if (! host_integerp (len, 1))
3121 return 0;
3122
3123 len_rtx = expand_normal (len);
3124 src_str = c_getstr (src);
3125
3126 /* If SRC is a string constant and block move would be done
3127 by pieces, we can avoid loading the string from memory
3128 and only stored the computed constants. */
3129 if (src_str
3130 && GET_CODE (len_rtx) == CONST_INT
3131 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3132 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3133 (void *) src_str, dest_align))
3134 {
3135 dest_mem = get_memory_rtx (dest, len);
3136 set_mem_align (dest_mem, dest_align);
3137 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3138 builtin_memcpy_read_str,
3139 (void *) src_str, dest_align, endp);
3140 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3141 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3142 return dest_mem;
3143 }
3144
3145 if (GET_CODE (len_rtx) == CONST_INT
3146 && can_move_by_pieces (INTVAL (len_rtx),
3147 MIN (dest_align, src_align)))
3148 {
3149 dest_mem = get_memory_rtx (dest, len);
3150 set_mem_align (dest_mem, dest_align);
3151 src_mem = get_memory_rtx (src, len);
3152 set_mem_align (src_mem, src_align);
3153 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3154 MIN (dest_align, src_align), endp);
3155 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3156 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3157 return dest_mem;
3158 }
3159
3160 return 0;
3161 }
3162 }
3163
3164 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3165 if we failed; the caller should emit a normal call. */
3166
3167 static rtx
3168 expand_builtin_memmove (tree arglist, tree type, rtx target,
3169 enum machine_mode mode)
3170 {
3171 if (!validate_arglist (arglist,
3172 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3173 return 0;
3174 else
3175 {
3176 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3177
3178 if (result)
3179 {
3180 while (TREE_CODE (result) == COMPOUND_EXPR)
3181 {
3182 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3183 EXPAND_NORMAL);
3184 result = TREE_OPERAND (result, 1);
3185 }
3186 return expand_expr (result, target, mode, EXPAND_NORMAL);
3187 }
3188
3189 /* Otherwise, call the normal function. */
3190 return 0;
3191 }
3192 }
3193
3194 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3195 if we failed the caller should emit a normal call. */
3196
3197 static rtx
3198 expand_builtin_bcopy (tree exp)
3199 {
3200 tree arglist = TREE_OPERAND (exp, 1);
3201 tree type = TREE_TYPE (exp);
3202 tree src, dest, size, newarglist;
3203
3204 if (!validate_arglist (arglist,
3205 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3206 return NULL_RTX;
3207
3208 src = TREE_VALUE (arglist);
3209 dest = TREE_VALUE (TREE_CHAIN (arglist));
3210 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3211
3212 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3213 memmove(ptr y, ptr x, size_t z). This is done this way
3214 so that if it isn't expanded inline, we fallback to
3215 calling bcopy instead of memmove. */
3216
3217 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3218 newarglist = tree_cons (NULL_TREE, src, newarglist);
3219 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3220
3221 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
3222 }
3223
3224 #ifndef HAVE_movstr
3225 # define HAVE_movstr 0
3226 # define CODE_FOR_movstr CODE_FOR_nothing
3227 #endif
3228
3229 /* Expand into a movstr instruction, if one is available. Return 0 if
3230 we failed, the caller should emit a normal call, otherwise try to
3231 get the result in TARGET, if convenient. If ENDP is 0 return the
3232 destination pointer, if ENDP is 1 return the end pointer ala
3233 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3234 stpcpy. */
3235
3236 static rtx
3237 expand_movstr (tree dest, tree src, rtx target, int endp)
3238 {
3239 rtx end;
3240 rtx dest_mem;
3241 rtx src_mem;
3242 rtx insn;
3243 const struct insn_data * data;
3244
3245 if (!HAVE_movstr)
3246 return 0;
3247
3248 dest_mem = get_memory_rtx (dest, NULL);
3249 src_mem = get_memory_rtx (src, NULL);
3250 if (!endp)
3251 {
3252 target = force_reg (Pmode, XEXP (dest_mem, 0));
3253 dest_mem = replace_equiv_address (dest_mem, target);
3254 end = gen_reg_rtx (Pmode);
3255 }
3256 else
3257 {
3258 if (target == 0 || target == const0_rtx)
3259 {
3260 end = gen_reg_rtx (Pmode);
3261 if (target == 0)
3262 target = end;
3263 }
3264 else
3265 end = target;
3266 }
3267
3268 data = insn_data + CODE_FOR_movstr;
3269
3270 if (data->operand[0].mode != VOIDmode)
3271 end = gen_lowpart (data->operand[0].mode, end);
3272
3273 insn = data->genfun (end, dest_mem, src_mem);
3274
3275 gcc_assert (insn);
3276
3277 emit_insn (insn);
3278
3279 /* movstr is supposed to set end to the address of the NUL
3280 terminator. If the caller requested a mempcpy-like return value,
3281 adjust it. */
3282 if (endp == 1 && target != const0_rtx)
3283 {
3284 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3285 emit_move_insn (target, force_operand (tem, NULL_RTX));
3286 }
3287
3288 return target;
3289 }
3290
3291 /* Expand expression EXP, which is a call to the strcpy 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). */
3295
3296 static rtx
3297 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3298 {
3299 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3300 {
3301 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3302 if (result)
3303 {
3304 while (TREE_CODE (result) == COMPOUND_EXPR)
3305 {
3306 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3307 EXPAND_NORMAL);
3308 result = TREE_OPERAND (result, 1);
3309 }
3310 return expand_expr (result, target, mode, EXPAND_NORMAL);
3311 }
3312
3313 return expand_movstr (TREE_VALUE (arglist),
3314 TREE_VALUE (TREE_CHAIN (arglist)),
3315 target, /*endp=*/0);
3316 }
3317 return 0;
3318 }
3319
3320 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3321 Return 0 if we failed the caller should emit a normal call,
3322 otherwise try to get the result in TARGET, if convenient (and in
3323 mode MODE if that's convenient). */
3324
3325 static rtx
3326 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3327 {
3328 tree arglist = TREE_OPERAND (exp, 1);
3329 /* If return value is ignored, transform stpcpy into strcpy. */
3330 if (target == const0_rtx)
3331 {
3332 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3333 if (!fn)
3334 return 0;
3335
3336 return expand_expr (build_function_call_expr (fn, arglist),
3337 target, mode, EXPAND_NORMAL);
3338 }
3339
3340 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3341 return 0;
3342 else
3343 {
3344 tree dst, src, len, lenp1;
3345 tree narglist;
3346 rtx ret;
3347
3348 /* Ensure we get an actual string whose length can be evaluated at
3349 compile-time, not an expression containing a string. This is
3350 because the latter will potentially produce pessimized code
3351 when used to produce the return value. */
3352 src = TREE_VALUE (TREE_CHAIN (arglist));
3353 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3354 return expand_movstr (TREE_VALUE (arglist),
3355 TREE_VALUE (TREE_CHAIN (arglist)),
3356 target, /*endp=*/2);
3357
3358 dst = TREE_VALUE (arglist);
3359 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3360 narglist = build_tree_list (NULL_TREE, lenp1);
3361 narglist = tree_cons (NULL_TREE, src, narglist);
3362 narglist = tree_cons (NULL_TREE, dst, narglist);
3363 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3364 target, mode, /*endp=*/2);
3365
3366 if (ret)
3367 return ret;
3368
3369 if (TREE_CODE (len) == INTEGER_CST)
3370 {
3371 rtx len_rtx = expand_normal (len);
3372
3373 if (GET_CODE (len_rtx) == CONST_INT)
3374 {
3375 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3376 arglist, target, mode);
3377
3378 if (ret)
3379 {
3380 if (! target)
3381 {
3382 if (mode != VOIDmode)
3383 target = gen_reg_rtx (mode);
3384 else
3385 target = gen_reg_rtx (GET_MODE (ret));
3386 }
3387 if (GET_MODE (target) != GET_MODE (ret))
3388 ret = gen_lowpart (GET_MODE (target), ret);
3389
3390 ret = plus_constant (ret, INTVAL (len_rtx));
3391 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3392 gcc_assert (ret);
3393
3394 return target;
3395 }
3396 }
3397 }
3398
3399 return expand_movstr (TREE_VALUE (arglist),
3400 TREE_VALUE (TREE_CHAIN (arglist)),
3401 target, /*endp=*/2);
3402 }
3403 }
3404
3405 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3406 bytes from constant string DATA + OFFSET and return it as target
3407 constant. */
3408
3409 static rtx
3410 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3411 enum machine_mode mode)
3412 {
3413 const char *str = (const char *) data;
3414
3415 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3416 return const0_rtx;
3417
3418 return c_readstr (str + offset, mode);
3419 }
3420
3421 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3422 if we failed the caller should emit a normal call. */
3423
3424 static rtx
3425 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3426 {
3427 tree fndecl = get_callee_fndecl (exp);
3428 tree arglist = TREE_OPERAND (exp, 1);
3429 if (validate_arglist (arglist,
3430 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3431 {
3432 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3433 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3434 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3435
3436 if (result)
3437 {
3438 while (TREE_CODE (result) == COMPOUND_EXPR)
3439 {
3440 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3441 EXPAND_NORMAL);
3442 result = TREE_OPERAND (result, 1);
3443 }
3444 return expand_expr (result, target, mode, EXPAND_NORMAL);
3445 }
3446
3447 /* We must be passed a constant len and src parameter. */
3448 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3449 return 0;
3450
3451 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3452
3453 /* We're required to pad with trailing zeros if the requested
3454 len is greater than strlen(s2)+1. In that case try to
3455 use store_by_pieces, if it fails, punt. */
3456 if (tree_int_cst_lt (slen, len))
3457 {
3458 tree dest = TREE_VALUE (arglist);
3459 unsigned int dest_align
3460 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3461 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3462 rtx dest_mem;
3463
3464 if (!p || dest_align == 0 || !host_integerp (len, 1)
3465 || !can_store_by_pieces (tree_low_cst (len, 1),
3466 builtin_strncpy_read_str,
3467 (void *) p, dest_align))
3468 return 0;
3469
3470 dest_mem = get_memory_rtx (dest, len);
3471 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3472 builtin_strncpy_read_str,
3473 (void *) p, dest_align, 0);
3474 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3475 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3476 return dest_mem;
3477 }
3478 }
3479 return 0;
3480 }
3481
3482 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3483 bytes from constant string DATA + OFFSET and return it as target
3484 constant. */
3485
3486 rtx
3487 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3488 enum machine_mode mode)
3489 {
3490 const char *c = (const char *) data;
3491 char *p = alloca (GET_MODE_SIZE (mode));
3492
3493 memset (p, *c, GET_MODE_SIZE (mode));
3494
3495 return c_readstr (p, mode);
3496 }
3497
3498 /* Callback routine for store_by_pieces. Return the RTL of a register
3499 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3500 char value given in the RTL register data. For example, if mode is
3501 4 bytes wide, return the RTL for 0x01010101*data. */
3502
3503 static rtx
3504 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3505 enum machine_mode mode)
3506 {
3507 rtx target, coeff;
3508 size_t size;
3509 char *p;
3510
3511 size = GET_MODE_SIZE (mode);
3512 if (size == 1)
3513 return (rtx) data;
3514
3515 p = alloca (size);
3516 memset (p, 1, size);
3517 coeff = c_readstr (p, mode);
3518
3519 target = convert_to_mode (mode, (rtx) data, 1);
3520 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3521 return force_reg (mode, target);
3522 }
3523
3524 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3525 if we failed the caller should emit a normal call, otherwise try to get
3526 the result in TARGET, if convenient (and in mode MODE if that's
3527 convenient). */
3528
3529 static rtx
3530 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3531 tree orig_exp)
3532 {
3533 if (!validate_arglist (arglist,
3534 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3535 return 0;
3536 else
3537 {
3538 tree dest = TREE_VALUE (arglist);
3539 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3540 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3541 tree fndecl, fn;
3542 enum built_in_function fcode;
3543 char c;
3544 unsigned int dest_align;
3545 rtx dest_mem, dest_addr, len_rtx;
3546
3547 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3548
3549 /* If DEST is not a pointer type, don't do this
3550 operation in-line. */
3551 if (dest_align == 0)
3552 return 0;
3553
3554 /* If the LEN parameter is zero, return DEST. */
3555 if (integer_zerop (len))
3556 {
3557 /* Evaluate and ignore VAL in case it has side-effects. */
3558 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3559 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3560 }
3561
3562 /* Stabilize the arguments in case we fail. */
3563 dest = builtin_save_expr (dest);
3564 val = builtin_save_expr (val);
3565 len = builtin_save_expr (len);
3566
3567 len_rtx = expand_normal (len);
3568 dest_mem = get_memory_rtx (dest, len);
3569
3570 if (TREE_CODE (val) != INTEGER_CST)
3571 {
3572 rtx val_rtx;
3573
3574 val_rtx = expand_normal (val);
3575 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3576 val_rtx, 0);
3577
3578 /* Assume that we can memset by pieces if we can store the
3579 * the coefficients by pieces (in the required modes).
3580 * We can't pass builtin_memset_gen_str as that emits RTL. */
3581 c = 1;
3582 if (host_integerp (len, 1)
3583 && !(optimize_size && tree_low_cst (len, 1) > 1)
3584 && can_store_by_pieces (tree_low_cst (len, 1),
3585 builtin_memset_read_str, &c, dest_align))
3586 {
3587 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3588 val_rtx);
3589 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3590 builtin_memset_gen_str, val_rtx, dest_align, 0);
3591 }
3592 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3593 dest_align))
3594 goto do_libcall;
3595
3596 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3597 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3598 return dest_mem;
3599 }
3600
3601 if (target_char_cast (val, &c))
3602 goto do_libcall;
3603
3604 if (c)
3605 {
3606 if (host_integerp (len, 1)
3607 && !(optimize_size && tree_low_cst (len, 1) > 1)
3608 && can_store_by_pieces (tree_low_cst (len, 1),
3609 builtin_memset_read_str, &c, dest_align))
3610 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3611 builtin_memset_read_str, &c, dest_align, 0);
3612 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3613 dest_align))
3614 goto do_libcall;
3615
3616 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3617 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3618 return dest_mem;
3619 }
3620
3621 set_mem_align (dest_mem, dest_align);
3622 dest_addr = clear_storage (dest_mem, len_rtx,
3623 CALL_EXPR_TAILCALL (orig_exp)
3624 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3625
3626 if (dest_addr == 0)
3627 {
3628 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3629 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3630 }
3631
3632 return dest_addr;
3633
3634 do_libcall:
3635 fndecl = get_callee_fndecl (orig_exp);
3636 fcode = DECL_FUNCTION_CODE (fndecl);
3637 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3638 arglist = build_tree_list (NULL_TREE, len);
3639 if (fcode == BUILT_IN_MEMSET)
3640 arglist = tree_cons (NULL_TREE, val, arglist);
3641 arglist = tree_cons (NULL_TREE, dest, arglist);
3642 fn = build_function_call_expr (fndecl, arglist);
3643 if (TREE_CODE (fn) == CALL_EXPR)
3644 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3645 return expand_call (fn, target, target == const0_rtx);
3646 }
3647 }
3648
3649 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3650 if we failed the caller should emit a normal call. */
3651
3652 static rtx
3653 expand_builtin_bzero (tree exp)
3654 {
3655 tree arglist = TREE_OPERAND (exp, 1);
3656 tree dest, size, newarglist;
3657
3658 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3659 return NULL_RTX;
3660
3661 dest = TREE_VALUE (arglist);
3662 size = TREE_VALUE (TREE_CHAIN (arglist));
3663
3664 /* New argument list transforming bzero(ptr x, int y) to
3665 memset(ptr x, int 0, size_t y). This is done this way
3666 so that if it isn't expanded inline, we fallback to
3667 calling bzero instead of memset. */
3668
3669 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3670 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3671 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3672
3673 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3674 }
3675
3676 /* Expand expression EXP, which is a call to the memcmp built-in function.
3677 ARGLIST is the argument list for this call. Return 0 if we failed and the
3678 caller should emit a normal call, otherwise try to get the result in
3679 TARGET, if convenient (and in mode MODE, if that's convenient). */
3680
3681 static rtx
3682 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3683 enum machine_mode mode)
3684 {
3685 if (!validate_arglist (arglist,
3686 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3687 return 0;
3688 else
3689 {
3690 tree result = fold_builtin_memcmp (arglist);
3691 if (result)
3692 return expand_expr (result, target, mode, EXPAND_NORMAL);
3693 }
3694
3695 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3696 {
3697 tree arg1 = TREE_VALUE (arglist);
3698 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3699 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3700 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3701 rtx result;
3702 rtx insn;
3703
3704 int arg1_align
3705 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3706 int arg2_align
3707 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3708 enum machine_mode insn_mode;
3709
3710 #ifdef HAVE_cmpmemsi
3711 if (HAVE_cmpmemsi)
3712 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3713 else
3714 #endif
3715 #ifdef HAVE_cmpstrnsi
3716 if (HAVE_cmpstrnsi)
3717 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3718 else
3719 #endif
3720 return 0;
3721
3722 /* If we don't have POINTER_TYPE, call the function. */
3723 if (arg1_align == 0 || arg2_align == 0)
3724 return 0;
3725
3726 /* Make a place to write the result of the instruction. */
3727 result = target;
3728 if (! (result != 0
3729 && REG_P (result) && GET_MODE (result) == insn_mode
3730 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3731 result = gen_reg_rtx (insn_mode);
3732
3733 arg1_rtx = get_memory_rtx (arg1, len);
3734 arg2_rtx = get_memory_rtx (arg2, len);
3735 arg3_rtx = expand_normal (len);
3736
3737 /* Set MEM_SIZE as appropriate. */
3738 if (GET_CODE (arg3_rtx) == CONST_INT)
3739 {
3740 set_mem_size (arg1_rtx, arg3_rtx);
3741 set_mem_size (arg2_rtx, arg3_rtx);
3742 }
3743
3744 #ifdef HAVE_cmpmemsi
3745 if (HAVE_cmpmemsi)
3746 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3747 GEN_INT (MIN (arg1_align, arg2_align)));
3748 else
3749 #endif
3750 #ifdef HAVE_cmpstrnsi
3751 if (HAVE_cmpstrnsi)
3752 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3753 GEN_INT (MIN (arg1_align, arg2_align)));
3754 else
3755 #endif
3756 gcc_unreachable ();
3757
3758 if (insn)
3759 emit_insn (insn);
3760 else
3761 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3762 TYPE_MODE (integer_type_node), 3,
3763 XEXP (arg1_rtx, 0), Pmode,
3764 XEXP (arg2_rtx, 0), Pmode,
3765 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3766 TYPE_UNSIGNED (sizetype)),
3767 TYPE_MODE (sizetype));
3768
3769 /* Return the value in the proper mode for this function. */
3770 mode = TYPE_MODE (TREE_TYPE (exp));
3771 if (GET_MODE (result) == mode)
3772 return result;
3773 else if (target != 0)
3774 {
3775 convert_move (target, result, 0);
3776 return target;
3777 }
3778 else
3779 return convert_to_mode (mode, result, 0);
3780 }
3781 #endif
3782
3783 return 0;
3784 }
3785
3786 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3787 if we failed the caller should emit a normal call, otherwise try to get
3788 the result in TARGET, if convenient. */
3789
3790 static rtx
3791 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3792 {
3793 tree arglist = TREE_OPERAND (exp, 1);
3794
3795 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3796 return 0;
3797 else
3798 {
3799 tree result = fold_builtin_strcmp (arglist);
3800 if (result)
3801 return expand_expr (result, target, mode, EXPAND_NORMAL);
3802 }
3803
3804 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3805 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3806 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3807 {
3808 rtx arg1_rtx, arg2_rtx;
3809 rtx result, insn = NULL_RTX;
3810 tree fndecl, fn;
3811
3812 tree arg1 = TREE_VALUE (arglist);
3813 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3814 int arg1_align
3815 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3816 int arg2_align
3817 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3818
3819 /* If we don't have POINTER_TYPE, call the function. */
3820 if (arg1_align == 0 || arg2_align == 0)
3821 return 0;
3822
3823 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3824 arg1 = builtin_save_expr (arg1);
3825 arg2 = builtin_save_expr (arg2);
3826
3827 arg1_rtx = get_memory_rtx (arg1, NULL);
3828 arg2_rtx = get_memory_rtx (arg2, NULL);
3829
3830 #ifdef HAVE_cmpstrsi
3831 /* Try to call cmpstrsi. */
3832 if (HAVE_cmpstrsi)
3833 {
3834 enum machine_mode insn_mode
3835 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3836
3837 /* Make a place to write the result of the instruction. */
3838 result = target;
3839 if (! (result != 0
3840 && REG_P (result) && GET_MODE (result) == insn_mode
3841 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3842 result = gen_reg_rtx (insn_mode);
3843
3844 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3845 GEN_INT (MIN (arg1_align, arg2_align)));
3846 }
3847 #endif
3848 #ifdef HAVE_cmpstrnsi
3849 /* Try to determine at least one length and call cmpstrnsi. */
3850 if (!insn && HAVE_cmpstrnsi)
3851 {
3852 tree len;
3853 rtx arg3_rtx;
3854
3855 enum machine_mode insn_mode
3856 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3857 tree len1 = c_strlen (arg1, 1);
3858 tree len2 = c_strlen (arg2, 1);
3859
3860 if (len1)
3861 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3862 if (len2)
3863 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3864
3865 /* If we don't have a constant length for the first, use the length
3866 of the second, if we know it. We don't require a constant for
3867 this case; some cost analysis could be done if both are available
3868 but neither is constant. For now, assume they're equally cheap,
3869 unless one has side effects. If both strings have constant lengths,
3870 use the smaller. */
3871
3872 if (!len1)
3873 len = len2;
3874 else if (!len2)
3875 len = len1;
3876 else if (TREE_SIDE_EFFECTS (len1))
3877 len = len2;
3878 else if (TREE_SIDE_EFFECTS (len2))
3879 len = len1;
3880 else if (TREE_CODE (len1) != INTEGER_CST)
3881 len = len2;
3882 else if (TREE_CODE (len2) != INTEGER_CST)
3883 len = len1;
3884 else if (tree_int_cst_lt (len1, len2))
3885 len = len1;
3886 else
3887 len = len2;
3888
3889 /* If both arguments have side effects, we cannot optimize. */
3890 if (!len || TREE_SIDE_EFFECTS (len))
3891 goto do_libcall;
3892
3893 arg3_rtx = expand_normal (len);
3894
3895 /* Make a place to write the result of the instruction. */
3896 result = target;
3897 if (! (result != 0
3898 && REG_P (result) && GET_MODE (result) == insn_mode
3899 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3900 result = gen_reg_rtx (insn_mode);
3901
3902 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3903 GEN_INT (MIN (arg1_align, arg2_align)));
3904 }
3905 #endif
3906
3907 if (insn)
3908 {
3909 emit_insn (insn);
3910
3911 /* Return the value in the proper mode for this function. */
3912 mode = TYPE_MODE (TREE_TYPE (exp));
3913 if (GET_MODE (result) == mode)
3914 return result;
3915 if (target == 0)
3916 return convert_to_mode (mode, result, 0);
3917 convert_move (target, result, 0);
3918 return target;
3919 }
3920
3921 /* Expand the library call ourselves using a stabilized argument
3922 list to avoid re-evaluating the function's arguments twice. */
3923 #ifdef HAVE_cmpstrnsi
3924 do_libcall:
3925 #endif
3926 arglist = build_tree_list (NULL_TREE, arg2);
3927 arglist = tree_cons (NULL_TREE, arg1, arglist);
3928 fndecl = get_callee_fndecl (exp);
3929 fn = build_function_call_expr (fndecl, arglist);
3930 if (TREE_CODE (fn) == CALL_EXPR)
3931 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3932 return expand_call (fn, target, target == const0_rtx);
3933 }
3934 #endif
3935 return 0;
3936 }
3937
3938 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3939 if we failed the caller should emit a normal call, otherwise try to get
3940 the result in TARGET, if convenient. */
3941
3942 static rtx
3943 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3944 {
3945 tree arglist = TREE_OPERAND (exp, 1);
3946
3947 if (!validate_arglist (arglist,
3948 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3949 return 0;
3950 else
3951 {
3952 tree result = fold_builtin_strncmp (arglist);
3953 if (result)
3954 return expand_expr (result, target, mode, EXPAND_NORMAL);
3955 }
3956
3957 /* If c_strlen can determine an expression for one of the string
3958 lengths, and it doesn't have side effects, then emit cmpstrnsi
3959 using length MIN(strlen(string)+1, arg3). */
3960 #ifdef HAVE_cmpstrnsi
3961 if (HAVE_cmpstrnsi)
3962 {
3963 tree arg1 = TREE_VALUE (arglist);
3964 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3965 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3966 tree len, len1, len2;
3967 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3968 rtx result, insn;
3969 tree fndecl, fn;
3970
3971 int arg1_align
3972 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3973 int arg2_align
3974 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3975 enum machine_mode insn_mode
3976 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3977
3978 len1 = c_strlen (arg1, 1);
3979 len2 = c_strlen (arg2, 1);
3980
3981 if (len1)
3982 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3983 if (len2)
3984 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3985
3986 /* If we don't have a constant length for the first, use the length
3987 of the second, if we know it. We don't require a constant for
3988 this case; some cost analysis could be done if both are available
3989 but neither is constant. For now, assume they're equally cheap,
3990 unless one has side effects. If both strings have constant lengths,
3991 use the smaller. */
3992
3993 if (!len1)
3994 len = len2;
3995 else if (!len2)
3996 len = len1;
3997 else if (TREE_SIDE_EFFECTS (len1))
3998 len = len2;
3999 else if (TREE_SIDE_EFFECTS (len2))
4000 len = len1;
4001 else if (TREE_CODE (len1) != INTEGER_CST)
4002 len = len2;
4003 else if (TREE_CODE (len2) != INTEGER_CST)
4004 len = len1;
4005 else if (tree_int_cst_lt (len1, len2))
4006 len = len1;
4007 else
4008 len = len2;
4009
4010 /* If both arguments have side effects, we cannot optimize. */
4011 if (!len || TREE_SIDE_EFFECTS (len))
4012 return 0;
4013
4014 /* The actual new length parameter is MIN(len,arg3). */
4015 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4016 fold_convert (TREE_TYPE (len), arg3));
4017
4018 /* If we don't have POINTER_TYPE, call the function. */
4019 if (arg1_align == 0 || arg2_align == 0)
4020 return 0;
4021
4022 /* Make a place to write the result of the instruction. */
4023 result = target;
4024 if (! (result != 0
4025 && REG_P (result) && GET_MODE (result) == insn_mode
4026 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4027 result = gen_reg_rtx (insn_mode);
4028
4029 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4030 arg1 = builtin_save_expr (arg1);
4031 arg2 = builtin_save_expr (arg2);
4032 len = builtin_save_expr (len);
4033
4034 arg1_rtx = get_memory_rtx (arg1, len);
4035 arg2_rtx = get_memory_rtx (arg2, len);
4036 arg3_rtx = expand_normal (len);
4037 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4038 GEN_INT (MIN (arg1_align, arg2_align)));
4039 if (insn)
4040 {
4041 emit_insn (insn);
4042
4043 /* Return the value in the proper mode for this function. */
4044 mode = TYPE_MODE (TREE_TYPE (exp));
4045 if (GET_MODE (result) == mode)
4046 return result;
4047 if (target == 0)
4048 return convert_to_mode (mode, result, 0);
4049 convert_move (target, result, 0);
4050 return target;
4051 }
4052
4053 /* Expand the library call ourselves using a stabilized argument
4054 list to avoid re-evaluating the function's arguments twice. */
4055 arglist = build_tree_list (NULL_TREE, len);
4056 arglist = tree_cons (NULL_TREE, arg2, arglist);
4057 arglist = tree_cons (NULL_TREE, arg1, arglist);
4058 fndecl = get_callee_fndecl (exp);
4059 fn = build_function_call_expr (fndecl, arglist);
4060 if (TREE_CODE (fn) == CALL_EXPR)
4061 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4062 return expand_call (fn, target, target == const0_rtx);
4063 }
4064 #endif
4065 return 0;
4066 }
4067
4068 /* Expand expression EXP, which is a call to the strcat builtin.
4069 Return 0 if we failed the caller should emit a normal call,
4070 otherwise try to get the result in TARGET, if convenient. */
4071
4072 static rtx
4073 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
4074 {
4075 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4076 return 0;
4077 else
4078 {
4079 tree dst = TREE_VALUE (arglist),
4080 src = TREE_VALUE (TREE_CHAIN (arglist));
4081 const char *p = c_getstr (src);
4082
4083 /* If the string length is zero, return the dst parameter. */
4084 if (p && *p == '\0')
4085 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4086
4087 if (!optimize_size)
4088 {
4089 /* See if we can store by pieces into (dst + strlen(dst)). */
4090 tree newsrc, newdst,
4091 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4092 rtx insns;
4093
4094 /* Stabilize the argument list. */
4095 newsrc = builtin_save_expr (src);
4096 if (newsrc != src)
4097 arglist = build_tree_list (NULL_TREE, newsrc);
4098 else
4099 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4100
4101 dst = builtin_save_expr (dst);
4102
4103 start_sequence ();
4104
4105 /* Create strlen (dst). */
4106 newdst =
4107 build_function_call_expr (strlen_fn,
4108 build_tree_list (NULL_TREE, dst));
4109 /* Create (dst + (cast) strlen (dst)). */
4110 newdst = fold_convert (TREE_TYPE (dst), newdst);
4111 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4112
4113 newdst = builtin_save_expr (newdst);
4114 arglist = tree_cons (NULL_TREE, newdst, arglist);
4115
4116 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4117 {
4118 end_sequence (); /* Stop sequence. */
4119 return 0;
4120 }
4121
4122 /* Output the entire sequence. */
4123 insns = get_insns ();
4124 end_sequence ();
4125 emit_insn (insns);
4126
4127 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4128 }
4129
4130 return 0;
4131 }
4132 }
4133
4134 /* Expand expression EXP, which is a call to the strncat builtin.
4135 Return 0 if we failed the caller should emit a normal call,
4136 otherwise try to get the result in TARGET, if convenient. */
4137
4138 static rtx
4139 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4140 {
4141 if (validate_arglist (arglist,
4142 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4143 {
4144 tree result = fold_builtin_strncat (arglist);
4145 if (result)
4146 return expand_expr (result, target, mode, EXPAND_NORMAL);
4147 }
4148 return 0;
4149 }
4150
4151 /* Expand expression EXP, which is a call to the strspn builtin.
4152 Return 0 if we failed the caller should emit a normal call,
4153 otherwise try to get the result in TARGET, if convenient. */
4154
4155 static rtx
4156 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4157 {
4158 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4159 {
4160 tree result = fold_builtin_strspn (arglist);
4161 if (result)
4162 return expand_expr (result, target, mode, EXPAND_NORMAL);
4163 }
4164 return 0;
4165 }
4166
4167 /* Expand expression EXP, which is a call to the strcspn builtin.
4168 Return 0 if we failed the caller should emit a normal call,
4169 otherwise try to get the result in TARGET, if convenient. */
4170
4171 static rtx
4172 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4173 {
4174 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4175 {
4176 tree result = fold_builtin_strcspn (arglist);
4177 if (result)
4178 return expand_expr (result, target, mode, EXPAND_NORMAL);
4179 }
4180 return 0;
4181 }
4182
4183 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4184 if that's convenient. */
4185
4186 rtx
4187 expand_builtin_saveregs (void)
4188 {
4189 rtx val, seq;
4190
4191 /* Don't do __builtin_saveregs more than once in a function.
4192 Save the result of the first call and reuse it. */
4193 if (saveregs_value != 0)
4194 return saveregs_value;
4195
4196 /* When this function is called, it means that registers must be
4197 saved on entry to this function. So we migrate the call to the
4198 first insn of this function. */
4199
4200 start_sequence ();
4201
4202 /* Do whatever the machine needs done in this case. */
4203 val = targetm.calls.expand_builtin_saveregs ();
4204
4205 seq = get_insns ();
4206 end_sequence ();
4207
4208 saveregs_value = val;
4209
4210 /* Put the insns after the NOTE that starts the function. If this
4211 is inside a start_sequence, make the outer-level insn chain current, so
4212 the code is placed at the start of the function. */
4213 push_topmost_sequence ();
4214 emit_insn_after (seq, entry_of_function ());
4215 pop_topmost_sequence ();
4216
4217 return val;
4218 }
4219
4220 /* __builtin_args_info (N) returns word N of the arg space info
4221 for the current function. The number and meanings of words
4222 is controlled by the definition of CUMULATIVE_ARGS. */
4223
4224 static rtx
4225 expand_builtin_args_info (tree arglist)
4226 {
4227 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4228 int *word_ptr = (int *) &current_function_args_info;
4229
4230 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4231
4232 if (arglist != 0)
4233 {
4234 if (!host_integerp (TREE_VALUE (arglist), 0))
4235 error ("argument of %<__builtin_args_info%> must be constant");
4236 else
4237 {
4238 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4239
4240 if (wordnum < 0 || wordnum >= nwords)
4241 error ("argument of %<__builtin_args_info%> out of range");
4242 else
4243 return GEN_INT (word_ptr[wordnum]);
4244 }
4245 }
4246 else
4247 error ("missing argument in %<__builtin_args_info%>");
4248
4249 return const0_rtx;
4250 }
4251
4252 /* Expand a call to __builtin_next_arg. */
4253
4254 static rtx
4255 expand_builtin_next_arg (void)
4256 {
4257 /* Checking arguments is already done in fold_builtin_next_arg
4258 that must be called before this function. */
4259 return expand_binop (Pmode, add_optab,
4260 current_function_internal_arg_pointer,
4261 current_function_arg_offset_rtx,
4262 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4263 }
4264
4265 /* Make it easier for the backends by protecting the valist argument
4266 from multiple evaluations. */
4267
4268 static tree
4269 stabilize_va_list (tree valist, int needs_lvalue)
4270 {
4271 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4272 {
4273 if (TREE_SIDE_EFFECTS (valist))
4274 valist = save_expr (valist);
4275
4276 /* For this case, the backends will be expecting a pointer to
4277 TREE_TYPE (va_list_type_node), but it's possible we've
4278 actually been given an array (an actual va_list_type_node).
4279 So fix it. */
4280 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4281 {
4282 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4283 valist = build_fold_addr_expr_with_type (valist, p1);
4284 }
4285 }
4286 else
4287 {
4288 tree pt;
4289
4290 if (! needs_lvalue)
4291 {
4292 if (! TREE_SIDE_EFFECTS (valist))
4293 return valist;
4294
4295 pt = build_pointer_type (va_list_type_node);
4296 valist = fold_build1 (ADDR_EXPR, pt, valist);
4297 TREE_SIDE_EFFECTS (valist) = 1;
4298 }
4299
4300 if (TREE_SIDE_EFFECTS (valist))
4301 valist = save_expr (valist);
4302 valist = build_fold_indirect_ref (valist);
4303 }
4304
4305 return valist;
4306 }
4307
4308 /* The "standard" definition of va_list is void*. */
4309
4310 tree
4311 std_build_builtin_va_list (void)
4312 {
4313 return ptr_type_node;
4314 }
4315
4316 /* The "standard" implementation of va_start: just assign `nextarg' to
4317 the variable. */
4318
4319 void
4320 std_expand_builtin_va_start (tree valist, rtx nextarg)
4321 {
4322 tree t;
4323
4324 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
4325 make_tree (ptr_type_node, nextarg));
4326 TREE_SIDE_EFFECTS (t) = 1;
4327
4328 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4329 }
4330
4331 /* Expand ARGLIST, from a call to __builtin_va_start. */
4332
4333 static rtx
4334 expand_builtin_va_start (tree arglist)
4335 {
4336 rtx nextarg;
4337 tree chain, valist;
4338
4339 chain = TREE_CHAIN (arglist);
4340
4341 if (!chain)
4342 {
4343 error ("too few arguments to function %<va_start%>");
4344 return const0_rtx;
4345 }
4346
4347 if (fold_builtin_next_arg (chain))
4348 return const0_rtx;
4349
4350 nextarg = expand_builtin_next_arg ();
4351 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4352
4353 #ifdef EXPAND_BUILTIN_VA_START
4354 EXPAND_BUILTIN_VA_START (valist, nextarg);
4355 #else
4356 std_expand_builtin_va_start (valist, nextarg);
4357 #endif
4358
4359 return const0_rtx;
4360 }
4361
4362 /* The "standard" implementation of va_arg: read the value from the
4363 current (padded) address and increment by the (padded) size. */
4364
4365 tree
4366 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4367 {
4368 tree addr, t, type_size, rounded_size, valist_tmp;
4369 unsigned HOST_WIDE_INT align, boundary;
4370 bool indirect;
4371
4372 #ifdef ARGS_GROW_DOWNWARD
4373 /* All of the alignment and movement below is for args-grow-up machines.
4374 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4375 implement their own specialized gimplify_va_arg_expr routines. */
4376 gcc_unreachable ();
4377 #endif
4378
4379 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4380 if (indirect)
4381 type = build_pointer_type (type);
4382
4383 align = PARM_BOUNDARY / BITS_PER_UNIT;
4384 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4385
4386 /* Hoist the valist value into a temporary for the moment. */
4387 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4388
4389 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4390 requires greater alignment, we must perform dynamic alignment. */
4391 if (boundary > align
4392 && !integer_zerop (TYPE_SIZE (type)))
4393 {
4394 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4395 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4396 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4397 gimplify_and_add (t, pre_p);
4398
4399 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4400 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4401 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4402 gimplify_and_add (t, pre_p);
4403 }
4404 else
4405 boundary = align;
4406
4407 /* If the actual alignment is less than the alignment of the type,
4408 adjust the type accordingly so that we don't assume strict alignment
4409 when deferencing the pointer. */
4410 boundary *= BITS_PER_UNIT;
4411 if (boundary < TYPE_ALIGN (type))
4412 {
4413 type = build_variant_type_copy (type);
4414 TYPE_ALIGN (type) = boundary;
4415 }
4416
4417 /* Compute the rounded size of the type. */
4418 type_size = size_in_bytes (type);
4419 rounded_size = round_up (type_size, align);
4420
4421 /* Reduce rounded_size so it's sharable with the postqueue. */
4422 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4423
4424 /* Get AP. */
4425 addr = valist_tmp;
4426 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4427 {
4428 /* Small args are padded downward. */
4429 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4430 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4431 size_binop (MINUS_EXPR, rounded_size, type_size));
4432 t = fold_convert (TREE_TYPE (addr), t);
4433 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4434 }
4435
4436 /* Compute new value for AP. */
4437 t = fold_convert (TREE_TYPE (valist), rounded_size);
4438 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4439 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist, t);
4440 gimplify_and_add (t, pre_p);
4441
4442 addr = fold_convert (build_pointer_type (type), addr);
4443
4444 if (indirect)
4445 addr = build_va_arg_indirect_ref (addr);
4446
4447 return build_va_arg_indirect_ref (addr);
4448 }
4449
4450 /* Build an indirect-ref expression over the given TREE, which represents a
4451 piece of a va_arg() expansion. */
4452 tree
4453 build_va_arg_indirect_ref (tree addr)
4454 {
4455 addr = build_fold_indirect_ref (addr);
4456
4457 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4458 mf_mark (addr);
4459
4460 return addr;
4461 }
4462
4463 /* Return a dummy expression of type TYPE in order to keep going after an
4464 error. */
4465
4466 static tree
4467 dummy_object (tree type)
4468 {
4469 tree t = build_int_cst (build_pointer_type (type), 0);
4470 return build1 (INDIRECT_REF, type, t);
4471 }
4472
4473 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4474 builtin function, but a very special sort of operator. */
4475
4476 enum gimplify_status
4477 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4478 {
4479 tree promoted_type, want_va_type, have_va_type;
4480 tree valist = TREE_OPERAND (*expr_p, 0);
4481 tree type = TREE_TYPE (*expr_p);
4482 tree t;
4483
4484 /* Verify that valist is of the proper type. */
4485 want_va_type = va_list_type_node;
4486 have_va_type = TREE_TYPE (valist);
4487
4488 if (have_va_type == error_mark_node)
4489 return GS_ERROR;
4490
4491 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4492 {
4493 /* If va_list is an array type, the argument may have decayed
4494 to a pointer type, e.g. by being passed to another function.
4495 In that case, unwrap both types so that we can compare the
4496 underlying records. */
4497 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4498 || POINTER_TYPE_P (have_va_type))
4499 {
4500 want_va_type = TREE_TYPE (want_va_type);
4501 have_va_type = TREE_TYPE (have_va_type);
4502 }
4503 }
4504
4505 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4506 {
4507 error ("first argument to %<va_arg%> not of type %<va_list%>");
4508 return GS_ERROR;
4509 }
4510
4511 /* Generate a diagnostic for requesting data of a type that cannot
4512 be passed through `...' due to type promotion at the call site. */
4513 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4514 != type)
4515 {
4516 static bool gave_help;
4517
4518 /* Unfortunately, this is merely undefined, rather than a constraint
4519 violation, so we cannot make this an error. If this call is never
4520 executed, the program is still strictly conforming. */
4521 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4522 type, promoted_type);
4523 if (! gave_help)
4524 {
4525 gave_help = true;
4526 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4527 promoted_type, type);
4528 }
4529
4530 /* We can, however, treat "undefined" any way we please.
4531 Call abort to encourage the user to fix the program. */
4532 inform ("if this code is reached, the program will abort");
4533 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4534 NULL);
4535 append_to_statement_list (t, pre_p);
4536
4537 /* This is dead code, but go ahead and finish so that the
4538 mode of the result comes out right. */
4539 *expr_p = dummy_object (type);
4540 return GS_ALL_DONE;
4541 }
4542 else
4543 {
4544 /* Make it easier for the backends by protecting the valist argument
4545 from multiple evaluations. */
4546 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4547 {
4548 /* For this case, the backends will be expecting a pointer to
4549 TREE_TYPE (va_list_type_node), but it's possible we've
4550 actually been given an array (an actual va_list_type_node).
4551 So fix it. */
4552 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4553 {
4554 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4555 valist = build_fold_addr_expr_with_type (valist, p1);
4556 }
4557 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4558 }
4559 else
4560 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4561
4562 if (!targetm.gimplify_va_arg_expr)
4563 /* FIXME:Once most targets are converted we should merely
4564 assert this is non-null. */
4565 return GS_ALL_DONE;
4566
4567 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4568 return GS_OK;
4569 }
4570 }
4571
4572 /* Expand ARGLIST, from a call to __builtin_va_end. */
4573
4574 static rtx
4575 expand_builtin_va_end (tree arglist)
4576 {
4577 tree valist = TREE_VALUE (arglist);
4578
4579 /* Evaluate for side effects, if needed. I hate macros that don't
4580 do that. */
4581 if (TREE_SIDE_EFFECTS (valist))
4582 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4583
4584 return const0_rtx;
4585 }
4586
4587 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4588 builtin rather than just as an assignment in stdarg.h because of the
4589 nastiness of array-type va_list types. */
4590
4591 static rtx
4592 expand_builtin_va_copy (tree arglist)
4593 {
4594 tree dst, src, t;
4595
4596 dst = TREE_VALUE (arglist);
4597 src = TREE_VALUE (TREE_CHAIN (arglist));
4598
4599 dst = stabilize_va_list (dst, 1);
4600 src = stabilize_va_list (src, 0);
4601
4602 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4603 {
4604 t = build2 (GIMPLE_MODIFY_STMT, va_list_type_node, dst, src);
4605 TREE_SIDE_EFFECTS (t) = 1;
4606 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4607 }
4608 else
4609 {
4610 rtx dstb, srcb, size;
4611
4612 /* Evaluate to pointers. */
4613 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4614 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4615 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4616 VOIDmode, EXPAND_NORMAL);
4617
4618 dstb = convert_memory_address (Pmode, dstb);
4619 srcb = convert_memory_address (Pmode, srcb);
4620
4621 /* "Dereference" to BLKmode memories. */
4622 dstb = gen_rtx_MEM (BLKmode, dstb);
4623 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4624 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4625 srcb = gen_rtx_MEM (BLKmode, srcb);
4626 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4627 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4628
4629 /* Copy. */
4630 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4631 }
4632
4633 return const0_rtx;
4634 }
4635
4636 /* Expand a call to one of the builtin functions __builtin_frame_address or
4637 __builtin_return_address. */
4638
4639 static rtx
4640 expand_builtin_frame_address (tree fndecl, tree arglist)
4641 {
4642 /* The argument must be a nonnegative integer constant.
4643 It counts the number of frames to scan up the stack.
4644 The value is the return address saved in that frame. */
4645 if (arglist == 0)
4646 /* Warning about missing arg was already issued. */
4647 return const0_rtx;
4648 else if (! host_integerp (TREE_VALUE (arglist), 1))
4649 {
4650 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4651 error ("invalid argument to %<__builtin_frame_address%>");
4652 else
4653 error ("invalid argument to %<__builtin_return_address%>");
4654 return const0_rtx;
4655 }
4656 else
4657 {
4658 rtx tem
4659 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4660 tree_low_cst (TREE_VALUE (arglist), 1));
4661
4662 /* Some ports cannot access arbitrary stack frames. */
4663 if (tem == NULL)
4664 {
4665 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4666 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4667 else
4668 warning (0, "unsupported argument to %<__builtin_return_address%>");
4669 return const0_rtx;
4670 }
4671
4672 /* For __builtin_frame_address, return what we've got. */
4673 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4674 return tem;
4675
4676 if (!REG_P (tem)
4677 && ! CONSTANT_P (tem))
4678 tem = copy_to_mode_reg (Pmode, tem);
4679 return tem;
4680 }
4681 }
4682
4683 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4684 we failed and the caller should emit a normal call, otherwise try to get
4685 the result in TARGET, if convenient. */
4686
4687 static rtx
4688 expand_builtin_alloca (tree arglist, rtx target)
4689 {
4690 rtx op0;
4691 rtx result;
4692
4693 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4694 should always expand to function calls. These can be intercepted
4695 in libmudflap. */
4696 if (flag_mudflap)
4697 return 0;
4698
4699 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4700 return 0;
4701
4702 /* Compute the argument. */
4703 op0 = expand_normal (TREE_VALUE (arglist));
4704
4705 /* Allocate the desired space. */
4706 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4707 result = convert_memory_address (ptr_mode, result);
4708
4709 return result;
4710 }
4711
4712 /* Expand a call to a bswap builtin. The arguments are in ARGLIST. MODE
4713 is the mode to expand with. */
4714
4715 static rtx
4716 expand_builtin_bswap (tree arglist, rtx target, rtx subtarget)
4717 {
4718 enum machine_mode mode;
4719 tree arg;
4720 rtx op0;
4721
4722 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4723 return 0;
4724
4725 arg = TREE_VALUE (arglist);
4726 mode = TYPE_MODE (TREE_TYPE (arg));
4727 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4728
4729 target = expand_unop (mode, bswap_optab, op0, target, 1);
4730
4731 gcc_assert (target);
4732
4733 return convert_to_mode (mode, target, 0);
4734 }
4735
4736 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4737 Return 0 if a normal call should be emitted rather than expanding the
4738 function in-line. If convenient, the result should be placed in TARGET.
4739 SUBTARGET may be used as the target for computing one of EXP's operands. */
4740
4741 static rtx
4742 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4743 rtx subtarget, optab op_optab)
4744 {
4745 rtx op0;
4746 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4747 return 0;
4748
4749 /* Compute the argument. */
4750 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4751 /* Compute op, into TARGET if possible.
4752 Set TARGET to wherever the result comes back. */
4753 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4754 op_optab, op0, target, 1);
4755 gcc_assert (target);
4756
4757 return convert_to_mode (target_mode, target, 0);
4758 }
4759
4760 /* If the string passed to fputs is a constant and is one character
4761 long, we attempt to transform this call into __builtin_fputc(). */
4762
4763 static rtx
4764 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4765 {
4766 /* Verify the arguments in the original call. */
4767 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4768 {
4769 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4770 unlocked, NULL_TREE);
4771 if (result)
4772 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4773 }
4774 return 0;
4775 }
4776
4777 /* Expand a call to __builtin_expect. We just return our argument
4778 as the builtin_expect semantic should've been already executed by
4779 tree branch prediction pass. */
4780
4781 static rtx
4782 expand_builtin_expect (tree arglist, rtx target)
4783 {
4784 tree exp, c;
4785
4786 if (arglist == NULL_TREE
4787 || TREE_CHAIN (arglist) == NULL_TREE)
4788 return const0_rtx;
4789 exp = TREE_VALUE (arglist);
4790 c = TREE_VALUE (TREE_CHAIN (arglist));
4791
4792 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4793 /* When guessing was done, the hints should be already stripped away. */
4794 gcc_assert (!flag_guess_branch_prob);
4795 return target;
4796 }
4797
4798 void
4799 expand_builtin_trap (void)
4800 {
4801 #ifdef HAVE_trap
4802 if (HAVE_trap)
4803 emit_insn (gen_trap ());
4804 else
4805 #endif
4806 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4807 emit_barrier ();
4808 }
4809
4810 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4811 Return 0 if a normal call should be emitted rather than expanding
4812 the function inline. If convenient, the result should be placed
4813 in TARGET. SUBTARGET may be used as the target for computing
4814 the operand. */
4815
4816 static rtx
4817 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4818 {
4819 enum machine_mode mode;
4820 tree arg;
4821 rtx op0;
4822
4823 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4824 return 0;
4825
4826 arg = TREE_VALUE (arglist);
4827 mode = TYPE_MODE (TREE_TYPE (arg));
4828 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4829 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4830 }
4831
4832 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4833 Return NULL is a normal call should be emitted rather than expanding the
4834 function inline. If convenient, the result should be placed in TARGET.
4835 SUBTARGET may be used as the target for computing the operand. */
4836
4837 static rtx
4838 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4839 {
4840 rtx op0, op1;
4841 tree arg;
4842
4843 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4844 return 0;
4845
4846 arg = TREE_VALUE (arglist);
4847 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4848
4849 arg = TREE_VALUE (TREE_CHAIN (arglist));
4850 op1 = expand_normal (arg);
4851
4852 return expand_copysign (op0, op1, target);
4853 }
4854
4855 /* Create a new constant string literal and return a char* pointer to it.
4856 The STRING_CST value is the LEN characters at STR. */
4857 tree
4858 build_string_literal (int len, const char *str)
4859 {
4860 tree t, elem, index, type;
4861
4862 t = build_string (len, str);
4863 elem = build_type_variant (char_type_node, 1, 0);
4864 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4865 type = build_array_type (elem, index);
4866 TREE_TYPE (t) = type;
4867 TREE_CONSTANT (t) = 1;
4868 TREE_INVARIANT (t) = 1;
4869 TREE_READONLY (t) = 1;
4870 TREE_STATIC (t) = 1;
4871
4872 type = build_pointer_type (type);
4873 t = build1 (ADDR_EXPR, type, t);
4874
4875 type = build_pointer_type (elem);
4876 t = build1 (NOP_EXPR, type, t);
4877 return t;
4878 }
4879
4880 /* Expand EXP, a call to printf or printf_unlocked.
4881 Return 0 if a normal call should be emitted rather than transforming
4882 the function inline. If convenient, the result should be placed in
4883 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4884 call. */
4885 static rtx
4886 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4887 bool unlocked)
4888 {
4889 tree arglist = TREE_OPERAND (exp, 1);
4890 /* If we're using an unlocked function, assume the other unlocked
4891 functions exist explicitly. */
4892 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4893 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4894 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4895 : implicit_built_in_decls[BUILT_IN_PUTS];
4896 const char *fmt_str;
4897 tree fn, fmt, arg;
4898
4899 /* If the return value is used, don't do the transformation. */
4900 if (target != const0_rtx)
4901 return 0;
4902
4903 /* Verify the required arguments in the original call. */
4904 if (! arglist)
4905 return 0;
4906 fmt = TREE_VALUE (arglist);
4907 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4908 return 0;
4909 arglist = TREE_CHAIN (arglist);
4910
4911 /* Check whether the format is a literal string constant. */
4912 fmt_str = c_getstr (fmt);
4913 if (fmt_str == NULL)
4914 return 0;
4915
4916 if (!init_target_chars())
4917 return 0;
4918
4919 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4920 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4921 {
4922 if (! arglist
4923 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4924 || TREE_CHAIN (arglist))
4925 return 0;
4926 fn = fn_puts;
4927 }
4928 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4929 else if (strcmp (fmt_str, target_percent_c) == 0)
4930 {
4931 if (! arglist
4932 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4933 || TREE_CHAIN (arglist))
4934 return 0;
4935 fn = fn_putchar;
4936 }
4937 else
4938 {
4939 /* We can't handle anything else with % args or %% ... yet. */
4940 if (strchr (fmt_str, target_percent))
4941 return 0;
4942
4943 if (arglist)
4944 return 0;
4945
4946 /* If the format specifier was "", printf does nothing. */
4947 if (fmt_str[0] == '\0')
4948 return const0_rtx;
4949 /* If the format specifier has length of 1, call putchar. */
4950 if (fmt_str[1] == '\0')
4951 {
4952 /* Given printf("c"), (where c is any one character,)
4953 convert "c"[0] to an int and pass that to the replacement
4954 function. */
4955 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4956 arglist = build_tree_list (NULL_TREE, arg);
4957 fn = fn_putchar;
4958 }
4959 else
4960 {
4961 /* If the format specifier was "string\n", call puts("string"). */
4962 size_t len = strlen (fmt_str);
4963 if ((unsigned char)fmt_str[len - 1] == target_newline)
4964 {
4965 /* Create a NUL-terminated string that's one char shorter
4966 than the original, stripping off the trailing '\n'. */
4967 char *newstr = alloca (len);
4968 memcpy (newstr, fmt_str, len - 1);
4969 newstr[len - 1] = 0;
4970
4971 arg = build_string_literal (len, newstr);
4972 arglist = build_tree_list (NULL_TREE, arg);
4973 fn = fn_puts;
4974 }
4975 else
4976 /* We'd like to arrange to call fputs(string,stdout) here,
4977 but we need stdout and don't have a way to get it yet. */
4978 return 0;
4979 }
4980 }
4981
4982 if (!fn)
4983 return 0;
4984 fn = build_function_call_expr (fn, arglist);
4985 if (TREE_CODE (fn) == CALL_EXPR)
4986 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4987 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4988 }
4989
4990 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4991 Return 0 if a normal call should be emitted rather than transforming
4992 the function inline. If convenient, the result should be placed in
4993 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4994 call. */
4995 static rtx
4996 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4997 bool unlocked)
4998 {
4999 tree arglist = TREE_OPERAND (exp, 1);
5000 /* If we're using an unlocked function, assume the other unlocked
5001 functions exist explicitly. */
5002 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5003 : implicit_built_in_decls[BUILT_IN_FPUTC];
5004 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5005 : implicit_built_in_decls[BUILT_IN_FPUTS];
5006 const char *fmt_str;
5007 tree fn, fmt, fp, arg;
5008
5009 /* If the return value is used, don't do the transformation. */
5010 if (target != const0_rtx)
5011 return 0;
5012
5013 /* Verify the required arguments in the original call. */
5014 if (! arglist)
5015 return 0;
5016 fp = TREE_VALUE (arglist);
5017 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5018 return 0;
5019 arglist = TREE_CHAIN (arglist);
5020 if (! arglist)
5021 return 0;
5022 fmt = TREE_VALUE (arglist);
5023 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5024 return 0;
5025 arglist = TREE_CHAIN (arglist);
5026
5027 /* Check whether the format is a literal string constant. */
5028 fmt_str = c_getstr (fmt);
5029 if (fmt_str == NULL)
5030 return 0;
5031
5032 if (!init_target_chars())
5033 return 0;
5034
5035 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5036 if (strcmp (fmt_str, target_percent_s) == 0)
5037 {
5038 if (! arglist
5039 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5040 || TREE_CHAIN (arglist))
5041 return 0;
5042 arg = TREE_VALUE (arglist);
5043 arglist = build_tree_list (NULL_TREE, fp);
5044 arglist = tree_cons (NULL_TREE, arg, arglist);
5045 fn = fn_fputs;
5046 }
5047 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5048 else if (strcmp (fmt_str, target_percent_c) == 0)
5049 {
5050 if (! arglist
5051 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5052 || TREE_CHAIN (arglist))
5053 return 0;
5054 arg = TREE_VALUE (arglist);
5055 arglist = build_tree_list (NULL_TREE, fp);
5056 arglist = tree_cons (NULL_TREE, arg, arglist);
5057 fn = fn_fputc;
5058 }
5059 else
5060 {
5061 /* We can't handle anything else with % args or %% ... yet. */
5062 if (strchr (fmt_str, target_percent))
5063 return 0;
5064
5065 if (arglist)
5066 return 0;
5067
5068 /* If the format specifier was "", fprintf does nothing. */
5069 if (fmt_str[0] == '\0')
5070 {
5071 /* Evaluate and ignore FILE* argument for side-effects. */
5072 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5073 return const0_rtx;
5074 }
5075
5076 /* When "string" doesn't contain %, replace all cases of
5077 fprintf(stream,string) with fputs(string,stream). The fputs
5078 builtin will take care of special cases like length == 1. */
5079 arglist = build_tree_list (NULL_TREE, fp);
5080 arglist = tree_cons (NULL_TREE, fmt, arglist);
5081 fn = fn_fputs;
5082 }
5083
5084 if (!fn)
5085 return 0;
5086 fn = build_function_call_expr (fn, arglist);
5087 if (TREE_CODE (fn) == CALL_EXPR)
5088 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5089 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5090 }
5091
5092 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5093 a normal call should be emitted rather than expanding the function
5094 inline. If convenient, the result should be placed in TARGET with
5095 mode MODE. */
5096
5097 static rtx
5098 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5099 {
5100 tree orig_arglist, dest, fmt;
5101 const char *fmt_str;
5102
5103 orig_arglist = arglist;
5104
5105 /* Verify the required arguments in the original call. */
5106 if (! arglist)
5107 return 0;
5108 dest = TREE_VALUE (arglist);
5109 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5110 return 0;
5111 arglist = TREE_CHAIN (arglist);
5112 if (! arglist)
5113 return 0;
5114 fmt = TREE_VALUE (arglist);
5115 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5116 return 0;
5117 arglist = TREE_CHAIN (arglist);
5118
5119 /* Check whether the format is a literal string constant. */
5120 fmt_str = c_getstr (fmt);
5121 if (fmt_str == NULL)
5122 return 0;
5123
5124 if (!init_target_chars())
5125 return 0;
5126
5127 /* If the format doesn't contain % args or %%, use strcpy. */
5128 if (strchr (fmt_str, target_percent) == 0)
5129 {
5130 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5131 tree exp;
5132
5133 if (arglist || ! fn)
5134 return 0;
5135 expand_expr (build_function_call_expr (fn, orig_arglist),
5136 const0_rtx, VOIDmode, EXPAND_NORMAL);
5137 if (target == const0_rtx)
5138 return const0_rtx;
5139 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5140 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5141 }
5142 /* If the format is "%s", use strcpy if the result isn't used. */
5143 else if (strcmp (fmt_str, target_percent_s) == 0)
5144 {
5145 tree fn, arg, len;
5146 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5147
5148 if (! fn)
5149 return 0;
5150
5151 if (! arglist || TREE_CHAIN (arglist))
5152 return 0;
5153 arg = TREE_VALUE (arglist);
5154 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5155 return 0;
5156
5157 if (target != const0_rtx)
5158 {
5159 len = c_strlen (arg, 1);
5160 if (! len || TREE_CODE (len) != INTEGER_CST)
5161 return 0;
5162 }
5163 else
5164 len = NULL_TREE;
5165
5166 arglist = build_tree_list (NULL_TREE, arg);
5167 arglist = tree_cons (NULL_TREE, dest, arglist);
5168 expand_expr (build_function_call_expr (fn, arglist),
5169 const0_rtx, VOIDmode, EXPAND_NORMAL);
5170
5171 if (target == const0_rtx)
5172 return const0_rtx;
5173 return expand_expr (len, target, mode, EXPAND_NORMAL);
5174 }
5175
5176 return 0;
5177 }
5178
5179 /* Expand a call to either the entry or exit function profiler. */
5180
5181 static rtx
5182 expand_builtin_profile_func (bool exitp)
5183 {
5184 rtx this, which;
5185
5186 this = DECL_RTL (current_function_decl);
5187 gcc_assert (MEM_P (this));
5188 this = XEXP (this, 0);
5189
5190 if (exitp)
5191 which = profile_function_exit_libfunc;
5192 else
5193 which = profile_function_entry_libfunc;
5194
5195 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5196 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5197 0),
5198 Pmode);
5199
5200 return const0_rtx;
5201 }
5202
5203 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5204
5205 static rtx
5206 round_trampoline_addr (rtx tramp)
5207 {
5208 rtx temp, addend, mask;
5209
5210 /* If we don't need too much alignment, we'll have been guaranteed
5211 proper alignment by get_trampoline_type. */
5212 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5213 return tramp;
5214
5215 /* Round address up to desired boundary. */
5216 temp = gen_reg_rtx (Pmode);
5217 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5218 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5219
5220 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5221 temp, 0, OPTAB_LIB_WIDEN);
5222 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5223 temp, 0, OPTAB_LIB_WIDEN);
5224
5225 return tramp;
5226 }
5227
5228 static rtx
5229 expand_builtin_init_trampoline (tree arglist)
5230 {
5231 tree t_tramp, t_func, t_chain;
5232 rtx r_tramp, r_func, r_chain;
5233 #ifdef TRAMPOLINE_TEMPLATE
5234 rtx blktramp;
5235 #endif
5236
5237 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5238 POINTER_TYPE, VOID_TYPE))
5239 return NULL_RTX;
5240
5241 t_tramp = TREE_VALUE (arglist);
5242 arglist = TREE_CHAIN (arglist);
5243 t_func = TREE_VALUE (arglist);
5244 arglist = TREE_CHAIN (arglist);
5245 t_chain = TREE_VALUE (arglist);
5246
5247 r_tramp = expand_normal (t_tramp);
5248 r_func = expand_normal (t_func);
5249 r_chain = expand_normal (t_chain);
5250
5251 /* Generate insns to initialize the trampoline. */
5252 r_tramp = round_trampoline_addr (r_tramp);
5253 #ifdef TRAMPOLINE_TEMPLATE
5254 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5255 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5256 emit_block_move (blktramp, assemble_trampoline_template (),
5257 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5258 #endif
5259 trampolines_created = 1;
5260 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5261
5262 return const0_rtx;
5263 }
5264
5265 static rtx
5266 expand_builtin_adjust_trampoline (tree arglist)
5267 {
5268 rtx tramp;
5269
5270 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5271 return NULL_RTX;
5272
5273 tramp = expand_normal (TREE_VALUE (arglist));
5274 tramp = round_trampoline_addr (tramp);
5275 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5276 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5277 #endif
5278
5279 return tramp;
5280 }
5281
5282 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5283 Return NULL_RTX if a normal call should be emitted rather than expanding
5284 the function in-line. EXP is the expression that is a call to the builtin
5285 function; if convenient, the result should be placed in TARGET. */
5286
5287 static rtx
5288 expand_builtin_signbit (tree exp, rtx target)
5289 {
5290 const struct real_format *fmt;
5291 enum machine_mode fmode, imode, rmode;
5292 HOST_WIDE_INT hi, lo;
5293 tree arg, arglist;
5294 int word, bitpos;
5295 rtx temp;
5296
5297 arglist = TREE_OPERAND (exp, 1);
5298 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5299 return 0;
5300
5301 arg = TREE_VALUE (arglist);
5302 fmode = TYPE_MODE (TREE_TYPE (arg));
5303 rmode = TYPE_MODE (TREE_TYPE (exp));
5304 fmt = REAL_MODE_FORMAT (fmode);
5305
5306 /* For floating point formats without a sign bit, implement signbit
5307 as "ARG < 0.0". */
5308 bitpos = fmt->signbit_ro;
5309 if (bitpos < 0)
5310 {
5311 /* But we can't do this if the format supports signed zero. */
5312 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5313 return 0;
5314
5315 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5316 build_real (TREE_TYPE (arg), dconst0));
5317 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5318 }
5319
5320 temp = expand_normal (arg);
5321 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5322 {
5323 imode = int_mode_for_mode (fmode);
5324 if (imode == BLKmode)
5325 return 0;
5326 temp = gen_lowpart (imode, temp);
5327 }
5328 else
5329 {
5330 imode = word_mode;
5331 /* Handle targets with different FP word orders. */
5332 if (FLOAT_WORDS_BIG_ENDIAN)
5333 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5334 else
5335 word = bitpos / BITS_PER_WORD;
5336 temp = operand_subword_force (temp, word, fmode);
5337 bitpos = bitpos % BITS_PER_WORD;
5338 }
5339
5340 /* Force the intermediate word_mode (or narrower) result into a
5341 register. This avoids attempting to create paradoxical SUBREGs
5342 of floating point modes below. */
5343 temp = force_reg (imode, temp);
5344
5345 /* If the bitpos is within the "result mode" lowpart, the operation
5346 can be implement with a single bitwise AND. Otherwise, we need
5347 a right shift and an AND. */
5348
5349 if (bitpos < GET_MODE_BITSIZE (rmode))
5350 {
5351 if (bitpos < HOST_BITS_PER_WIDE_INT)
5352 {
5353 hi = 0;
5354 lo = (HOST_WIDE_INT) 1 << bitpos;
5355 }
5356 else
5357 {
5358 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5359 lo = 0;
5360 }
5361
5362 if (imode != rmode)
5363 temp = gen_lowpart (rmode, temp);
5364 temp = expand_binop (rmode, and_optab, temp,
5365 immed_double_const (lo, hi, rmode),
5366 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5367 }
5368 else
5369 {
5370 /* Perform a logical right shift to place the signbit in the least
5371 significant bit, then truncate the result to the desired mode
5372 and mask just this bit. */
5373 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5374 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5375 temp = gen_lowpart (rmode, temp);
5376 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5377 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5378 }
5379
5380 return temp;
5381 }
5382
5383 /* Expand fork or exec calls. TARGET is the desired target of the
5384 call. ARGLIST is the list of arguments of the call. FN is the
5385 identificator of the actual function. IGNORE is nonzero if the
5386 value is to be ignored. */
5387
5388 static rtx
5389 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5390 {
5391 tree id, decl;
5392 tree call;
5393
5394 /* If we are not profiling, just call the function. */
5395 if (!profile_arc_flag)
5396 return NULL_RTX;
5397
5398 /* Otherwise call the wrapper. This should be equivalent for the rest of
5399 compiler, so the code does not diverge, and the wrapper may run the
5400 code necessary for keeping the profiling sane. */
5401
5402 switch (DECL_FUNCTION_CODE (fn))
5403 {
5404 case BUILT_IN_FORK:
5405 id = get_identifier ("__gcov_fork");
5406 break;
5407
5408 case BUILT_IN_EXECL:
5409 id = get_identifier ("__gcov_execl");
5410 break;
5411
5412 case BUILT_IN_EXECV:
5413 id = get_identifier ("__gcov_execv");
5414 break;
5415
5416 case BUILT_IN_EXECLP:
5417 id = get_identifier ("__gcov_execlp");
5418 break;
5419
5420 case BUILT_IN_EXECLE:
5421 id = get_identifier ("__gcov_execle");
5422 break;
5423
5424 case BUILT_IN_EXECVP:
5425 id = get_identifier ("__gcov_execvp");
5426 break;
5427
5428 case BUILT_IN_EXECVE:
5429 id = get_identifier ("__gcov_execve");
5430 break;
5431
5432 default:
5433 gcc_unreachable ();
5434 }
5435
5436 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5437 DECL_EXTERNAL (decl) = 1;
5438 TREE_PUBLIC (decl) = 1;
5439 DECL_ARTIFICIAL (decl) = 1;
5440 TREE_NOTHROW (decl) = 1;
5441 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5442 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5443 call = build_function_call_expr (decl, arglist);
5444
5445 return expand_call (call, target, ignore);
5446 }
5447
5448 \f
5449 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5450 the pointer in these functions is void*, the tree optimizers may remove
5451 casts. The mode computed in expand_builtin isn't reliable either, due
5452 to __sync_bool_compare_and_swap.
5453
5454 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5455 group of builtins. This gives us log2 of the mode size. */
5456
5457 static inline enum machine_mode
5458 get_builtin_sync_mode (int fcode_diff)
5459 {
5460 /* The size is not negotiable, so ask not to get BLKmode in return
5461 if the target indicates that a smaller size would be better. */
5462 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5463 }
5464
5465 /* Expand the memory expression LOC and return the appropriate memory operand
5466 for the builtin_sync operations. */
5467
5468 static rtx
5469 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5470 {
5471 rtx addr, mem;
5472
5473 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5474
5475 /* Note that we explicitly do not want any alias information for this
5476 memory, so that we kill all other live memories. Otherwise we don't
5477 satisfy the full barrier semantics of the intrinsic. */
5478 mem = validize_mem (gen_rtx_MEM (mode, addr));
5479
5480 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5481 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5482 MEM_VOLATILE_P (mem) = 1;
5483
5484 return mem;
5485 }
5486
5487 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5488 ARGLIST is the operands list to the function. CODE is the rtx code
5489 that corresponds to the arithmetic or logical operation from the name;
5490 an exception here is that NOT actually means NAND. TARGET is an optional
5491 place for us to store the results; AFTER is true if this is the
5492 fetch_and_xxx form. IGNORE is true if we don't actually care about
5493 the result of the operation at all. */
5494
5495 static rtx
5496 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5497 enum rtx_code code, bool after,
5498 rtx target, bool ignore)
5499 {
5500 rtx val, mem;
5501
5502 /* Expand the operands. */
5503 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5504
5505 arglist = TREE_CHAIN (arglist);
5506 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5507 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5508 val = convert_to_mode (mode, val, 1);
5509
5510 if (ignore)
5511 return expand_sync_operation (mem, val, code);
5512 else
5513 return expand_sync_fetch_operation (mem, val, code, after, target);
5514 }
5515
5516 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5517 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5518 true if this is the boolean form. TARGET is a place for us to store the
5519 results; this is NOT optional if IS_BOOL is true. */
5520
5521 static rtx
5522 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5523 bool is_bool, rtx target)
5524 {
5525 rtx old_val, new_val, mem;
5526
5527 /* Expand the operands. */
5528 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5529
5530 arglist = TREE_CHAIN (arglist);
5531 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5532 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5533 old_val = convert_to_mode (mode, old_val, 1);
5534
5535 arglist = TREE_CHAIN (arglist);
5536 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5537 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5538 new_val = convert_to_mode (mode, new_val, 1);
5539
5540 if (is_bool)
5541 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5542 else
5543 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5544 }
5545
5546 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5547 general form is actually an atomic exchange, and some targets only
5548 support a reduced form with the second argument being a constant 1.
5549 ARGLIST is the operands list to the function; TARGET is an optional
5550 place for us to store the results. */
5551
5552 static rtx
5553 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5554 rtx target)
5555 {
5556 rtx val, mem;
5557
5558 /* Expand the operands. */
5559 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5560
5561 arglist = TREE_CHAIN (arglist);
5562 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5563 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5564 val = convert_to_mode (mode, val, 1);
5565
5566 return expand_sync_lock_test_and_set (mem, val, target);
5567 }
5568
5569 /* Expand the __sync_synchronize intrinsic. */
5570
5571 static void
5572 expand_builtin_synchronize (void)
5573 {
5574 tree x;
5575
5576 #ifdef HAVE_memory_barrier
5577 if (HAVE_memory_barrier)
5578 {
5579 emit_insn (gen_memory_barrier ());
5580 return;
5581 }
5582 #endif
5583
5584 /* If no explicit memory barrier instruction is available, create an
5585 empty asm stmt with a memory clobber. */
5586 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5587 tree_cons (NULL, build_string (6, "memory"), NULL));
5588 ASM_VOLATILE_P (x) = 1;
5589 expand_asm_expr (x);
5590 }
5591
5592 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5593 to the function. */
5594
5595 static void
5596 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5597 {
5598 enum insn_code icode;
5599 rtx mem, insn;
5600 rtx val = const0_rtx;
5601
5602 /* Expand the operands. */
5603 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5604
5605 /* If there is an explicit operation in the md file, use it. */
5606 icode = sync_lock_release[mode];
5607 if (icode != CODE_FOR_nothing)
5608 {
5609 if (!insn_data[icode].operand[1].predicate (val, mode))
5610 val = force_reg (mode, val);
5611
5612 insn = GEN_FCN (icode) (mem, val);
5613 if (insn)
5614 {
5615 emit_insn (insn);
5616 return;
5617 }
5618 }
5619
5620 /* Otherwise we can implement this operation by emitting a barrier
5621 followed by a store of zero. */
5622 expand_builtin_synchronize ();
5623 emit_move_insn (mem, val);
5624 }
5625 \f
5626 /* Expand an expression EXP that calls a built-in function,
5627 with result going to TARGET if that's convenient
5628 (and in mode MODE if that's convenient).
5629 SUBTARGET may be used as the target for computing one of EXP's operands.
5630 IGNORE is nonzero if the value is to be ignored. */
5631
5632 rtx
5633 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5634 int ignore)
5635 {
5636 tree fndecl = get_callee_fndecl (exp);
5637 tree arglist = TREE_OPERAND (exp, 1);
5638 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5639 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5640
5641 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5642 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5643
5644 /* When not optimizing, generate calls to library functions for a certain
5645 set of builtins. */
5646 if (!optimize
5647 && !called_as_built_in (fndecl)
5648 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5649 && fcode != BUILT_IN_ALLOCA)
5650 return expand_call (exp, target, ignore);
5651
5652 /* The built-in function expanders test for target == const0_rtx
5653 to determine whether the function's result will be ignored. */
5654 if (ignore)
5655 target = const0_rtx;
5656
5657 /* If the result of a pure or const built-in function is ignored, and
5658 none of its arguments are volatile, we can avoid expanding the
5659 built-in call and just evaluate the arguments for side-effects. */
5660 if (target == const0_rtx
5661 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5662 {
5663 bool volatilep = false;
5664 tree arg;
5665
5666 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5667 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5668 {
5669 volatilep = true;
5670 break;
5671 }
5672
5673 if (! volatilep)
5674 {
5675 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5676 expand_expr (TREE_VALUE (arg), const0_rtx,
5677 VOIDmode, EXPAND_NORMAL);
5678 return const0_rtx;
5679 }
5680 }
5681
5682 switch (fcode)
5683 {
5684 CASE_FLT_FN (BUILT_IN_FABS):
5685 target = expand_builtin_fabs (arglist, target, subtarget);
5686 if (target)
5687 return target;
5688 break;
5689
5690 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5691 target = expand_builtin_copysign (arglist, target, subtarget);
5692 if (target)
5693 return target;
5694 break;
5695
5696 /* Just do a normal library call if we were unable to fold
5697 the values. */
5698 CASE_FLT_FN (BUILT_IN_CABS):
5699 break;
5700
5701 CASE_FLT_FN (BUILT_IN_EXP):
5702 CASE_FLT_FN (BUILT_IN_EXP10):
5703 CASE_FLT_FN (BUILT_IN_POW10):
5704 CASE_FLT_FN (BUILT_IN_EXP2):
5705 CASE_FLT_FN (BUILT_IN_EXPM1):
5706 CASE_FLT_FN (BUILT_IN_LOGB):
5707 CASE_FLT_FN (BUILT_IN_ILOGB):
5708 CASE_FLT_FN (BUILT_IN_LOG):
5709 CASE_FLT_FN (BUILT_IN_LOG10):
5710 CASE_FLT_FN (BUILT_IN_LOG2):
5711 CASE_FLT_FN (BUILT_IN_LOG1P):
5712 CASE_FLT_FN (BUILT_IN_TAN):
5713 CASE_FLT_FN (BUILT_IN_ASIN):
5714 CASE_FLT_FN (BUILT_IN_ACOS):
5715 CASE_FLT_FN (BUILT_IN_ATAN):
5716 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5717 because of possible accuracy problems. */
5718 if (! flag_unsafe_math_optimizations)
5719 break;
5720 CASE_FLT_FN (BUILT_IN_SQRT):
5721 CASE_FLT_FN (BUILT_IN_FLOOR):
5722 CASE_FLT_FN (BUILT_IN_CEIL):
5723 CASE_FLT_FN (BUILT_IN_TRUNC):
5724 CASE_FLT_FN (BUILT_IN_ROUND):
5725 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5726 CASE_FLT_FN (BUILT_IN_RINT):
5727 target = expand_builtin_mathfn (exp, target, subtarget);
5728 if (target)
5729 return target;
5730 break;
5731
5732 CASE_FLT_FN (BUILT_IN_LCEIL):
5733 CASE_FLT_FN (BUILT_IN_LLCEIL):
5734 CASE_FLT_FN (BUILT_IN_LFLOOR):
5735 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5736 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5737 if (target)
5738 return target;
5739 break;
5740
5741 CASE_FLT_FN (BUILT_IN_LRINT):
5742 CASE_FLT_FN (BUILT_IN_LLRINT):
5743 CASE_FLT_FN (BUILT_IN_LROUND):
5744 CASE_FLT_FN (BUILT_IN_LLROUND):
5745 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
5746 if (target)
5747 return target;
5748 break;
5749
5750 CASE_FLT_FN (BUILT_IN_POW):
5751 target = expand_builtin_pow (exp, target, subtarget);
5752 if (target)
5753 return target;
5754 break;
5755
5756 CASE_FLT_FN (BUILT_IN_POWI):
5757 target = expand_builtin_powi (exp, target, subtarget);
5758 if (target)
5759 return target;
5760 break;
5761
5762 CASE_FLT_FN (BUILT_IN_ATAN2):
5763 CASE_FLT_FN (BUILT_IN_LDEXP):
5764 if (! flag_unsafe_math_optimizations)
5765 break;
5766
5767 CASE_FLT_FN (BUILT_IN_FMOD):
5768 CASE_FLT_FN (BUILT_IN_REMAINDER):
5769 CASE_FLT_FN (BUILT_IN_DREM):
5770 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5771 if (target)
5772 return target;
5773 break;
5774
5775 CASE_FLT_FN (BUILT_IN_SIN):
5776 CASE_FLT_FN (BUILT_IN_COS):
5777 if (! flag_unsafe_math_optimizations)
5778 break;
5779 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5780 if (target)
5781 return target;
5782 break;
5783
5784 CASE_FLT_FN (BUILT_IN_SINCOS):
5785 if (! flag_unsafe_math_optimizations)
5786 break;
5787 target = expand_builtin_sincos (exp);
5788 if (target)
5789 return target;
5790 break;
5791
5792 case BUILT_IN_APPLY_ARGS:
5793 return expand_builtin_apply_args ();
5794
5795 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5796 FUNCTION with a copy of the parameters described by
5797 ARGUMENTS, and ARGSIZE. It returns a block of memory
5798 allocated on the stack into which is stored all the registers
5799 that might possibly be used for returning the result of a
5800 function. ARGUMENTS is the value returned by
5801 __builtin_apply_args. ARGSIZE is the number of bytes of
5802 arguments that must be copied. ??? How should this value be
5803 computed? We'll also need a safe worst case value for varargs
5804 functions. */
5805 case BUILT_IN_APPLY:
5806 if (!validate_arglist (arglist, POINTER_TYPE,
5807 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5808 && !validate_arglist (arglist, REFERENCE_TYPE,
5809 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5810 return const0_rtx;
5811 else
5812 {
5813 int i;
5814 tree t;
5815 rtx ops[3];
5816
5817 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5818 ops[i] = expand_normal (TREE_VALUE (t));
5819
5820 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5821 }
5822
5823 /* __builtin_return (RESULT) causes the function to return the
5824 value described by RESULT. RESULT is address of the block of
5825 memory returned by __builtin_apply. */
5826 case BUILT_IN_RETURN:
5827 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5828 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5829 return const0_rtx;
5830
5831 case BUILT_IN_SAVEREGS:
5832 return expand_builtin_saveregs ();
5833
5834 case BUILT_IN_ARGS_INFO:
5835 return expand_builtin_args_info (arglist);
5836
5837 /* Return the address of the first anonymous stack arg. */
5838 case BUILT_IN_NEXT_ARG:
5839 if (fold_builtin_next_arg (arglist))
5840 return const0_rtx;
5841 return expand_builtin_next_arg ();
5842
5843 case BUILT_IN_CLASSIFY_TYPE:
5844 return expand_builtin_classify_type (arglist);
5845
5846 case BUILT_IN_CONSTANT_P:
5847 return const0_rtx;
5848
5849 case BUILT_IN_FRAME_ADDRESS:
5850 case BUILT_IN_RETURN_ADDRESS:
5851 return expand_builtin_frame_address (fndecl, arglist);
5852
5853 /* Returns the address of the area where the structure is returned.
5854 0 otherwise. */
5855 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5856 if (arglist != 0
5857 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5858 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5859 return const0_rtx;
5860 else
5861 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5862
5863 case BUILT_IN_ALLOCA:
5864 target = expand_builtin_alloca (arglist, target);
5865 if (target)
5866 return target;
5867 break;
5868
5869 case BUILT_IN_STACK_SAVE:
5870 return expand_stack_save ();
5871
5872 case BUILT_IN_STACK_RESTORE:
5873 expand_stack_restore (TREE_VALUE (arglist));
5874 return const0_rtx;
5875
5876 case BUILT_IN_BSWAP32:
5877 case BUILT_IN_BSWAP64:
5878 target = expand_builtin_bswap (arglist, target, subtarget);
5879
5880 if (target)
5881 return target;
5882 break;
5883
5884 CASE_INT_FN (BUILT_IN_FFS):
5885 case BUILT_IN_FFSIMAX:
5886 target = expand_builtin_unop (target_mode, arglist, target,
5887 subtarget, ffs_optab);
5888 if (target)
5889 return target;
5890 break;
5891
5892 CASE_INT_FN (BUILT_IN_CLZ):
5893 case BUILT_IN_CLZIMAX:
5894 target = expand_builtin_unop (target_mode, arglist, target,
5895 subtarget, clz_optab);
5896 if (target)
5897 return target;
5898 break;
5899
5900 CASE_INT_FN (BUILT_IN_CTZ):
5901 case BUILT_IN_CTZIMAX:
5902 target = expand_builtin_unop (target_mode, arglist, target,
5903 subtarget, ctz_optab);
5904 if (target)
5905 return target;
5906 break;
5907
5908 CASE_INT_FN (BUILT_IN_POPCOUNT):
5909 case BUILT_IN_POPCOUNTIMAX:
5910 target = expand_builtin_unop (target_mode, arglist, target,
5911 subtarget, popcount_optab);
5912 if (target)
5913 return target;
5914 break;
5915
5916 CASE_INT_FN (BUILT_IN_PARITY):
5917 case BUILT_IN_PARITYIMAX:
5918 target = expand_builtin_unop (target_mode, arglist, target,
5919 subtarget, parity_optab);
5920 if (target)
5921 return target;
5922 break;
5923
5924 case BUILT_IN_STRLEN:
5925 target = expand_builtin_strlen (arglist, target, target_mode);
5926 if (target)
5927 return target;
5928 break;
5929
5930 case BUILT_IN_STRCPY:
5931 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5932 if (target)
5933 return target;
5934 break;
5935
5936 case BUILT_IN_STRNCPY:
5937 target = expand_builtin_strncpy (exp, target, mode);
5938 if (target)
5939 return target;
5940 break;
5941
5942 case BUILT_IN_STPCPY:
5943 target = expand_builtin_stpcpy (exp, target, mode);
5944 if (target)
5945 return target;
5946 break;
5947
5948 case BUILT_IN_STRCAT:
5949 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5950 if (target)
5951 return target;
5952 break;
5953
5954 case BUILT_IN_STRNCAT:
5955 target = expand_builtin_strncat (arglist, target, mode);
5956 if (target)
5957 return target;
5958 break;
5959
5960 case BUILT_IN_STRSPN:
5961 target = expand_builtin_strspn (arglist, target, mode);
5962 if (target)
5963 return target;
5964 break;
5965
5966 case BUILT_IN_STRCSPN:
5967 target = expand_builtin_strcspn (arglist, target, mode);
5968 if (target)
5969 return target;
5970 break;
5971
5972 case BUILT_IN_STRSTR:
5973 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5974 if (target)
5975 return target;
5976 break;
5977
5978 case BUILT_IN_STRPBRK:
5979 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5980 if (target)
5981 return target;
5982 break;
5983
5984 case BUILT_IN_INDEX:
5985 case BUILT_IN_STRCHR:
5986 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5987 if (target)
5988 return target;
5989 break;
5990
5991 case BUILT_IN_RINDEX:
5992 case BUILT_IN_STRRCHR:
5993 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5994 if (target)
5995 return target;
5996 break;
5997
5998 case BUILT_IN_MEMCPY:
5999 target = expand_builtin_memcpy (exp, target, mode);
6000 if (target)
6001 return target;
6002 break;
6003
6004 case BUILT_IN_MEMPCPY:
6005 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6006 if (target)
6007 return target;
6008 break;
6009
6010 case BUILT_IN_MEMMOVE:
6011 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6012 mode);
6013 if (target)
6014 return target;
6015 break;
6016
6017 case BUILT_IN_BCOPY:
6018 target = expand_builtin_bcopy (exp);
6019 if (target)
6020 return target;
6021 break;
6022
6023 case BUILT_IN_MEMSET:
6024 target = expand_builtin_memset (arglist, target, mode, exp);
6025 if (target)
6026 return target;
6027 break;
6028
6029 case BUILT_IN_BZERO:
6030 target = expand_builtin_bzero (exp);
6031 if (target)
6032 return target;
6033 break;
6034
6035 case BUILT_IN_STRCMP:
6036 target = expand_builtin_strcmp (exp, target, mode);
6037 if (target)
6038 return target;
6039 break;
6040
6041 case BUILT_IN_STRNCMP:
6042 target = expand_builtin_strncmp (exp, target, mode);
6043 if (target)
6044 return target;
6045 break;
6046
6047 case BUILT_IN_BCMP:
6048 case BUILT_IN_MEMCMP:
6049 target = expand_builtin_memcmp (exp, arglist, target, mode);
6050 if (target)
6051 return target;
6052 break;
6053
6054 case BUILT_IN_SETJMP:
6055 /* This should have been lowered to the builtins below. */
6056 gcc_unreachable ();
6057
6058 case BUILT_IN_SETJMP_SETUP:
6059 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6060 and the receiver label. */
6061 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6062 {
6063 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6064 VOIDmode, EXPAND_NORMAL);
6065 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6066 rtx label_r = label_rtx (label);
6067
6068 /* This is copied from the handling of non-local gotos. */
6069 expand_builtin_setjmp_setup (buf_addr, label_r);
6070 nonlocal_goto_handler_labels
6071 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6072 nonlocal_goto_handler_labels);
6073 /* ??? Do not let expand_label treat us as such since we would
6074 not want to be both on the list of non-local labels and on
6075 the list of forced labels. */
6076 FORCED_LABEL (label) = 0;
6077 return const0_rtx;
6078 }
6079 break;
6080
6081 case BUILT_IN_SETJMP_DISPATCHER:
6082 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6083 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6084 {
6085 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6086 rtx label_r = label_rtx (label);
6087
6088 /* Remove the dispatcher label from the list of non-local labels
6089 since the receiver labels have been added to it above. */
6090 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6091 return const0_rtx;
6092 }
6093 break;
6094
6095 case BUILT_IN_SETJMP_RECEIVER:
6096 /* __builtin_setjmp_receiver is passed the receiver label. */
6097 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6098 {
6099 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6100 rtx label_r = label_rtx (label);
6101
6102 expand_builtin_setjmp_receiver (label_r);
6103 return const0_rtx;
6104 }
6105 break;
6106
6107 /* __builtin_longjmp is passed a pointer to an array of five words.
6108 It's similar to the C library longjmp function but works with
6109 __builtin_setjmp above. */
6110 case BUILT_IN_LONGJMP:
6111 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6112 {
6113 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6114 VOIDmode, EXPAND_NORMAL);
6115 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6116
6117 if (value != const1_rtx)
6118 {
6119 error ("%<__builtin_longjmp%> second argument must be 1");
6120 return const0_rtx;
6121 }
6122
6123 expand_builtin_longjmp (buf_addr, value);
6124 return const0_rtx;
6125 }
6126 break;
6127
6128 case BUILT_IN_NONLOCAL_GOTO:
6129 target = expand_builtin_nonlocal_goto (arglist);
6130 if (target)
6131 return target;
6132 break;
6133
6134 /* This updates the setjmp buffer that is its argument with the value
6135 of the current stack pointer. */
6136 case BUILT_IN_UPDATE_SETJMP_BUF:
6137 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6138 {
6139 rtx buf_addr
6140 = expand_normal (TREE_VALUE (arglist));
6141
6142 expand_builtin_update_setjmp_buf (buf_addr);
6143 return const0_rtx;
6144 }
6145 break;
6146
6147 case BUILT_IN_TRAP:
6148 expand_builtin_trap ();
6149 return const0_rtx;
6150
6151 case BUILT_IN_PRINTF:
6152 target = expand_builtin_printf (exp, target, mode, false);
6153 if (target)
6154 return target;
6155 break;
6156
6157 case BUILT_IN_PRINTF_UNLOCKED:
6158 target = expand_builtin_printf (exp, target, mode, true);
6159 if (target)
6160 return target;
6161 break;
6162
6163 case BUILT_IN_FPUTS:
6164 target = expand_builtin_fputs (arglist, target, false);
6165 if (target)
6166 return target;
6167 break;
6168 case BUILT_IN_FPUTS_UNLOCKED:
6169 target = expand_builtin_fputs (arglist, target, true);
6170 if (target)
6171 return target;
6172 break;
6173
6174 case BUILT_IN_FPRINTF:
6175 target = expand_builtin_fprintf (exp, target, mode, false);
6176 if (target)
6177 return target;
6178 break;
6179
6180 case BUILT_IN_FPRINTF_UNLOCKED:
6181 target = expand_builtin_fprintf (exp, target, mode, true);
6182 if (target)
6183 return target;
6184 break;
6185
6186 case BUILT_IN_SPRINTF:
6187 target = expand_builtin_sprintf (arglist, target, mode);
6188 if (target)
6189 return target;
6190 break;
6191
6192 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6193 target = expand_builtin_signbit (exp, target);
6194 if (target)
6195 return target;
6196 break;
6197
6198 /* Various hooks for the DWARF 2 __throw routine. */
6199 case BUILT_IN_UNWIND_INIT:
6200 expand_builtin_unwind_init ();
6201 return const0_rtx;
6202 case BUILT_IN_DWARF_CFA:
6203 return virtual_cfa_rtx;
6204 #ifdef DWARF2_UNWIND_INFO
6205 case BUILT_IN_DWARF_SP_COLUMN:
6206 return expand_builtin_dwarf_sp_column ();
6207 case BUILT_IN_INIT_DWARF_REG_SIZES:
6208 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6209 return const0_rtx;
6210 #endif
6211 case BUILT_IN_FROB_RETURN_ADDR:
6212 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6213 case BUILT_IN_EXTRACT_RETURN_ADDR:
6214 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6215 case BUILT_IN_EH_RETURN:
6216 expand_builtin_eh_return (TREE_VALUE (arglist),
6217 TREE_VALUE (TREE_CHAIN (arglist)));
6218 return const0_rtx;
6219 #ifdef EH_RETURN_DATA_REGNO
6220 case BUILT_IN_EH_RETURN_DATA_REGNO:
6221 return expand_builtin_eh_return_data_regno (arglist);
6222 #endif
6223 case BUILT_IN_EXTEND_POINTER:
6224 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6225
6226 case BUILT_IN_VA_START:
6227 case BUILT_IN_STDARG_START:
6228 return expand_builtin_va_start (arglist);
6229 case BUILT_IN_VA_END:
6230 return expand_builtin_va_end (arglist);
6231 case BUILT_IN_VA_COPY:
6232 return expand_builtin_va_copy (arglist);
6233 case BUILT_IN_EXPECT:
6234 return expand_builtin_expect (arglist, target);
6235 case BUILT_IN_PREFETCH:
6236 expand_builtin_prefetch (arglist);
6237 return const0_rtx;
6238
6239 case BUILT_IN_PROFILE_FUNC_ENTER:
6240 return expand_builtin_profile_func (false);
6241 case BUILT_IN_PROFILE_FUNC_EXIT:
6242 return expand_builtin_profile_func (true);
6243
6244 case BUILT_IN_INIT_TRAMPOLINE:
6245 return expand_builtin_init_trampoline (arglist);
6246 case BUILT_IN_ADJUST_TRAMPOLINE:
6247 return expand_builtin_adjust_trampoline (arglist);
6248
6249 case BUILT_IN_FORK:
6250 case BUILT_IN_EXECL:
6251 case BUILT_IN_EXECV:
6252 case BUILT_IN_EXECLP:
6253 case BUILT_IN_EXECLE:
6254 case BUILT_IN_EXECVP:
6255 case BUILT_IN_EXECVE:
6256 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6257 if (target)
6258 return target;
6259 break;
6260
6261 case BUILT_IN_FETCH_AND_ADD_1:
6262 case BUILT_IN_FETCH_AND_ADD_2:
6263 case BUILT_IN_FETCH_AND_ADD_4:
6264 case BUILT_IN_FETCH_AND_ADD_8:
6265 case BUILT_IN_FETCH_AND_ADD_16:
6266 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6267 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6268 false, target, ignore);
6269 if (target)
6270 return target;
6271 break;
6272
6273 case BUILT_IN_FETCH_AND_SUB_1:
6274 case BUILT_IN_FETCH_AND_SUB_2:
6275 case BUILT_IN_FETCH_AND_SUB_4:
6276 case BUILT_IN_FETCH_AND_SUB_8:
6277 case BUILT_IN_FETCH_AND_SUB_16:
6278 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6279 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6280 false, target, ignore);
6281 if (target)
6282 return target;
6283 break;
6284
6285 case BUILT_IN_FETCH_AND_OR_1:
6286 case BUILT_IN_FETCH_AND_OR_2:
6287 case BUILT_IN_FETCH_AND_OR_4:
6288 case BUILT_IN_FETCH_AND_OR_8:
6289 case BUILT_IN_FETCH_AND_OR_16:
6290 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6291 target = expand_builtin_sync_operation (mode, arglist, IOR,
6292 false, target, ignore);
6293 if (target)
6294 return target;
6295 break;
6296
6297 case BUILT_IN_FETCH_AND_AND_1:
6298 case BUILT_IN_FETCH_AND_AND_2:
6299 case BUILT_IN_FETCH_AND_AND_4:
6300 case BUILT_IN_FETCH_AND_AND_8:
6301 case BUILT_IN_FETCH_AND_AND_16:
6302 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6303 target = expand_builtin_sync_operation (mode, arglist, AND,
6304 false, target, ignore);
6305 if (target)
6306 return target;
6307 break;
6308
6309 case BUILT_IN_FETCH_AND_XOR_1:
6310 case BUILT_IN_FETCH_AND_XOR_2:
6311 case BUILT_IN_FETCH_AND_XOR_4:
6312 case BUILT_IN_FETCH_AND_XOR_8:
6313 case BUILT_IN_FETCH_AND_XOR_16:
6314 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6315 target = expand_builtin_sync_operation (mode, arglist, XOR,
6316 false, target, ignore);
6317 if (target)
6318 return target;
6319 break;
6320
6321 case BUILT_IN_FETCH_AND_NAND_1:
6322 case BUILT_IN_FETCH_AND_NAND_2:
6323 case BUILT_IN_FETCH_AND_NAND_4:
6324 case BUILT_IN_FETCH_AND_NAND_8:
6325 case BUILT_IN_FETCH_AND_NAND_16:
6326 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6327 target = expand_builtin_sync_operation (mode, arglist, NOT,
6328 false, target, ignore);
6329 if (target)
6330 return target;
6331 break;
6332
6333 case BUILT_IN_ADD_AND_FETCH_1:
6334 case BUILT_IN_ADD_AND_FETCH_2:
6335 case BUILT_IN_ADD_AND_FETCH_4:
6336 case BUILT_IN_ADD_AND_FETCH_8:
6337 case BUILT_IN_ADD_AND_FETCH_16:
6338 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6339 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6340 true, target, ignore);
6341 if (target)
6342 return target;
6343 break;
6344
6345 case BUILT_IN_SUB_AND_FETCH_1:
6346 case BUILT_IN_SUB_AND_FETCH_2:
6347 case BUILT_IN_SUB_AND_FETCH_4:
6348 case BUILT_IN_SUB_AND_FETCH_8:
6349 case BUILT_IN_SUB_AND_FETCH_16:
6350 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6351 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6352 true, target, ignore);
6353 if (target)
6354 return target;
6355 break;
6356
6357 case BUILT_IN_OR_AND_FETCH_1:
6358 case BUILT_IN_OR_AND_FETCH_2:
6359 case BUILT_IN_OR_AND_FETCH_4:
6360 case BUILT_IN_OR_AND_FETCH_8:
6361 case BUILT_IN_OR_AND_FETCH_16:
6362 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6363 target = expand_builtin_sync_operation (mode, arglist, IOR,
6364 true, target, ignore);
6365 if (target)
6366 return target;
6367 break;
6368
6369 case BUILT_IN_AND_AND_FETCH_1:
6370 case BUILT_IN_AND_AND_FETCH_2:
6371 case BUILT_IN_AND_AND_FETCH_4:
6372 case BUILT_IN_AND_AND_FETCH_8:
6373 case BUILT_IN_AND_AND_FETCH_16:
6374 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6375 target = expand_builtin_sync_operation (mode, arglist, AND,
6376 true, target, ignore);
6377 if (target)
6378 return target;
6379 break;
6380
6381 case BUILT_IN_XOR_AND_FETCH_1:
6382 case BUILT_IN_XOR_AND_FETCH_2:
6383 case BUILT_IN_XOR_AND_FETCH_4:
6384 case BUILT_IN_XOR_AND_FETCH_8:
6385 case BUILT_IN_XOR_AND_FETCH_16:
6386 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6387 target = expand_builtin_sync_operation (mode, arglist, XOR,
6388 true, target, ignore);
6389 if (target)
6390 return target;
6391 break;
6392
6393 case BUILT_IN_NAND_AND_FETCH_1:
6394 case BUILT_IN_NAND_AND_FETCH_2:
6395 case BUILT_IN_NAND_AND_FETCH_4:
6396 case BUILT_IN_NAND_AND_FETCH_8:
6397 case BUILT_IN_NAND_AND_FETCH_16:
6398 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6399 target = expand_builtin_sync_operation (mode, arglist, NOT,
6400 true, target, ignore);
6401 if (target)
6402 return target;
6403 break;
6404
6405 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6406 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6407 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6408 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6409 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6410 if (mode == VOIDmode)
6411 mode = TYPE_MODE (boolean_type_node);
6412 if (!target || !register_operand (target, mode))
6413 target = gen_reg_rtx (mode);
6414
6415 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6416 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6417 if (target)
6418 return target;
6419 break;
6420
6421 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6422 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6423 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6424 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6425 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6426 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6427 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6428 if (target)
6429 return target;
6430 break;
6431
6432 case BUILT_IN_LOCK_TEST_AND_SET_1:
6433 case BUILT_IN_LOCK_TEST_AND_SET_2:
6434 case BUILT_IN_LOCK_TEST_AND_SET_4:
6435 case BUILT_IN_LOCK_TEST_AND_SET_8:
6436 case BUILT_IN_LOCK_TEST_AND_SET_16:
6437 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6438 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6439 if (target)
6440 return target;
6441 break;
6442
6443 case BUILT_IN_LOCK_RELEASE_1:
6444 case BUILT_IN_LOCK_RELEASE_2:
6445 case BUILT_IN_LOCK_RELEASE_4:
6446 case BUILT_IN_LOCK_RELEASE_8:
6447 case BUILT_IN_LOCK_RELEASE_16:
6448 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6449 expand_builtin_lock_release (mode, arglist);
6450 return const0_rtx;
6451
6452 case BUILT_IN_SYNCHRONIZE:
6453 expand_builtin_synchronize ();
6454 return const0_rtx;
6455
6456 case BUILT_IN_OBJECT_SIZE:
6457 return expand_builtin_object_size (exp);
6458
6459 case BUILT_IN_MEMCPY_CHK:
6460 case BUILT_IN_MEMPCPY_CHK:
6461 case BUILT_IN_MEMMOVE_CHK:
6462 case BUILT_IN_MEMSET_CHK:
6463 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6464 if (target)
6465 return target;
6466 break;
6467
6468 case BUILT_IN_STRCPY_CHK:
6469 case BUILT_IN_STPCPY_CHK:
6470 case BUILT_IN_STRNCPY_CHK:
6471 case BUILT_IN_STRCAT_CHK:
6472 case BUILT_IN_STRNCAT_CHK:
6473 case BUILT_IN_SNPRINTF_CHK:
6474 case BUILT_IN_VSNPRINTF_CHK:
6475 maybe_emit_chk_warning (exp, fcode);
6476 break;
6477
6478 case BUILT_IN_SPRINTF_CHK:
6479 case BUILT_IN_VSPRINTF_CHK:
6480 maybe_emit_sprintf_chk_warning (exp, fcode);
6481 break;
6482
6483 default: /* just do library call, if unknown builtin */
6484 break;
6485 }
6486
6487 /* The switch statement above can drop through to cause the function
6488 to be called normally. */
6489 return expand_call (exp, target, ignore);
6490 }
6491
6492 /* Determine whether a tree node represents a call to a built-in
6493 function. If the tree T is a call to a built-in function with
6494 the right number of arguments of the appropriate types, return
6495 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6496 Otherwise the return value is END_BUILTINS. */
6497
6498 enum built_in_function
6499 builtin_mathfn_code (tree t)
6500 {
6501 tree fndecl, arglist, parmlist;
6502 tree argtype, parmtype;
6503
6504 if (TREE_CODE (t) != CALL_EXPR
6505 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6506 return END_BUILTINS;
6507
6508 fndecl = get_callee_fndecl (t);
6509 if (fndecl == NULL_TREE
6510 || TREE_CODE (fndecl) != FUNCTION_DECL
6511 || ! DECL_BUILT_IN (fndecl)
6512 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6513 return END_BUILTINS;
6514
6515 arglist = TREE_OPERAND (t, 1);
6516 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6517 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6518 {
6519 /* If a function doesn't take a variable number of arguments,
6520 the last element in the list will have type `void'. */
6521 parmtype = TREE_VALUE (parmlist);
6522 if (VOID_TYPE_P (parmtype))
6523 {
6524 if (arglist)
6525 return END_BUILTINS;
6526 return DECL_FUNCTION_CODE (fndecl);
6527 }
6528
6529 if (! arglist)
6530 return END_BUILTINS;
6531
6532 argtype = TREE_TYPE (TREE_VALUE (arglist));
6533
6534 if (SCALAR_FLOAT_TYPE_P (parmtype))
6535 {
6536 if (! SCALAR_FLOAT_TYPE_P (argtype))
6537 return END_BUILTINS;
6538 }
6539 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6540 {
6541 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6542 return END_BUILTINS;
6543 }
6544 else if (POINTER_TYPE_P (parmtype))
6545 {
6546 if (! POINTER_TYPE_P (argtype))
6547 return END_BUILTINS;
6548 }
6549 else if (INTEGRAL_TYPE_P (parmtype))
6550 {
6551 if (! INTEGRAL_TYPE_P (argtype))
6552 return END_BUILTINS;
6553 }
6554 else
6555 return END_BUILTINS;
6556
6557 arglist = TREE_CHAIN (arglist);
6558 }
6559
6560 /* Variable-length argument list. */
6561 return DECL_FUNCTION_CODE (fndecl);
6562 }
6563
6564 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6565 constant. ARGLIST is the argument list of the call. */
6566
6567 static tree
6568 fold_builtin_constant_p (tree arglist)
6569 {
6570 if (arglist == 0)
6571 return 0;
6572
6573 arglist = TREE_VALUE (arglist);
6574
6575 /* We return 1 for a numeric type that's known to be a constant
6576 value at compile-time or for an aggregate type that's a
6577 literal constant. */
6578 STRIP_NOPS (arglist);
6579
6580 /* If we know this is a constant, emit the constant of one. */
6581 if (CONSTANT_CLASS_P (arglist)
6582 || (TREE_CODE (arglist) == CONSTRUCTOR
6583 && TREE_CONSTANT (arglist)))
6584 return integer_one_node;
6585 if (TREE_CODE (arglist) == ADDR_EXPR)
6586 {
6587 tree op = TREE_OPERAND (arglist, 0);
6588 if (TREE_CODE (op) == STRING_CST
6589 || (TREE_CODE (op) == ARRAY_REF
6590 && integer_zerop (TREE_OPERAND (op, 1))
6591 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6592 return integer_one_node;
6593 }
6594
6595 /* If this expression has side effects, show we don't know it to be a
6596 constant. Likewise if it's a pointer or aggregate type since in
6597 those case we only want literals, since those are only optimized
6598 when generating RTL, not later.
6599 And finally, if we are compiling an initializer, not code, we
6600 need to return a definite result now; there's not going to be any
6601 more optimization done. */
6602 if (TREE_SIDE_EFFECTS (arglist)
6603 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6604 || POINTER_TYPE_P (TREE_TYPE (arglist))
6605 || cfun == 0
6606 || folding_initializer)
6607 return integer_zero_node;
6608
6609 return 0;
6610 }
6611
6612 /* Fold a call to __builtin_expect, if we expect that a comparison against
6613 the argument will fold to a constant. In practice, this means a true
6614 constant or the address of a non-weak symbol. ARGLIST is the argument
6615 list of the call. */
6616
6617 static tree
6618 fold_builtin_expect (tree arglist)
6619 {
6620 tree arg, inner;
6621
6622 if (arglist == 0)
6623 return 0;
6624
6625 arg = TREE_VALUE (arglist);
6626
6627 /* If the argument isn't invariant, then there's nothing we can do. */
6628 if (!TREE_INVARIANT (arg))
6629 return 0;
6630
6631 /* If we're looking at an address of a weak decl, then do not fold. */
6632 inner = arg;
6633 STRIP_NOPS (inner);
6634 if (TREE_CODE (inner) == ADDR_EXPR)
6635 {
6636 do
6637 {
6638 inner = TREE_OPERAND (inner, 0);
6639 }
6640 while (TREE_CODE (inner) == COMPONENT_REF
6641 || TREE_CODE (inner) == ARRAY_REF);
6642 if (DECL_P (inner) && DECL_WEAK (inner))
6643 return 0;
6644 }
6645
6646 /* Otherwise, ARG already has the proper type for the return value. */
6647 return arg;
6648 }
6649
6650 /* Fold a call to __builtin_classify_type. */
6651
6652 static tree
6653 fold_builtin_classify_type (tree arglist)
6654 {
6655 if (arglist == 0)
6656 return build_int_cst (NULL_TREE, no_type_class);
6657
6658 return build_int_cst (NULL_TREE,
6659 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6660 }
6661
6662 /* Fold a call to __builtin_strlen. */
6663
6664 static tree
6665 fold_builtin_strlen (tree arglist)
6666 {
6667 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6668 return NULL_TREE;
6669 else
6670 {
6671 tree len = c_strlen (TREE_VALUE (arglist), 0);
6672
6673 if (len)
6674 {
6675 /* Convert from the internal "sizetype" type to "size_t". */
6676 if (size_type_node)
6677 len = fold_convert (size_type_node, len);
6678 return len;
6679 }
6680
6681 return NULL_TREE;
6682 }
6683 }
6684
6685 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6686
6687 static tree
6688 fold_builtin_inf (tree type, int warn)
6689 {
6690 REAL_VALUE_TYPE real;
6691
6692 /* __builtin_inff is intended to be usable to define INFINITY on all
6693 targets. If an infinity is not available, INFINITY expands "to a
6694 positive constant of type float that overflows at translation
6695 time", footnote "In this case, using INFINITY will violate the
6696 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6697 Thus we pedwarn to ensure this constraint violation is
6698 diagnosed. */
6699 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6700 pedwarn ("target format does not support infinity");
6701
6702 real_inf (&real);
6703 return build_real (type, real);
6704 }
6705
6706 /* Fold a call to __builtin_nan or __builtin_nans. */
6707
6708 static tree
6709 fold_builtin_nan (tree arglist, tree type, int quiet)
6710 {
6711 REAL_VALUE_TYPE real;
6712 const char *str;
6713
6714 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6715 return 0;
6716 str = c_getstr (TREE_VALUE (arglist));
6717 if (!str)
6718 return 0;
6719
6720 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6721 return 0;
6722
6723 return build_real (type, real);
6724 }
6725
6726 /* Return true if the floating point expression T has an integer value.
6727 We also allow +Inf, -Inf and NaN to be considered integer values. */
6728
6729 static bool
6730 integer_valued_real_p (tree t)
6731 {
6732 switch (TREE_CODE (t))
6733 {
6734 case FLOAT_EXPR:
6735 return true;
6736
6737 case ABS_EXPR:
6738 case SAVE_EXPR:
6739 case NON_LVALUE_EXPR:
6740 return integer_valued_real_p (TREE_OPERAND (t, 0));
6741
6742 case COMPOUND_EXPR:
6743 case GIMPLE_MODIFY_STMT:
6744 case BIND_EXPR:
6745 return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
6746
6747 case PLUS_EXPR:
6748 case MINUS_EXPR:
6749 case MULT_EXPR:
6750 case MIN_EXPR:
6751 case MAX_EXPR:
6752 return integer_valued_real_p (TREE_OPERAND (t, 0))
6753 && integer_valued_real_p (TREE_OPERAND (t, 1));
6754
6755 case COND_EXPR:
6756 return integer_valued_real_p (TREE_OPERAND (t, 1))
6757 && integer_valued_real_p (TREE_OPERAND (t, 2));
6758
6759 case REAL_CST:
6760 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
6761
6762 case NOP_EXPR:
6763 {
6764 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6765 if (TREE_CODE (type) == INTEGER_TYPE)
6766 return true;
6767 if (TREE_CODE (type) == REAL_TYPE)
6768 return integer_valued_real_p (TREE_OPERAND (t, 0));
6769 break;
6770 }
6771
6772 case CALL_EXPR:
6773 switch (builtin_mathfn_code (t))
6774 {
6775 CASE_FLT_FN (BUILT_IN_CEIL):
6776 CASE_FLT_FN (BUILT_IN_FLOOR):
6777 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6778 CASE_FLT_FN (BUILT_IN_RINT):
6779 CASE_FLT_FN (BUILT_IN_ROUND):
6780 CASE_FLT_FN (BUILT_IN_TRUNC):
6781 return true;
6782
6783 CASE_FLT_FN (BUILT_IN_FMIN):
6784 CASE_FLT_FN (BUILT_IN_FMAX):
6785 return integer_valued_real_p (TREE_VALUE (TREE_OPERAND (t, 1)))
6786 && integer_valued_real_p (TREE_VALUE (TREE_CHAIN (TREE_OPERAND (t, 1))));
6787
6788 default:
6789 break;
6790 }
6791 break;
6792
6793 default:
6794 break;
6795 }
6796 return false;
6797 }
6798
6799 /* EXP is assumed to be builtin call where truncation can be propagated
6800 across (for instance floor((double)f) == (double)floorf (f).
6801 Do the transformation. */
6802
6803 static tree
6804 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6805 {
6806 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6807 tree arg;
6808
6809 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6810 return 0;
6811
6812 arg = TREE_VALUE (arglist);
6813 /* Integer rounding functions are idempotent. */
6814 if (fcode == builtin_mathfn_code (arg))
6815 return arg;
6816
6817 /* If argument is already integer valued, and we don't need to worry
6818 about setting errno, there's no need to perform rounding. */
6819 if (! flag_errno_math && integer_valued_real_p (arg))
6820 return arg;
6821
6822 if (optimize)
6823 {
6824 tree arg0 = strip_float_extensions (arg);
6825 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6826 tree newtype = TREE_TYPE (arg0);
6827 tree decl;
6828
6829 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6830 && (decl = mathfn_built_in (newtype, fcode)))
6831 {
6832 arglist =
6833 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6834 return fold_convert (ftype,
6835 build_function_call_expr (decl, arglist));
6836 }
6837 }
6838 return 0;
6839 }
6840
6841 /* EXP is assumed to be builtin call which can narrow the FP type of
6842 the argument, for instance lround((double)f) -> lroundf (f). */
6843
6844 static tree
6845 fold_fixed_mathfn (tree fndecl, tree arglist)
6846 {
6847 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6848 tree arg;
6849
6850 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6851 return 0;
6852
6853 arg = TREE_VALUE (arglist);
6854
6855 /* If argument is already integer valued, and we don't need to worry
6856 about setting errno, there's no need to perform rounding. */
6857 if (! flag_errno_math && integer_valued_real_p (arg))
6858 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6859
6860 if (optimize)
6861 {
6862 tree ftype = TREE_TYPE (arg);
6863 tree arg0 = strip_float_extensions (arg);
6864 tree newtype = TREE_TYPE (arg0);
6865 tree decl;
6866
6867 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6868 && (decl = mathfn_built_in (newtype, fcode)))
6869 {
6870 arglist =
6871 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6872 return build_function_call_expr (decl, arglist);
6873 }
6874 }
6875
6876 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6877 sizeof (long long) == sizeof (long). */
6878 if (TYPE_PRECISION (long_long_integer_type_node)
6879 == TYPE_PRECISION (long_integer_type_node))
6880 {
6881 tree newfn = NULL_TREE;
6882 switch (fcode)
6883 {
6884 CASE_FLT_FN (BUILT_IN_LLCEIL):
6885 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6886 break;
6887
6888 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6889 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6890 break;
6891
6892 CASE_FLT_FN (BUILT_IN_LLROUND):
6893 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6894 break;
6895
6896 CASE_FLT_FN (BUILT_IN_LLRINT):
6897 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6898 break;
6899
6900 default:
6901 break;
6902 }
6903
6904 if (newfn)
6905 {
6906 tree newcall = build_function_call_expr (newfn, arglist);
6907 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6908 }
6909 }
6910
6911 return 0;
6912 }
6913
6914 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6915 is the argument list, TYPE is the return type and FNDECL is the
6916 original function DECL. Return NULL_TREE if no if no simplification
6917 can be made. */
6918
6919 static tree
6920 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6921 {
6922 tree arg;
6923
6924 if (!arglist || TREE_CHAIN (arglist))
6925 return NULL_TREE;
6926
6927 arg = TREE_VALUE (arglist);
6928 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6929 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6930 return NULL_TREE;
6931
6932 /* Evaluate cabs of a constant at compile-time. */
6933 if (flag_unsafe_math_optimizations
6934 && TREE_CODE (arg) == COMPLEX_CST
6935 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6936 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6937 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6938 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6939 {
6940 REAL_VALUE_TYPE r, i;
6941
6942 r = TREE_REAL_CST (TREE_REALPART (arg));
6943 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6944
6945 real_arithmetic (&r, MULT_EXPR, &r, &r);
6946 real_arithmetic (&i, MULT_EXPR, &i, &i);
6947 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6948 if (real_sqrt (&r, TYPE_MODE (type), &r)
6949 || ! flag_trapping_math)
6950 return build_real (type, r);
6951 }
6952
6953 /* If either part is zero, cabs is fabs of the other. */
6954 if (TREE_CODE (arg) == COMPLEX_EXPR
6955 && real_zerop (TREE_OPERAND (arg, 0)))
6956 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6957 if (TREE_CODE (arg) == COMPLEX_EXPR
6958 && real_zerop (TREE_OPERAND (arg, 1)))
6959 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6960
6961 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6962 if (TREE_CODE (arg) == NEGATE_EXPR
6963 || TREE_CODE (arg) == CONJ_EXPR)
6964 {
6965 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6966 return build_function_call_expr (fndecl, arglist);
6967 }
6968
6969 /* Don't do this when optimizing for size. */
6970 if (flag_unsafe_math_optimizations
6971 && optimize && !optimize_size)
6972 {
6973 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6974
6975 if (sqrtfn != NULL_TREE)
6976 {
6977 tree rpart, ipart, result, arglist;
6978
6979 arg = builtin_save_expr (arg);
6980
6981 rpart = fold_build1 (REALPART_EXPR, type, arg);
6982 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6983
6984 rpart = builtin_save_expr (rpart);
6985 ipart = builtin_save_expr (ipart);
6986
6987 result = fold_build2 (PLUS_EXPR, type,
6988 fold_build2 (MULT_EXPR, type,
6989 rpart, rpart),
6990 fold_build2 (MULT_EXPR, type,
6991 ipart, ipart));
6992
6993 arglist = build_tree_list (NULL_TREE, result);
6994 return build_function_call_expr (sqrtfn, arglist);
6995 }
6996 }
6997
6998 return NULL_TREE;
6999 }
7000
7001 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7002 NULL_TREE if no simplification can be made. */
7003
7004 static tree
7005 fold_builtin_sqrt (tree arglist, tree type)
7006 {
7007
7008 enum built_in_function fcode;
7009 tree arg = TREE_VALUE (arglist);
7010
7011 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7012 return NULL_TREE;
7013
7014 /* Optimize sqrt of constant value. */
7015 if (TREE_CODE (arg) == REAL_CST
7016 && ! TREE_CONSTANT_OVERFLOW (arg))
7017 {
7018 REAL_VALUE_TYPE r, x;
7019
7020 x = TREE_REAL_CST (arg);
7021 if (real_sqrt (&r, TYPE_MODE (type), &x)
7022 || (!flag_trapping_math && !flag_errno_math))
7023 return build_real (type, r);
7024 }
7025
7026 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7027 fcode = builtin_mathfn_code (arg);
7028 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7029 {
7030 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7031 arg = fold_build2 (MULT_EXPR, type,
7032 TREE_VALUE (TREE_OPERAND (arg, 1)),
7033 build_real (type, dconsthalf));
7034 arglist = build_tree_list (NULL_TREE, arg);
7035 return build_function_call_expr (expfn, arglist);
7036 }
7037
7038 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7039 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7040 {
7041 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7042
7043 if (powfn)
7044 {
7045 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7046 tree tree_root;
7047 /* The inner root was either sqrt or cbrt. */
7048 REAL_VALUE_TYPE dconstroot =
7049 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7050
7051 /* Adjust for the outer root. */
7052 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7053 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7054 tree_root = build_real (type, dconstroot);
7055 arglist = tree_cons (NULL_TREE, arg0,
7056 build_tree_list (NULL_TREE, tree_root));
7057 return build_function_call_expr (powfn, arglist);
7058 }
7059 }
7060
7061 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7062 if (flag_unsafe_math_optimizations
7063 && (fcode == BUILT_IN_POW
7064 || fcode == BUILT_IN_POWF
7065 || fcode == BUILT_IN_POWL))
7066 {
7067 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7068 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7069 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7070 tree narg1;
7071 if (!tree_expr_nonnegative_p (arg0))
7072 arg0 = build1 (ABS_EXPR, type, arg0);
7073 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7074 build_real (type, dconsthalf));
7075 arglist = tree_cons (NULL_TREE, arg0,
7076 build_tree_list (NULL_TREE, narg1));
7077 return build_function_call_expr (powfn, arglist);
7078 }
7079
7080 return NULL_TREE;
7081 }
7082
7083 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7084 NULL_TREE if no simplification can be made. */
7085 static tree
7086 fold_builtin_cbrt (tree arglist, tree type)
7087 {
7088 tree arg = TREE_VALUE (arglist);
7089 const enum built_in_function fcode = builtin_mathfn_code (arg);
7090 tree res;
7091
7092 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7093 return NULL_TREE;
7094
7095 /* Calculate the result when the argument is a constant. */
7096 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7097 return res;
7098
7099 if (flag_unsafe_math_optimizations)
7100 {
7101 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7102 if (BUILTIN_EXPONENT_P (fcode))
7103 {
7104 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7105 const REAL_VALUE_TYPE third_trunc =
7106 real_value_truncate (TYPE_MODE (type), dconstthird);
7107 arg = fold_build2 (MULT_EXPR, type,
7108 TREE_VALUE (TREE_OPERAND (arg, 1)),
7109 build_real (type, third_trunc));
7110 arglist = build_tree_list (NULL_TREE, arg);
7111 return build_function_call_expr (expfn, arglist);
7112 }
7113
7114 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7115 if (BUILTIN_SQRT_P (fcode))
7116 {
7117 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7118
7119 if (powfn)
7120 {
7121 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7122 tree tree_root;
7123 REAL_VALUE_TYPE dconstroot = dconstthird;
7124
7125 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7126 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7127 tree_root = build_real (type, dconstroot);
7128 arglist = tree_cons (NULL_TREE, arg0,
7129 build_tree_list (NULL_TREE, tree_root));
7130 return build_function_call_expr (powfn, arglist);
7131 }
7132 }
7133
7134 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7135 if (BUILTIN_CBRT_P (fcode))
7136 {
7137 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7138 if (tree_expr_nonnegative_p (arg0))
7139 {
7140 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7141
7142 if (powfn)
7143 {
7144 tree tree_root;
7145 REAL_VALUE_TYPE dconstroot;
7146
7147 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7148 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7149 tree_root = build_real (type, dconstroot);
7150 arglist = tree_cons (NULL_TREE, arg0,
7151 build_tree_list (NULL_TREE, tree_root));
7152 return build_function_call_expr (powfn, arglist);
7153 }
7154 }
7155 }
7156
7157 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7158 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7159 || fcode == BUILT_IN_POWL)
7160 {
7161 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7162 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7163 if (tree_expr_nonnegative_p (arg00))
7164 {
7165 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7166 const REAL_VALUE_TYPE dconstroot
7167 = real_value_truncate (TYPE_MODE (type), dconstthird);
7168 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7169 build_real (type, dconstroot));
7170 arglist = tree_cons (NULL_TREE, arg00,
7171 build_tree_list (NULL_TREE, narg01));
7172 return build_function_call_expr (powfn, arglist);
7173 }
7174 }
7175 }
7176 return NULL_TREE;
7177 }
7178
7179 /* Fold function call to builtin cos, cosf, or cosl. Return
7180 NULL_TREE if no simplification can be made. */
7181 static tree
7182 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7183 {
7184 tree arg = TREE_VALUE (arglist);
7185 tree res, narg;
7186
7187 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7188 return NULL_TREE;
7189
7190 /* Calculate the result when the argument is a constant. */
7191 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7192 return res;
7193
7194 /* Optimize cos(-x) into cos (x). */
7195 if ((narg = fold_strip_sign_ops (arg)))
7196 return build_function_call_expr (fndecl,
7197 build_tree_list (NULL_TREE, narg));
7198
7199 return NULL_TREE;
7200 }
7201
7202 /* Fold function call to builtin cosh, coshf, or coshl. Return
7203 NULL_TREE if no simplification can be made. */
7204 static tree
7205 fold_builtin_cosh (tree arglist, tree type, tree fndecl)
7206 {
7207 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7208 {
7209 tree arg = TREE_VALUE (arglist);
7210 tree res, narg;
7211
7212 /* Calculate the result when the argument is a constant. */
7213 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7214 return res;
7215
7216 /* Optimize cosh(-x) into cosh (x). */
7217 if ((narg = fold_strip_sign_ops (arg)))
7218 return build_function_call_expr (fndecl,
7219 build_tree_list (NULL_TREE, narg));
7220 }
7221
7222 return NULL_TREE;
7223 }
7224
7225 /* Fold function call to builtin tan, tanf, or tanl. Return
7226 NULL_TREE if no simplification can be made. */
7227 static tree
7228 fold_builtin_tan (tree arglist, tree type)
7229 {
7230 enum built_in_function fcode;
7231 tree arg = TREE_VALUE (arglist);
7232 tree res;
7233
7234 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7235 return NULL_TREE;
7236
7237 /* Calculate the result when the argument is a constant. */
7238 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7239 return res;
7240
7241 /* Optimize tan(atan(x)) = x. */
7242 fcode = builtin_mathfn_code (arg);
7243 if (flag_unsafe_math_optimizations
7244 && (fcode == BUILT_IN_ATAN
7245 || fcode == BUILT_IN_ATANF
7246 || fcode == BUILT_IN_ATANL))
7247 return TREE_VALUE (TREE_OPERAND (arg, 1));
7248
7249 return NULL_TREE;
7250 }
7251
7252 /* Fold function call to builtin trunc, truncf or truncl. Return
7253 NULL_TREE if no simplification can be made. */
7254
7255 static tree
7256 fold_builtin_trunc (tree fndecl, tree arglist)
7257 {
7258 tree arg;
7259
7260 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7261 return 0;
7262
7263 /* Optimize trunc of constant value. */
7264 arg = TREE_VALUE (arglist);
7265 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7266 {
7267 REAL_VALUE_TYPE r, x;
7268 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7269
7270 x = TREE_REAL_CST (arg);
7271 real_trunc (&r, TYPE_MODE (type), &x);
7272 return build_real (type, r);
7273 }
7274
7275 return fold_trunc_transparent_mathfn (fndecl, arglist);
7276 }
7277
7278 /* Fold function call to builtin floor, floorf or floorl. Return
7279 NULL_TREE if no simplification can be made. */
7280
7281 static tree
7282 fold_builtin_floor (tree fndecl, tree arglist)
7283 {
7284 tree arg;
7285
7286 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7287 return 0;
7288
7289 /* Optimize floor of constant value. */
7290 arg = TREE_VALUE (arglist);
7291 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7292 {
7293 REAL_VALUE_TYPE x;
7294
7295 x = TREE_REAL_CST (arg);
7296 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7297 {
7298 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7299 REAL_VALUE_TYPE r;
7300
7301 real_floor (&r, TYPE_MODE (type), &x);
7302 return build_real (type, r);
7303 }
7304 }
7305
7306 /* Fold floor (x) where x is nonnegative to trunc (x). */
7307 if (tree_expr_nonnegative_p (arg))
7308 {
7309 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7310 if (truncfn)
7311 return build_function_call_expr (truncfn, arglist);
7312 }
7313
7314 return fold_trunc_transparent_mathfn (fndecl, arglist);
7315 }
7316
7317 /* Fold function call to builtin ceil, ceilf or ceill. Return
7318 NULL_TREE if no simplification can be made. */
7319
7320 static tree
7321 fold_builtin_ceil (tree fndecl, tree arglist)
7322 {
7323 tree arg;
7324
7325 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7326 return 0;
7327
7328 /* Optimize ceil of constant value. */
7329 arg = TREE_VALUE (arglist);
7330 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7331 {
7332 REAL_VALUE_TYPE x;
7333
7334 x = TREE_REAL_CST (arg);
7335 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7336 {
7337 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7338 REAL_VALUE_TYPE r;
7339
7340 real_ceil (&r, TYPE_MODE (type), &x);
7341 return build_real (type, r);
7342 }
7343 }
7344
7345 return fold_trunc_transparent_mathfn (fndecl, arglist);
7346 }
7347
7348 /* Fold function call to builtin round, roundf or roundl. Return
7349 NULL_TREE if no simplification can be made. */
7350
7351 static tree
7352 fold_builtin_round (tree fndecl, tree arglist)
7353 {
7354 tree arg;
7355
7356 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7357 return 0;
7358
7359 /* Optimize round of constant value. */
7360 arg = TREE_VALUE (arglist);
7361 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7362 {
7363 REAL_VALUE_TYPE x;
7364
7365 x = TREE_REAL_CST (arg);
7366 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7367 {
7368 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7369 REAL_VALUE_TYPE r;
7370
7371 real_round (&r, TYPE_MODE (type), &x);
7372 return build_real (type, r);
7373 }
7374 }
7375
7376 return fold_trunc_transparent_mathfn (fndecl, arglist);
7377 }
7378
7379 /* Fold function call to builtin lround, lroundf or lroundl (or the
7380 corresponding long long versions) and other rounding functions.
7381 Return NULL_TREE if no simplification can be made. */
7382
7383 static tree
7384 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7385 {
7386 tree arg;
7387
7388 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7389 return 0;
7390
7391 /* Optimize lround of constant value. */
7392 arg = TREE_VALUE (arglist);
7393 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7394 {
7395 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7396
7397 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7398 {
7399 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7400 tree ftype = TREE_TYPE (arg), result;
7401 HOST_WIDE_INT hi, lo;
7402 REAL_VALUE_TYPE r;
7403
7404 switch (DECL_FUNCTION_CODE (fndecl))
7405 {
7406 CASE_FLT_FN (BUILT_IN_LFLOOR):
7407 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7408 real_floor (&r, TYPE_MODE (ftype), &x);
7409 break;
7410
7411 CASE_FLT_FN (BUILT_IN_LCEIL):
7412 CASE_FLT_FN (BUILT_IN_LLCEIL):
7413 real_ceil (&r, TYPE_MODE (ftype), &x);
7414 break;
7415
7416 CASE_FLT_FN (BUILT_IN_LROUND):
7417 CASE_FLT_FN (BUILT_IN_LLROUND):
7418 real_round (&r, TYPE_MODE (ftype), &x);
7419 break;
7420
7421 default:
7422 gcc_unreachable ();
7423 }
7424
7425 REAL_VALUE_TO_INT (&lo, &hi, r);
7426 result = build_int_cst_wide (NULL_TREE, lo, hi);
7427 if (int_fits_type_p (result, itype))
7428 return fold_convert (itype, result);
7429 }
7430 }
7431
7432 switch (DECL_FUNCTION_CODE (fndecl))
7433 {
7434 CASE_FLT_FN (BUILT_IN_LFLOOR):
7435 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7436 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7437 if (tree_expr_nonnegative_p (arg))
7438 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7439 arg);
7440 break;
7441 default:;
7442 }
7443
7444 return fold_fixed_mathfn (fndecl, arglist);
7445 }
7446
7447 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7448 and their long and long long variants (i.e. ffsl and ffsll).
7449 Return NULL_TREE if no simplification can be made. */
7450
7451 static tree
7452 fold_builtin_bitop (tree fndecl, tree arglist)
7453 {
7454 tree arg;
7455
7456 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7457 return NULL_TREE;
7458
7459 /* Optimize for constant argument. */
7460 arg = TREE_VALUE (arglist);
7461 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7462 {
7463 HOST_WIDE_INT hi, width, result;
7464 unsigned HOST_WIDE_INT lo;
7465 tree type;
7466
7467 type = TREE_TYPE (arg);
7468 width = TYPE_PRECISION (type);
7469 lo = TREE_INT_CST_LOW (arg);
7470
7471 /* Clear all the bits that are beyond the type's precision. */
7472 if (width > HOST_BITS_PER_WIDE_INT)
7473 {
7474 hi = TREE_INT_CST_HIGH (arg);
7475 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7476 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7477 }
7478 else
7479 {
7480 hi = 0;
7481 if (width < HOST_BITS_PER_WIDE_INT)
7482 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7483 }
7484
7485 switch (DECL_FUNCTION_CODE (fndecl))
7486 {
7487 CASE_INT_FN (BUILT_IN_FFS):
7488 if (lo != 0)
7489 result = exact_log2 (lo & -lo) + 1;
7490 else if (hi != 0)
7491 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7492 else
7493 result = 0;
7494 break;
7495
7496 CASE_INT_FN (BUILT_IN_CLZ):
7497 if (hi != 0)
7498 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7499 else if (lo != 0)
7500 result = width - floor_log2 (lo) - 1;
7501 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7502 result = width;
7503 break;
7504
7505 CASE_INT_FN (BUILT_IN_CTZ):
7506 if (lo != 0)
7507 result = exact_log2 (lo & -lo);
7508 else if (hi != 0)
7509 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7510 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7511 result = width;
7512 break;
7513
7514 CASE_INT_FN (BUILT_IN_POPCOUNT):
7515 result = 0;
7516 while (lo)
7517 result++, lo &= lo - 1;
7518 while (hi)
7519 result++, hi &= hi - 1;
7520 break;
7521
7522 CASE_INT_FN (BUILT_IN_PARITY):
7523 result = 0;
7524 while (lo)
7525 result++, lo &= lo - 1;
7526 while (hi)
7527 result++, hi &= hi - 1;
7528 result &= 1;
7529 break;
7530
7531 default:
7532 gcc_unreachable ();
7533 }
7534
7535 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7536 }
7537
7538 return NULL_TREE;
7539 }
7540
7541 /* Fold function call to builtin_bswap and the long and long long
7542 variants. Return NULL_TREE if no simplification can be made. */
7543 static tree
7544 fold_builtin_bswap (tree fndecl, tree arglist)
7545 {
7546 tree arg;
7547
7548 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7549 return 0;
7550
7551 /* Optimize constant value. */
7552 arg = TREE_VALUE (arglist);
7553 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7554 {
7555 HOST_WIDE_INT hi, width, r_hi = 0;
7556 unsigned HOST_WIDE_INT lo, r_lo = 0;
7557 tree type;
7558
7559 type = TREE_TYPE (arg);
7560 width = TYPE_PRECISION (type);
7561 lo = TREE_INT_CST_LOW (arg);
7562 hi = TREE_INT_CST_HIGH (arg);
7563
7564 switch (DECL_FUNCTION_CODE (fndecl))
7565 {
7566 case BUILT_IN_BSWAP32:
7567 case BUILT_IN_BSWAP64:
7568 {
7569 int s;
7570
7571 for (s = 0; s < width; s += 8)
7572 {
7573 int d = width - s - 8;
7574 unsigned HOST_WIDE_INT byte;
7575
7576 if (s < HOST_BITS_PER_WIDE_INT)
7577 byte = (lo >> s) & 0xff;
7578 else
7579 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7580
7581 if (d < HOST_BITS_PER_WIDE_INT)
7582 r_lo |= byte << d;
7583 else
7584 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7585 }
7586 }
7587
7588 break;
7589
7590 default:
7591 gcc_unreachable ();
7592 }
7593
7594 if (width < HOST_BITS_PER_WIDE_INT)
7595 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7596 else
7597 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7598 }
7599
7600 return NULL_TREE;
7601 }
7602 /* Return true if EXPR is the real constant contained in VALUE. */
7603
7604 static bool
7605 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7606 {
7607 STRIP_NOPS (expr);
7608
7609 return ((TREE_CODE (expr) == REAL_CST
7610 && ! TREE_CONSTANT_OVERFLOW (expr)
7611 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7612 || (TREE_CODE (expr) == COMPLEX_CST
7613 && real_dconstp (TREE_REALPART (expr), value)
7614 && real_zerop (TREE_IMAGPART (expr))));
7615 }
7616
7617 /* A subroutine of fold_builtin to fold the various logarithmic
7618 functions. Return NULL_TREE if no simplification can me made.
7619 FUNC is the corresponding MPFR logarithm function. */
7620
7621 static tree
7622 fold_builtin_logarithm (tree fndecl, tree arglist,
7623 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7624 {
7625 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7626 {
7627 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7628 tree arg = TREE_VALUE (arglist);
7629 tree res;
7630 const enum built_in_function fcode = builtin_mathfn_code (arg);
7631
7632 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7633 instead we'll look for 'e' truncated to MODE. So only do
7634 this if flag_unsafe_math_optimizations is set. */
7635 if (flag_unsafe_math_optimizations && func == mpfr_log)
7636 {
7637 const REAL_VALUE_TYPE e_truncated =
7638 real_value_truncate (TYPE_MODE (type), dconste);
7639 if (real_dconstp (arg, &e_truncated))
7640 return build_real (type, dconst1);
7641 }
7642
7643 /* Calculate the result when the argument is a constant. */
7644 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7645 return res;
7646
7647 /* Special case, optimize logN(expN(x)) = x. */
7648 if (flag_unsafe_math_optimizations
7649 && ((func == mpfr_log
7650 && (fcode == BUILT_IN_EXP
7651 || fcode == BUILT_IN_EXPF
7652 || fcode == BUILT_IN_EXPL))
7653 || (func == mpfr_log2
7654 && (fcode == BUILT_IN_EXP2
7655 || fcode == BUILT_IN_EXP2F
7656 || fcode == BUILT_IN_EXP2L))
7657 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7658 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7659
7660 /* Optimize logN(func()) for various exponential functions. We
7661 want to determine the value "x" and the power "exponent" in
7662 order to transform logN(x**exponent) into exponent*logN(x). */
7663 if (flag_unsafe_math_optimizations)
7664 {
7665 tree exponent = 0, x = 0;
7666
7667 switch (fcode)
7668 {
7669 CASE_FLT_FN (BUILT_IN_EXP):
7670 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7671 x = build_real (type,
7672 real_value_truncate (TYPE_MODE (type), dconste));
7673 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7674 break;
7675 CASE_FLT_FN (BUILT_IN_EXP2):
7676 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7677 x = build_real (type, dconst2);
7678 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7679 break;
7680 CASE_FLT_FN (BUILT_IN_EXP10):
7681 CASE_FLT_FN (BUILT_IN_POW10):
7682 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7683 x = build_real (type, dconst10);
7684 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7685 break;
7686 CASE_FLT_FN (BUILT_IN_SQRT):
7687 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7688 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7689 exponent = build_real (type, dconsthalf);
7690 break;
7691 CASE_FLT_FN (BUILT_IN_CBRT):
7692 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7693 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7694 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7695 dconstthird));
7696 break;
7697 CASE_FLT_FN (BUILT_IN_POW):
7698 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7699 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7700 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7701 break;
7702 default:
7703 break;
7704 }
7705
7706 /* Now perform the optimization. */
7707 if (x && exponent)
7708 {
7709 tree logfn;
7710 arglist = build_tree_list (NULL_TREE, x);
7711 logfn = build_function_call_expr (fndecl, arglist);
7712 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7713 }
7714 }
7715 }
7716
7717 return 0;
7718 }
7719
7720 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
7721 NULL_TREE if no simplification can be made. */
7722
7723 static tree
7724 fold_builtin_hypot (tree fndecl, tree arglist, tree type)
7725 {
7726 tree arg0 = TREE_VALUE (arglist);
7727 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7728 tree res, narg0, narg1;
7729
7730 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7731 return NULL_TREE;
7732
7733 /* Calculate the result when the argument is a constant. */
7734 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
7735 return res;
7736
7737 /* If either argument to hypot has a negate or abs, strip that off.
7738 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
7739 narg0 = fold_strip_sign_ops (arg0);
7740 narg1 = fold_strip_sign_ops (arg1);
7741 if (narg0 || narg1)
7742 {
7743 tree narglist = tree_cons (NULL_TREE, narg0 ? narg0 : arg0,
7744 build_tree_list (NULL_TREE,
7745 narg1 ? narg1 : arg1));
7746 return build_function_call_expr (fndecl, narglist);
7747 }
7748
7749 /* If either argument is zero, hypot is fabs of the other. */
7750 if (real_zerop (arg0))
7751 return fold_build1 (ABS_EXPR, type, arg1);
7752 else if (real_zerop (arg1))
7753 return fold_build1 (ABS_EXPR, type, arg0);
7754
7755 /* hypot(x,x) -> fabs(x)*sqrt(2). */
7756 if (flag_unsafe_math_optimizations
7757 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
7758 {
7759 REAL_VALUE_TYPE sqrt2;
7760
7761 real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
7762 return fold_build2 (MULT_EXPR, type,
7763 fold_build1 (ABS_EXPR, type, arg0),
7764 build_real (type, sqrt2));
7765 }
7766
7767 return NULL_TREE;
7768 }
7769
7770
7771 /* Fold a builtin function call to pow, powf, or powl. Return
7772 NULL_TREE if no simplification can be made. */
7773 static tree
7774 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7775 {
7776 tree arg0 = TREE_VALUE (arglist);
7777 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7778 tree res;
7779
7780 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7781 return NULL_TREE;
7782
7783 /* Calculate the result when the argument is a constant. */
7784 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
7785 return res;
7786
7787 /* Optimize pow(1.0,y) = 1.0. */
7788 if (real_onep (arg0))
7789 return omit_one_operand (type, build_real (type, dconst1), arg1);
7790
7791 if (TREE_CODE (arg1) == REAL_CST
7792 && ! TREE_CONSTANT_OVERFLOW (arg1))
7793 {
7794 REAL_VALUE_TYPE cint;
7795 REAL_VALUE_TYPE c;
7796 HOST_WIDE_INT n;
7797
7798 c = TREE_REAL_CST (arg1);
7799
7800 /* Optimize pow(x,0.0) = 1.0. */
7801 if (REAL_VALUES_EQUAL (c, dconst0))
7802 return omit_one_operand (type, build_real (type, dconst1),
7803 arg0);
7804
7805 /* Optimize pow(x,1.0) = x. */
7806 if (REAL_VALUES_EQUAL (c, dconst1))
7807 return arg0;
7808
7809 /* Optimize pow(x,-1.0) = 1.0/x. */
7810 if (REAL_VALUES_EQUAL (c, dconstm1))
7811 return fold_build2 (RDIV_EXPR, type,
7812 build_real (type, dconst1), arg0);
7813
7814 /* Optimize pow(x,0.5) = sqrt(x). */
7815 if (flag_unsafe_math_optimizations
7816 && REAL_VALUES_EQUAL (c, dconsthalf))
7817 {
7818 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7819
7820 if (sqrtfn != NULL_TREE)
7821 {
7822 tree arglist = build_tree_list (NULL_TREE, arg0);
7823 return build_function_call_expr (sqrtfn, arglist);
7824 }
7825 }
7826
7827 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
7828 if (flag_unsafe_math_optimizations)
7829 {
7830 const REAL_VALUE_TYPE dconstroot
7831 = real_value_truncate (TYPE_MODE (type), dconstthird);
7832
7833 if (REAL_VALUES_EQUAL (c, dconstroot))
7834 {
7835 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
7836 if (cbrtfn != NULL_TREE)
7837 {
7838 tree arglist = build_tree_list (NULL_TREE, arg0);
7839 return build_function_call_expr (cbrtfn, arglist);
7840 }
7841 }
7842 }
7843
7844 /* Check for an integer exponent. */
7845 n = real_to_integer (&c);
7846 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7847 if (real_identical (&c, &cint))
7848 {
7849 /* Attempt to evaluate pow at compile-time. */
7850 if (TREE_CODE (arg0) == REAL_CST
7851 && ! TREE_CONSTANT_OVERFLOW (arg0))
7852 {
7853 REAL_VALUE_TYPE x;
7854 bool inexact;
7855
7856 x = TREE_REAL_CST (arg0);
7857 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7858 if (flag_unsafe_math_optimizations || !inexact)
7859 return build_real (type, x);
7860 }
7861
7862 /* Strip sign ops from even integer powers. */
7863 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7864 {
7865 tree narg0 = fold_strip_sign_ops (arg0);
7866 if (narg0)
7867 {
7868 arglist = build_tree_list (NULL_TREE, arg1);
7869 arglist = tree_cons (NULL_TREE, narg0, arglist);
7870 return build_function_call_expr (fndecl, arglist);
7871 }
7872 }
7873 }
7874 }
7875
7876 if (flag_unsafe_math_optimizations)
7877 {
7878 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7879
7880 /* Optimize pow(expN(x),y) = expN(x*y). */
7881 if (BUILTIN_EXPONENT_P (fcode))
7882 {
7883 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7884 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7885 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7886 arglist = build_tree_list (NULL_TREE, arg);
7887 return build_function_call_expr (expfn, arglist);
7888 }
7889
7890 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7891 if (BUILTIN_SQRT_P (fcode))
7892 {
7893 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7894 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7895 build_real (type, dconsthalf));
7896
7897 arglist = tree_cons (NULL_TREE, narg0,
7898 build_tree_list (NULL_TREE, narg1));
7899 return build_function_call_expr (fndecl, arglist);
7900 }
7901
7902 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7903 if (BUILTIN_CBRT_P (fcode))
7904 {
7905 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7906 if (tree_expr_nonnegative_p (arg))
7907 {
7908 const REAL_VALUE_TYPE dconstroot
7909 = real_value_truncate (TYPE_MODE (type), dconstthird);
7910 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7911 build_real (type, dconstroot));
7912 arglist = tree_cons (NULL_TREE, arg,
7913 build_tree_list (NULL_TREE, narg1));
7914 return build_function_call_expr (fndecl, arglist);
7915 }
7916 }
7917
7918 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7919 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7920 || fcode == BUILT_IN_POWL)
7921 {
7922 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7923 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7924 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7925 arglist = tree_cons (NULL_TREE, arg00,
7926 build_tree_list (NULL_TREE, narg1));
7927 return build_function_call_expr (fndecl, arglist);
7928 }
7929 }
7930
7931 return NULL_TREE;
7932 }
7933
7934 /* Fold a builtin function call to powi, powif, or powil. Return
7935 NULL_TREE if no simplification can be made. */
7936 static tree
7937 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7938 {
7939 tree arg0 = TREE_VALUE (arglist);
7940 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7941
7942 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7943 return NULL_TREE;
7944
7945 /* Optimize pow(1.0,y) = 1.0. */
7946 if (real_onep (arg0))
7947 return omit_one_operand (type, build_real (type, dconst1), arg1);
7948
7949 if (host_integerp (arg1, 0))
7950 {
7951 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7952
7953 /* Evaluate powi at compile-time. */
7954 if (TREE_CODE (arg0) == REAL_CST
7955 && ! TREE_CONSTANT_OVERFLOW (arg0))
7956 {
7957 REAL_VALUE_TYPE x;
7958 x = TREE_REAL_CST (arg0);
7959 real_powi (&x, TYPE_MODE (type), &x, c);
7960 return build_real (type, x);
7961 }
7962
7963 /* Optimize pow(x,0) = 1.0. */
7964 if (c == 0)
7965 return omit_one_operand (type, build_real (type, dconst1),
7966 arg0);
7967
7968 /* Optimize pow(x,1) = x. */
7969 if (c == 1)
7970 return arg0;
7971
7972 /* Optimize pow(x,-1) = 1.0/x. */
7973 if (c == -1)
7974 return fold_build2 (RDIV_EXPR, type,
7975 build_real (type, dconst1), arg0);
7976 }
7977
7978 return NULL_TREE;
7979 }
7980
7981 /* A subroutine of fold_builtin to fold the various exponent
7982 functions. Return NULL_TREE if no simplification can me made.
7983 FUNC is the corresponding MPFR exponent function. */
7984
7985 static tree
7986 fold_builtin_exponent (tree fndecl, tree arglist,
7987 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7988 {
7989 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7990 {
7991 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7992 tree arg = TREE_VALUE (arglist);
7993 tree res;
7994
7995 /* Calculate the result when the argument is a constant. */
7996 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
7997 return res;
7998
7999 /* Optimize expN(logN(x)) = x. */
8000 if (flag_unsafe_math_optimizations)
8001 {
8002 const enum built_in_function fcode = builtin_mathfn_code (arg);
8003
8004 if ((func == mpfr_exp
8005 && (fcode == BUILT_IN_LOG
8006 || fcode == BUILT_IN_LOGF
8007 || fcode == BUILT_IN_LOGL))
8008 || (func == mpfr_exp2
8009 && (fcode == BUILT_IN_LOG2
8010 || fcode == BUILT_IN_LOG2F
8011 || fcode == BUILT_IN_LOG2L))
8012 || (func == mpfr_exp10
8013 && (fcode == BUILT_IN_LOG10
8014 || fcode == BUILT_IN_LOG10F
8015 || fcode == BUILT_IN_LOG10L)))
8016 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8017 }
8018 }
8019
8020 return 0;
8021 }
8022
8023 /* Return true if VAR is a VAR_DECL or a component thereof. */
8024
8025 static bool
8026 var_decl_component_p (tree var)
8027 {
8028 tree inner = var;
8029 while (handled_component_p (inner))
8030 inner = TREE_OPERAND (inner, 0);
8031 return SSA_VAR_P (inner);
8032 }
8033
8034 /* Fold function call to builtin memset. Return
8035 NULL_TREE if no simplification can be made. */
8036
8037 static tree
8038 fold_builtin_memset (tree arglist, tree type, bool ignore)
8039 {
8040 tree dest, c, len, var, ret;
8041 unsigned HOST_WIDE_INT length, cval;
8042
8043 if (!validate_arglist (arglist,
8044 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8045 return 0;
8046
8047 dest = TREE_VALUE (arglist);
8048 c = TREE_VALUE (TREE_CHAIN (arglist));
8049 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8050
8051 if (! host_integerp (len, 1))
8052 return 0;
8053
8054 /* If the LEN parameter is zero, return DEST. */
8055 if (integer_zerop (len))
8056 return omit_one_operand (type, dest, c);
8057
8058 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8059 return 0;
8060
8061 var = dest;
8062 STRIP_NOPS (var);
8063 if (TREE_CODE (var) != ADDR_EXPR)
8064 return 0;
8065
8066 var = TREE_OPERAND (var, 0);
8067 if (TREE_THIS_VOLATILE (var))
8068 return 0;
8069
8070 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8071 && !POINTER_TYPE_P (TREE_TYPE (var)))
8072 return 0;
8073
8074 if (! var_decl_component_p (var))
8075 return 0;
8076
8077 length = tree_low_cst (len, 1);
8078 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8079 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8080 < (int) length)
8081 return 0;
8082
8083 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8084 return 0;
8085
8086 if (integer_zerop (c))
8087 cval = 0;
8088 else
8089 {
8090 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8091 return 0;
8092
8093 cval = tree_low_cst (c, 1);
8094 cval &= 0xff;
8095 cval |= cval << 8;
8096 cval |= cval << 16;
8097 cval |= (cval << 31) << 1;
8098 }
8099
8100 ret = build_int_cst_type (TREE_TYPE (var), cval);
8101 ret = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (var), var, ret);
8102 if (ignore)
8103 return ret;
8104
8105 return omit_one_operand (type, dest, ret);
8106 }
8107
8108 /* Fold function call to builtin memset. Return
8109 NULL_TREE if no simplification can be made. */
8110
8111 static tree
8112 fold_builtin_bzero (tree arglist, bool ignore)
8113 {
8114 tree dest, size, newarglist;
8115
8116 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8117 return 0;
8118
8119 if (!ignore)
8120 return 0;
8121
8122 dest = TREE_VALUE (arglist);
8123 size = TREE_VALUE (TREE_CHAIN (arglist));
8124
8125 /* New argument list transforming bzero(ptr x, int y) to
8126 memset(ptr x, int 0, size_t y). This is done this way
8127 so that if it isn't expanded inline, we fallback to
8128 calling bzero instead of memset. */
8129
8130 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8131 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8132 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8133 return fold_builtin_memset (newarglist, void_type_node, ignore);
8134 }
8135
8136 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8137 NULL_TREE if no simplification can be made.
8138 If ENDP is 0, return DEST (like memcpy).
8139 If ENDP is 1, return DEST+LEN (like mempcpy).
8140 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8141 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8142 (memmove). */
8143
8144 static tree
8145 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8146 {
8147 tree dest, src, len, destvar, srcvar, expr;
8148
8149 if (! validate_arglist (arglist,
8150 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8151 return 0;
8152
8153 dest = TREE_VALUE (arglist);
8154 src = TREE_VALUE (TREE_CHAIN (arglist));
8155 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8156
8157 /* If the LEN parameter is zero, return DEST. */
8158 if (integer_zerop (len))
8159 return omit_one_operand (type, dest, src);
8160
8161 /* If SRC and DEST are the same (and not volatile), return
8162 DEST{,+LEN,+LEN-1}. */
8163 if (operand_equal_p (src, dest, 0))
8164 expr = len;
8165 else
8166 {
8167 tree srctype, desttype;
8168 if (endp == 3)
8169 {
8170 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8171 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8172
8173 /* Both DEST and SRC must be pointer types.
8174 ??? This is what old code did. Is the testing for pointer types
8175 really mandatory?
8176
8177 If either SRC is readonly or length is 1, we can use memcpy. */
8178 if (dest_align && src_align
8179 && (readonly_data_expr (src)
8180 || (host_integerp (len, 1)
8181 && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8182 tree_low_cst (len, 1)))))
8183 {
8184 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8185 if (!fn)
8186 return 0;
8187 return build_function_call_expr (fn, arglist);
8188 }
8189 return 0;
8190 }
8191
8192 if (!host_integerp (len, 0))
8193 return 0;
8194 /* FIXME:
8195 This logic lose for arguments like (type *)malloc (sizeof (type)),
8196 since we strip the casts of up to VOID return value from malloc.
8197 Perhaps we ought to inherit type from non-VOID argument here? */
8198 STRIP_NOPS (src);
8199 STRIP_NOPS (dest);
8200 srctype = TREE_TYPE (TREE_TYPE (src));
8201 desttype = TREE_TYPE (TREE_TYPE (dest));
8202 if (!srctype || !desttype
8203 || !TYPE_SIZE_UNIT (srctype)
8204 || !TYPE_SIZE_UNIT (desttype)
8205 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8206 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8207 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8208 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8209 return 0;
8210
8211 if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT)
8212 < (int) TYPE_ALIGN (desttype)
8213 || (get_pointer_alignment (src, BIGGEST_ALIGNMENT)
8214 < (int) TYPE_ALIGN (srctype)))
8215 return 0;
8216
8217 if (!ignore)
8218 dest = builtin_save_expr (dest);
8219
8220 srcvar = build_fold_indirect_ref (src);
8221 if (TREE_THIS_VOLATILE (srcvar))
8222 return 0;
8223 if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8224 return 0;
8225 /* With memcpy, it is possible to bypass aliasing rules, so without
8226 this check i. e. execute/20060930-2.c would be misoptimized, because
8227 it use conflicting alias set to hold argument for the memcpy call.
8228 This check is probably unnecesary with -fno-strict-aliasing.
8229 Similarly for destvar. See also PR29286. */
8230 if (!var_decl_component_p (srcvar)
8231 /* Accept: memcpy (*char_var, "test", 1); that simplify
8232 to char_var='t'; */
8233 || is_gimple_min_invariant (srcvar)
8234 || readonly_data_expr (src))
8235 return 0;
8236
8237 destvar = build_fold_indirect_ref (dest);
8238 if (TREE_THIS_VOLATILE (destvar))
8239 return 0;
8240 if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8241 return 0;
8242 if (!var_decl_component_p (destvar))
8243 return 0;
8244
8245 if (srctype == desttype
8246 || (gimple_in_ssa_p (cfun)
8247 && tree_ssa_useless_type_conversion_1 (desttype, srctype)))
8248 expr = srcvar;
8249 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8250 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8251 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8252 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8253 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8254 else
8255 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8256 expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (destvar), destvar, expr);
8257 }
8258
8259 if (ignore)
8260 return expr;
8261
8262 if (endp == 0 || endp == 3)
8263 return omit_one_operand (type, dest, expr);
8264
8265 if (expr == len)
8266 expr = 0;
8267
8268 if (endp == 2)
8269 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8270 ssize_int (1));
8271
8272 len = fold_convert (TREE_TYPE (dest), len);
8273 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8274 dest = fold_convert (type, dest);
8275 if (expr)
8276 dest = omit_one_operand (type, dest, expr);
8277 return dest;
8278 }
8279
8280 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8281 simplification can be made. */
8282
8283 static tree
8284 fold_builtin_bcopy (tree arglist, bool ignore)
8285 {
8286 tree src, dest, size, newarglist;
8287
8288 if (!validate_arglist (arglist,
8289 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8290 return 0;
8291
8292 if (! ignore)
8293 return 0;
8294
8295 src = TREE_VALUE (arglist);
8296 dest = TREE_VALUE (TREE_CHAIN (arglist));
8297 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8298
8299 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8300 memmove(ptr y, ptr x, size_t z). This is done this way
8301 so that if it isn't expanded inline, we fallback to
8302 calling bcopy instead of memmove. */
8303
8304 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8305 newarglist = tree_cons (NULL_TREE, src, newarglist);
8306 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8307
8308 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8309 }
8310
8311 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8312 the length of the string to be copied. Return NULL_TREE if no
8313 simplification can be made. */
8314
8315 tree
8316 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8317 {
8318 tree dest, src, fn;
8319
8320 if (!validate_arglist (arglist,
8321 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8322 return 0;
8323
8324 dest = TREE_VALUE (arglist);
8325 src = TREE_VALUE (TREE_CHAIN (arglist));
8326
8327 /* If SRC and DEST are the same (and not volatile), return DEST. */
8328 if (operand_equal_p (src, dest, 0))
8329 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8330
8331 if (optimize_size)
8332 return 0;
8333
8334 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8335 if (!fn)
8336 return 0;
8337
8338 if (!len)
8339 {
8340 len = c_strlen (src, 1);
8341 if (! len || TREE_SIDE_EFFECTS (len))
8342 return 0;
8343 }
8344
8345 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8346 arglist = build_tree_list (NULL_TREE, len);
8347 arglist = tree_cons (NULL_TREE, src, arglist);
8348 arglist = tree_cons (NULL_TREE, dest, arglist);
8349 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8350 build_function_call_expr (fn, arglist));
8351 }
8352
8353 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8354 the length of the source string. Return NULL_TREE if no simplification
8355 can be made. */
8356
8357 tree
8358 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8359 {
8360 tree dest, src, len, fn;
8361
8362 if (!validate_arglist (arglist,
8363 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8364 return 0;
8365
8366 dest = TREE_VALUE (arglist);
8367 src = TREE_VALUE (TREE_CHAIN (arglist));
8368 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8369
8370 /* If the LEN parameter is zero, return DEST. */
8371 if (integer_zerop (len))
8372 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8373
8374 /* We can't compare slen with len as constants below if len is not a
8375 constant. */
8376 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8377 return 0;
8378
8379 if (!slen)
8380 slen = c_strlen (src, 1);
8381
8382 /* Now, we must be passed a constant src ptr parameter. */
8383 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8384 return 0;
8385
8386 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8387
8388 /* We do not support simplification of this case, though we do
8389 support it when expanding trees into RTL. */
8390 /* FIXME: generate a call to __builtin_memset. */
8391 if (tree_int_cst_lt (slen, len))
8392 return 0;
8393
8394 /* OK transform into builtin memcpy. */
8395 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8396 if (!fn)
8397 return 0;
8398 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8399 build_function_call_expr (fn, arglist));
8400 }
8401
8402 /* Fold function call to builtin memcmp. Return
8403 NULL_TREE if no simplification can be made. */
8404
8405 static tree
8406 fold_builtin_memcmp (tree arglist)
8407 {
8408 tree arg1, arg2, len;
8409 const char *p1, *p2;
8410
8411 if (!validate_arglist (arglist,
8412 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8413 return 0;
8414
8415 arg1 = TREE_VALUE (arglist);
8416 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8417 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8418
8419 /* If the LEN parameter is zero, return zero. */
8420 if (integer_zerop (len))
8421 return omit_two_operands (integer_type_node, integer_zero_node,
8422 arg1, arg2);
8423
8424 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8425 if (operand_equal_p (arg1, arg2, 0))
8426 return omit_one_operand (integer_type_node, integer_zero_node, len);
8427
8428 p1 = c_getstr (arg1);
8429 p2 = c_getstr (arg2);
8430
8431 /* If all arguments are constant, and the value of len is not greater
8432 than the lengths of arg1 and arg2, evaluate at compile-time. */
8433 if (host_integerp (len, 1) && p1 && p2
8434 && compare_tree_int (len, strlen (p1) + 1) <= 0
8435 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8436 {
8437 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8438
8439 if (r > 0)
8440 return integer_one_node;
8441 else if (r < 0)
8442 return integer_minus_one_node;
8443 else
8444 return integer_zero_node;
8445 }
8446
8447 /* If len parameter is one, return an expression corresponding to
8448 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8449 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8450 {
8451 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8452 tree cst_uchar_ptr_node
8453 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8454
8455 tree ind1 = fold_convert (integer_type_node,
8456 build1 (INDIRECT_REF, cst_uchar_node,
8457 fold_convert (cst_uchar_ptr_node,
8458 arg1)));
8459 tree ind2 = fold_convert (integer_type_node,
8460 build1 (INDIRECT_REF, cst_uchar_node,
8461 fold_convert (cst_uchar_ptr_node,
8462 arg2)));
8463 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8464 }
8465
8466 return 0;
8467 }
8468
8469 /* Fold function call to builtin strcmp. Return
8470 NULL_TREE if no simplification can be made. */
8471
8472 static tree
8473 fold_builtin_strcmp (tree arglist)
8474 {
8475 tree arg1, arg2;
8476 const char *p1, *p2;
8477
8478 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8479 return 0;
8480
8481 arg1 = TREE_VALUE (arglist);
8482 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8483
8484 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8485 if (operand_equal_p (arg1, arg2, 0))
8486 return integer_zero_node;
8487
8488 p1 = c_getstr (arg1);
8489 p2 = c_getstr (arg2);
8490
8491 if (p1 && p2)
8492 {
8493 const int i = strcmp (p1, p2);
8494 if (i < 0)
8495 return integer_minus_one_node;
8496 else if (i > 0)
8497 return integer_one_node;
8498 else
8499 return integer_zero_node;
8500 }
8501
8502 /* If the second arg is "", return *(const unsigned char*)arg1. */
8503 if (p2 && *p2 == '\0')
8504 {
8505 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8506 tree cst_uchar_ptr_node
8507 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8508
8509 return fold_convert (integer_type_node,
8510 build1 (INDIRECT_REF, cst_uchar_node,
8511 fold_convert (cst_uchar_ptr_node,
8512 arg1)));
8513 }
8514
8515 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8516 if (p1 && *p1 == '\0')
8517 {
8518 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8519 tree cst_uchar_ptr_node
8520 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8521
8522 tree temp = fold_convert (integer_type_node,
8523 build1 (INDIRECT_REF, cst_uchar_node,
8524 fold_convert (cst_uchar_ptr_node,
8525 arg2)));
8526 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8527 }
8528
8529 return 0;
8530 }
8531
8532 /* Fold function call to builtin strncmp. Return
8533 NULL_TREE if no simplification can be made. */
8534
8535 static tree
8536 fold_builtin_strncmp (tree arglist)
8537 {
8538 tree arg1, arg2, len;
8539 const char *p1, *p2;
8540
8541 if (!validate_arglist (arglist,
8542 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8543 return 0;
8544
8545 arg1 = TREE_VALUE (arglist);
8546 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8547 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8548
8549 /* If the LEN parameter is zero, return zero. */
8550 if (integer_zerop (len))
8551 return omit_two_operands (integer_type_node, integer_zero_node,
8552 arg1, arg2);
8553
8554 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8555 if (operand_equal_p (arg1, arg2, 0))
8556 return omit_one_operand (integer_type_node, integer_zero_node, len);
8557
8558 p1 = c_getstr (arg1);
8559 p2 = c_getstr (arg2);
8560
8561 if (host_integerp (len, 1) && p1 && p2)
8562 {
8563 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8564 if (i > 0)
8565 return integer_one_node;
8566 else if (i < 0)
8567 return integer_minus_one_node;
8568 else
8569 return integer_zero_node;
8570 }
8571
8572 /* If the second arg is "", and the length is greater than zero,
8573 return *(const unsigned char*)arg1. */
8574 if (p2 && *p2 == '\0'
8575 && TREE_CODE (len) == INTEGER_CST
8576 && tree_int_cst_sgn (len) == 1)
8577 {
8578 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8579 tree cst_uchar_ptr_node
8580 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8581
8582 return fold_convert (integer_type_node,
8583 build1 (INDIRECT_REF, cst_uchar_node,
8584 fold_convert (cst_uchar_ptr_node,
8585 arg1)));
8586 }
8587
8588 /* If the first arg is "", and the length is greater than zero,
8589 return -*(const unsigned char*)arg2. */
8590 if (p1 && *p1 == '\0'
8591 && TREE_CODE (len) == INTEGER_CST
8592 && tree_int_cst_sgn (len) == 1)
8593 {
8594 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8595 tree cst_uchar_ptr_node
8596 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8597
8598 tree temp = fold_convert (integer_type_node,
8599 build1 (INDIRECT_REF, cst_uchar_node,
8600 fold_convert (cst_uchar_ptr_node,
8601 arg2)));
8602 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8603 }
8604
8605 /* If len parameter is one, return an expression corresponding to
8606 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8607 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8608 {
8609 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8610 tree cst_uchar_ptr_node
8611 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8612
8613 tree ind1 = fold_convert (integer_type_node,
8614 build1 (INDIRECT_REF, cst_uchar_node,
8615 fold_convert (cst_uchar_ptr_node,
8616 arg1)));
8617 tree ind2 = fold_convert (integer_type_node,
8618 build1 (INDIRECT_REF, cst_uchar_node,
8619 fold_convert (cst_uchar_ptr_node,
8620 arg2)));
8621 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8622 }
8623
8624 return 0;
8625 }
8626
8627 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8628 NULL_TREE if no simplification can be made. */
8629
8630 static tree
8631 fold_builtin_signbit (tree fndecl, tree arglist)
8632 {
8633 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8634 tree arg, temp;
8635
8636 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8637 return NULL_TREE;
8638
8639 arg = TREE_VALUE (arglist);
8640
8641 /* If ARG is a compile-time constant, determine the result. */
8642 if (TREE_CODE (arg) == REAL_CST
8643 && !TREE_CONSTANT_OVERFLOW (arg))
8644 {
8645 REAL_VALUE_TYPE c;
8646
8647 c = TREE_REAL_CST (arg);
8648 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8649 return fold_convert (type, temp);
8650 }
8651
8652 /* If ARG is non-negative, the result is always zero. */
8653 if (tree_expr_nonnegative_p (arg))
8654 return omit_one_operand (type, integer_zero_node, arg);
8655
8656 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8657 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8658 return fold_build2 (LT_EXPR, type, arg,
8659 build_real (TREE_TYPE (arg), dconst0));
8660
8661 return NULL_TREE;
8662 }
8663
8664 /* Fold function call to builtin copysign, copysignf or copysignl.
8665 Return NULL_TREE if no simplification can be made. */
8666
8667 static tree
8668 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8669 {
8670 tree arg1, arg2, tem;
8671
8672 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8673 return NULL_TREE;
8674
8675 arg1 = TREE_VALUE (arglist);
8676 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8677
8678 /* copysign(X,X) is X. */
8679 if (operand_equal_p (arg1, arg2, 0))
8680 return fold_convert (type, arg1);
8681
8682 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8683 if (TREE_CODE (arg1) == REAL_CST
8684 && TREE_CODE (arg2) == REAL_CST
8685 && !TREE_CONSTANT_OVERFLOW (arg1)
8686 && !TREE_CONSTANT_OVERFLOW (arg2))
8687 {
8688 REAL_VALUE_TYPE c1, c2;
8689
8690 c1 = TREE_REAL_CST (arg1);
8691 c2 = TREE_REAL_CST (arg2);
8692 /* c1.sign := c2.sign. */
8693 real_copysign (&c1, &c2);
8694 return build_real (type, c1);
8695 }
8696
8697 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8698 Remember to evaluate Y for side-effects. */
8699 if (tree_expr_nonnegative_p (arg2))
8700 return omit_one_operand (type,
8701 fold_build1 (ABS_EXPR, type, arg1),
8702 arg2);
8703
8704 /* Strip sign changing operations for the first argument. */
8705 tem = fold_strip_sign_ops (arg1);
8706 if (tem)
8707 {
8708 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8709 return build_function_call_expr (fndecl, arglist);
8710 }
8711
8712 return NULL_TREE;
8713 }
8714
8715 /* Fold a call to builtin isascii. */
8716
8717 static tree
8718 fold_builtin_isascii (tree arglist)
8719 {
8720 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8721 return 0;
8722 else
8723 {
8724 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8725 tree arg = TREE_VALUE (arglist);
8726
8727 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8728 build_int_cst (NULL_TREE,
8729 ~ (unsigned HOST_WIDE_INT) 0x7f));
8730 return fold_build2 (EQ_EXPR, integer_type_node,
8731 arg, integer_zero_node);
8732 }
8733 }
8734
8735 /* Fold a call to builtin toascii. */
8736
8737 static tree
8738 fold_builtin_toascii (tree arglist)
8739 {
8740 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8741 return 0;
8742 else
8743 {
8744 /* Transform toascii(c) -> (c & 0x7f). */
8745 tree arg = TREE_VALUE (arglist);
8746
8747 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8748 build_int_cst (NULL_TREE, 0x7f));
8749 }
8750 }
8751
8752 /* Fold a call to builtin isdigit. */
8753
8754 static tree
8755 fold_builtin_isdigit (tree arglist)
8756 {
8757 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8758 return 0;
8759 else
8760 {
8761 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8762 /* According to the C standard, isdigit is unaffected by locale.
8763 However, it definitely is affected by the target character set. */
8764 tree arg;
8765 unsigned HOST_WIDE_INT target_digit0
8766 = lang_hooks.to_target_charset ('0');
8767
8768 if (target_digit0 == 0)
8769 return NULL_TREE;
8770
8771 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8772 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8773 build_int_cst (unsigned_type_node, target_digit0));
8774 return fold_build2 (LE_EXPR, integer_type_node, arg,
8775 build_int_cst (unsigned_type_node, 9));
8776 }
8777 }
8778
8779 /* Fold a call to fabs, fabsf or fabsl. */
8780
8781 static tree
8782 fold_builtin_fabs (tree arglist, tree type)
8783 {
8784 tree arg;
8785
8786 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8787 return 0;
8788
8789 arg = TREE_VALUE (arglist);
8790 arg = fold_convert (type, arg);
8791 if (TREE_CODE (arg) == REAL_CST)
8792 return fold_abs_const (arg, type);
8793 return fold_build1 (ABS_EXPR, type, arg);
8794 }
8795
8796 /* Fold a call to abs, labs, llabs or imaxabs. */
8797
8798 static tree
8799 fold_builtin_abs (tree arglist, tree type)
8800 {
8801 tree arg;
8802
8803 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8804 return 0;
8805
8806 arg = TREE_VALUE (arglist);
8807 arg = fold_convert (type, arg);
8808 if (TREE_CODE (arg) == INTEGER_CST)
8809 return fold_abs_const (arg, type);
8810 return fold_build1 (ABS_EXPR, type, arg);
8811 }
8812
8813 /* Fold a call to builtin fmin or fmax. */
8814
8815 static tree
8816 fold_builtin_fmin_fmax (tree arglist, tree type, bool max)
8817 {
8818 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8819 {
8820 tree arg0 = TREE_VALUE (arglist);
8821 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8822 /* Calculate the result when the argument is a constant. */
8823 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
8824
8825 if (res)
8826 return res;
8827
8828 /* If either argument is NaN, return the other one. Avoid the
8829 transformation if we get (and honor) a signalling NaN. Using
8830 omit_one_operand() ensures we create a non-lvalue. */
8831 if (TREE_CODE (arg0) == REAL_CST
8832 && real_isnan (&TREE_REAL_CST (arg0))
8833 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
8834 || ! TREE_REAL_CST (arg0).signalling))
8835 return omit_one_operand (type, arg1, arg0);
8836 if (TREE_CODE (arg1) == REAL_CST
8837 && real_isnan (&TREE_REAL_CST (arg1))
8838 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
8839 || ! TREE_REAL_CST (arg1).signalling))
8840 return omit_one_operand (type, arg0, arg1);
8841
8842 /* Transform fmin/fmax(x,x) -> x. */
8843 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8844 return omit_one_operand (type, arg0, arg1);
8845
8846 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
8847 functions to return the numeric arg if the other one is NaN.
8848 These tree codes don't honor that, so only transform if
8849 -ffinite-math-only is set. C99 doesn't require -0.0 to be
8850 handled, so we don't have to worry about it either. */
8851 if (flag_finite_math_only)
8852 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
8853 fold_convert (type, arg0),
8854 fold_convert (type, arg1));
8855 }
8856 return NULL_TREE;
8857 }
8858
8859 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8860 EXP is the CALL_EXPR for the call. */
8861
8862 static tree
8863 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8864 {
8865 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8866 tree arg;
8867 REAL_VALUE_TYPE r;
8868
8869 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8870 {
8871 /* Check that we have exactly one argument. */
8872 if (arglist == 0)
8873 {
8874 error ("too few arguments to function %qs",
8875 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8876 return error_mark_node;
8877 }
8878 else if (TREE_CHAIN (arglist) != 0)
8879 {
8880 error ("too many arguments to function %qs",
8881 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8882 return error_mark_node;
8883 }
8884 else
8885 {
8886 error ("non-floating-point argument to function %qs",
8887 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8888 return error_mark_node;
8889 }
8890 }
8891
8892 arg = TREE_VALUE (arglist);
8893 switch (builtin_index)
8894 {
8895 case BUILT_IN_ISINF:
8896 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8897 return omit_one_operand (type, integer_zero_node, arg);
8898
8899 if (TREE_CODE (arg) == REAL_CST)
8900 {
8901 r = TREE_REAL_CST (arg);
8902 if (real_isinf (&r))
8903 return real_compare (GT_EXPR, &r, &dconst0)
8904 ? integer_one_node : integer_minus_one_node;
8905 else
8906 return integer_zero_node;
8907 }
8908
8909 return NULL_TREE;
8910
8911 case BUILT_IN_FINITE:
8912 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8913 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8914 return omit_one_operand (type, integer_one_node, arg);
8915
8916 if (TREE_CODE (arg) == REAL_CST)
8917 {
8918 r = TREE_REAL_CST (arg);
8919 return real_isinf (&r) || real_isnan (&r)
8920 ? integer_zero_node : integer_one_node;
8921 }
8922
8923 return NULL_TREE;
8924
8925 case BUILT_IN_ISNAN:
8926 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8927 return omit_one_operand (type, integer_zero_node, arg);
8928
8929 if (TREE_CODE (arg) == REAL_CST)
8930 {
8931 r = TREE_REAL_CST (arg);
8932 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8933 }
8934
8935 arg = builtin_save_expr (arg);
8936 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8937
8938 default:
8939 gcc_unreachable ();
8940 }
8941 }
8942
8943 /* Fold a call to an unordered comparison function such as
8944 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8945 being called and ARGLIST is the argument list for the call.
8946 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8947 the opposite of the desired result. UNORDERED_CODE is used
8948 for modes that can hold NaNs and ORDERED_CODE is used for
8949 the rest. */
8950
8951 static tree
8952 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8953 enum tree_code unordered_code,
8954 enum tree_code ordered_code)
8955 {
8956 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8957 enum tree_code code;
8958 tree arg0, arg1;
8959 tree type0, type1;
8960 enum tree_code code0, code1;
8961 tree cmp_type = NULL_TREE;
8962
8963 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8964 {
8965 /* Check that we have exactly two arguments. */
8966 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8967 {
8968 error ("too few arguments to function %qs",
8969 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8970 return error_mark_node;
8971 }
8972 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8973 {
8974 error ("too many arguments to function %qs",
8975 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8976 return error_mark_node;
8977 }
8978 }
8979
8980 arg0 = TREE_VALUE (arglist);
8981 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8982
8983 type0 = TREE_TYPE (arg0);
8984 type1 = TREE_TYPE (arg1);
8985
8986 code0 = TREE_CODE (type0);
8987 code1 = TREE_CODE (type1);
8988
8989 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8990 /* Choose the wider of two real types. */
8991 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8992 ? type0 : type1;
8993 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8994 cmp_type = type0;
8995 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8996 cmp_type = type1;
8997 else
8998 {
8999 error ("non-floating-point argument to function %qs",
9000 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9001 return error_mark_node;
9002 }
9003
9004 arg0 = fold_convert (cmp_type, arg0);
9005 arg1 = fold_convert (cmp_type, arg1);
9006
9007 if (unordered_code == UNORDERED_EXPR)
9008 {
9009 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9010 return omit_two_operands (type, integer_zero_node, arg0, arg1);
9011 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9012 }
9013
9014 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9015 : ordered_code;
9016 return fold_build1 (TRUTH_NOT_EXPR, type,
9017 fold_build2 (code, type, arg0, arg1));
9018 }
9019
9020 /* Used by constant folding to simplify calls to builtin functions. EXP is
9021 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
9022 result of the function call is ignored. This function returns NULL_TREE
9023 if no simplification was possible. */
9024
9025 static tree
9026 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9027 {
9028 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9029 enum built_in_function fcode;
9030
9031 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9032 return targetm.fold_builtin (fndecl, arglist, ignore);
9033
9034 fcode = DECL_FUNCTION_CODE (fndecl);
9035 switch (fcode)
9036 {
9037 case BUILT_IN_FPUTS:
9038 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9039
9040 case BUILT_IN_FPUTS_UNLOCKED:
9041 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9042
9043 case BUILT_IN_STRSTR:
9044 return fold_builtin_strstr (arglist, type);
9045
9046 case BUILT_IN_STRCAT:
9047 return fold_builtin_strcat (arglist);
9048
9049 case BUILT_IN_STRNCAT:
9050 return fold_builtin_strncat (arglist);
9051
9052 case BUILT_IN_STRSPN:
9053 return fold_builtin_strspn (arglist);
9054
9055 case BUILT_IN_STRCSPN:
9056 return fold_builtin_strcspn (arglist);
9057
9058 case BUILT_IN_STRCHR:
9059 case BUILT_IN_INDEX:
9060 return fold_builtin_strchr (arglist, type);
9061
9062 case BUILT_IN_STRRCHR:
9063 case BUILT_IN_RINDEX:
9064 return fold_builtin_strrchr (arglist, type);
9065
9066 case BUILT_IN_STRCPY:
9067 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9068
9069 case BUILT_IN_STRNCPY:
9070 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9071
9072 case BUILT_IN_STRCMP:
9073 return fold_builtin_strcmp (arglist);
9074
9075 case BUILT_IN_STRNCMP:
9076 return fold_builtin_strncmp (arglist);
9077
9078 case BUILT_IN_STRPBRK:
9079 return fold_builtin_strpbrk (arglist, type);
9080
9081 case BUILT_IN_BCMP:
9082 case BUILT_IN_MEMCMP:
9083 return fold_builtin_memcmp (arglist);
9084
9085 case BUILT_IN_SPRINTF:
9086 return fold_builtin_sprintf (arglist, ignore);
9087
9088 case BUILT_IN_CONSTANT_P:
9089 {
9090 tree val;
9091
9092 val = fold_builtin_constant_p (arglist);
9093 /* Gimplification will pull the CALL_EXPR for the builtin out of
9094 an if condition. When not optimizing, we'll not CSE it back.
9095 To avoid link error types of regressions, return false now. */
9096 if (!val && !optimize)
9097 val = integer_zero_node;
9098
9099 return val;
9100 }
9101
9102 case BUILT_IN_EXPECT:
9103 return fold_builtin_expect (arglist);
9104
9105 case BUILT_IN_CLASSIFY_TYPE:
9106 return fold_builtin_classify_type (arglist);
9107
9108 case BUILT_IN_STRLEN:
9109 return fold_builtin_strlen (arglist);
9110
9111 CASE_FLT_FN (BUILT_IN_FABS):
9112 return fold_builtin_fabs (arglist, type);
9113
9114 case BUILT_IN_ABS:
9115 case BUILT_IN_LABS:
9116 case BUILT_IN_LLABS:
9117 case BUILT_IN_IMAXABS:
9118 return fold_builtin_abs (arglist, type);
9119
9120 CASE_FLT_FN (BUILT_IN_CONJ):
9121 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9122 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9123 break;
9124
9125 CASE_FLT_FN (BUILT_IN_CREAL):
9126 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9127 return non_lvalue (fold_build1 (REALPART_EXPR, type,
9128 TREE_VALUE (arglist)));
9129 break;
9130
9131 CASE_FLT_FN (BUILT_IN_CIMAG):
9132 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9133 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9134 TREE_VALUE (arglist)));
9135 break;
9136
9137 CASE_FLT_FN (BUILT_IN_CABS):
9138 return fold_builtin_cabs (arglist, type, fndecl);
9139
9140 CASE_FLT_FN (BUILT_IN_SQRT):
9141 return fold_builtin_sqrt (arglist, type);
9142
9143 CASE_FLT_FN (BUILT_IN_CBRT):
9144 return fold_builtin_cbrt (arglist, type);
9145
9146 CASE_FLT_FN (BUILT_IN_ASIN):
9147 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9148 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9149 &dconstm1, &dconst1, true);
9150 break;
9151
9152 CASE_FLT_FN (BUILT_IN_ACOS):
9153 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9154 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9155 &dconstm1, &dconst1, true);
9156 break;
9157
9158 CASE_FLT_FN (BUILT_IN_ATAN):
9159 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9160 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9161 NULL, NULL, 0);
9162 break;
9163
9164 CASE_FLT_FN (BUILT_IN_ASINH):
9165 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9166 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9167 NULL, NULL, 0);
9168 break;
9169
9170 CASE_FLT_FN (BUILT_IN_ACOSH):
9171 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9172 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9173 &dconst1, NULL, true);
9174 break;
9175
9176 CASE_FLT_FN (BUILT_IN_ATANH):
9177 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9178 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9179 &dconstm1, &dconst1, false);
9180 break;
9181
9182 CASE_FLT_FN (BUILT_IN_SIN):
9183 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9184 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9185 NULL, NULL, 0);
9186 break;
9187
9188 CASE_FLT_FN (BUILT_IN_COS):
9189 return fold_builtin_cos (arglist, type, fndecl);
9190
9191 CASE_FLT_FN (BUILT_IN_TAN):
9192 return fold_builtin_tan (arglist, type);
9193
9194 CASE_FLT_FN (BUILT_IN_SINCOS):
9195 if (validate_arglist (arglist, REAL_TYPE, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9196 return do_mpfr_sincos (TREE_VALUE (arglist), TREE_VALUE (TREE_CHAIN (arglist)),
9197 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
9198 break;
9199
9200 CASE_FLT_FN (BUILT_IN_SINH):
9201 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9202 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9203 NULL, NULL, 0);
9204 break;
9205
9206 CASE_FLT_FN (BUILT_IN_COSH):
9207 return fold_builtin_cosh (arglist, type, fndecl);
9208
9209 CASE_FLT_FN (BUILT_IN_TANH):
9210 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9211 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9212 NULL, NULL, 0);
9213 break;
9214
9215 CASE_FLT_FN (BUILT_IN_ERF):
9216 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9217 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9218 NULL, NULL, 0);
9219 break;
9220
9221 CASE_FLT_FN (BUILT_IN_ERFC):
9222 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9223 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9224 NULL, NULL, 0);
9225 break;
9226
9227 CASE_FLT_FN (BUILT_IN_TGAMMA):
9228 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9229 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9230 NULL, NULL, 0);
9231 break;
9232
9233 CASE_FLT_FN (BUILT_IN_EXP):
9234 return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9235
9236 CASE_FLT_FN (BUILT_IN_EXP2):
9237 return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9238
9239 CASE_FLT_FN (BUILT_IN_EXP10):
9240 CASE_FLT_FN (BUILT_IN_POW10):
9241 return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9242
9243 CASE_FLT_FN (BUILT_IN_EXPM1):
9244 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9245 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9246 NULL, NULL, 0);
9247 break;
9248
9249 CASE_FLT_FN (BUILT_IN_LOG):
9250 return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9251
9252 CASE_FLT_FN (BUILT_IN_LOG2):
9253 return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9254
9255 CASE_FLT_FN (BUILT_IN_LOG10):
9256 return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9257
9258 CASE_FLT_FN (BUILT_IN_LOG1P):
9259 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9260 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9261 &dconstm1, NULL, false);
9262 break;
9263
9264 CASE_FLT_FN (BUILT_IN_ATAN2):
9265 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9266 return do_mpfr_arg2 (TREE_VALUE (arglist),
9267 TREE_VALUE (TREE_CHAIN (arglist)),
9268 type, mpfr_atan2);
9269 break;
9270
9271 CASE_FLT_FN (BUILT_IN_FMA):
9272 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9273 return do_mpfr_arg3 (TREE_VALUE (arglist),
9274 TREE_VALUE (TREE_CHAIN (arglist)),
9275 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9276 type, mpfr_fma);
9277 break;
9278
9279 CASE_FLT_FN (BUILT_IN_FMIN):
9280 return fold_builtin_fmin_fmax (arglist, type, /*max=*/false);
9281
9282 CASE_FLT_FN (BUILT_IN_FMAX):
9283 return fold_builtin_fmin_fmax (arglist, type, /*max=*/true);
9284
9285 CASE_FLT_FN (BUILT_IN_HYPOT):
9286 return fold_builtin_hypot (fndecl, arglist, type);
9287
9288 CASE_FLT_FN (BUILT_IN_POW):
9289 return fold_builtin_pow (fndecl, arglist, type);
9290
9291 CASE_FLT_FN (BUILT_IN_POWI):
9292 return fold_builtin_powi (fndecl, arglist, type);
9293
9294 CASE_FLT_FN (BUILT_IN_INF):
9295 case BUILT_IN_INFD32:
9296 case BUILT_IN_INFD64:
9297 case BUILT_IN_INFD128:
9298 return fold_builtin_inf (type, true);
9299
9300 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9301 return fold_builtin_inf (type, false);
9302
9303 CASE_FLT_FN (BUILT_IN_NAN):
9304 case BUILT_IN_NAND32:
9305 case BUILT_IN_NAND64:
9306 case BUILT_IN_NAND128:
9307 return fold_builtin_nan (arglist, type, true);
9308
9309 CASE_FLT_FN (BUILT_IN_NANS):
9310 return fold_builtin_nan (arglist, type, false);
9311
9312 CASE_FLT_FN (BUILT_IN_FLOOR):
9313 return fold_builtin_floor (fndecl, arglist);
9314
9315 CASE_FLT_FN (BUILT_IN_CEIL):
9316 return fold_builtin_ceil (fndecl, arglist);
9317
9318 CASE_FLT_FN (BUILT_IN_TRUNC):
9319 return fold_builtin_trunc (fndecl, arglist);
9320
9321 CASE_FLT_FN (BUILT_IN_ROUND):
9322 return fold_builtin_round (fndecl, arglist);
9323
9324 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9325 CASE_FLT_FN (BUILT_IN_RINT):
9326 return fold_trunc_transparent_mathfn (fndecl, arglist);
9327
9328 CASE_FLT_FN (BUILT_IN_LCEIL):
9329 CASE_FLT_FN (BUILT_IN_LLCEIL):
9330 CASE_FLT_FN (BUILT_IN_LFLOOR):
9331 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9332 CASE_FLT_FN (BUILT_IN_LROUND):
9333 CASE_FLT_FN (BUILT_IN_LLROUND):
9334 return fold_builtin_int_roundingfn (fndecl, arglist);
9335
9336 CASE_FLT_FN (BUILT_IN_LRINT):
9337 CASE_FLT_FN (BUILT_IN_LLRINT):
9338 return fold_fixed_mathfn (fndecl, arglist);
9339
9340 case BUILT_IN_BSWAP32:
9341 case BUILT_IN_BSWAP64:
9342 return fold_builtin_bswap (fndecl, arglist);
9343
9344 CASE_INT_FN (BUILT_IN_FFS):
9345 CASE_INT_FN (BUILT_IN_CLZ):
9346 CASE_INT_FN (BUILT_IN_CTZ):
9347 CASE_INT_FN (BUILT_IN_POPCOUNT):
9348 CASE_INT_FN (BUILT_IN_PARITY):
9349 return fold_builtin_bitop (fndecl, arglist);
9350
9351 case BUILT_IN_MEMSET:
9352 return fold_builtin_memset (arglist, type, ignore);
9353
9354 case BUILT_IN_MEMCPY:
9355 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9356
9357 case BUILT_IN_MEMPCPY:
9358 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9359
9360 case BUILT_IN_MEMMOVE:
9361 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9362
9363 case BUILT_IN_BZERO:
9364 return fold_builtin_bzero (arglist, ignore);
9365
9366 case BUILT_IN_BCOPY:
9367 return fold_builtin_bcopy (arglist, ignore);
9368
9369 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9370 return fold_builtin_signbit (fndecl, arglist);
9371
9372 case BUILT_IN_ISASCII:
9373 return fold_builtin_isascii (arglist);
9374
9375 case BUILT_IN_TOASCII:
9376 return fold_builtin_toascii (arglist);
9377
9378 case BUILT_IN_ISDIGIT:
9379 return fold_builtin_isdigit (arglist);
9380
9381 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9382 return fold_builtin_copysign (fndecl, arglist, type);
9383
9384 CASE_FLT_FN (BUILT_IN_FINITE):
9385 case BUILT_IN_FINITED32:
9386 case BUILT_IN_FINITED64:
9387 case BUILT_IN_FINITED128:
9388 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9389
9390 CASE_FLT_FN (BUILT_IN_ISINF):
9391 case BUILT_IN_ISINFD32:
9392 case BUILT_IN_ISINFD64:
9393 case BUILT_IN_ISINFD128:
9394 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9395
9396 CASE_FLT_FN (BUILT_IN_ISNAN):
9397 case BUILT_IN_ISNAND32:
9398 case BUILT_IN_ISNAND64:
9399 case BUILT_IN_ISNAND128:
9400 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9401
9402 case BUILT_IN_ISGREATER:
9403 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9404 case BUILT_IN_ISGREATEREQUAL:
9405 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9406 case BUILT_IN_ISLESS:
9407 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9408 case BUILT_IN_ISLESSEQUAL:
9409 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9410 case BUILT_IN_ISLESSGREATER:
9411 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9412 case BUILT_IN_ISUNORDERED:
9413 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9414 NOP_EXPR);
9415
9416 /* We do the folding for va_start in the expander. */
9417 case BUILT_IN_VA_START:
9418 break;
9419
9420 case BUILT_IN_OBJECT_SIZE:
9421 return fold_builtin_object_size (arglist);
9422 case BUILT_IN_MEMCPY_CHK:
9423 case BUILT_IN_MEMPCPY_CHK:
9424 case BUILT_IN_MEMMOVE_CHK:
9425 case BUILT_IN_MEMSET_CHK:
9426 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9427 DECL_FUNCTION_CODE (fndecl));
9428 case BUILT_IN_STRCPY_CHK:
9429 case BUILT_IN_STPCPY_CHK:
9430 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9431 DECL_FUNCTION_CODE (fndecl));
9432 case BUILT_IN_STRNCPY_CHK:
9433 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9434 case BUILT_IN_STRCAT_CHK:
9435 return fold_builtin_strcat_chk (fndecl, arglist);
9436 case BUILT_IN_STRNCAT_CHK:
9437 return fold_builtin_strncat_chk (fndecl, arglist);
9438 case BUILT_IN_SPRINTF_CHK:
9439 case BUILT_IN_VSPRINTF_CHK:
9440 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9441 case BUILT_IN_SNPRINTF_CHK:
9442 case BUILT_IN_VSNPRINTF_CHK:
9443 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9444 DECL_FUNCTION_CODE (fndecl));
9445
9446 case BUILT_IN_PRINTF:
9447 case BUILT_IN_PRINTF_UNLOCKED:
9448 case BUILT_IN_VPRINTF:
9449 case BUILT_IN_PRINTF_CHK:
9450 case BUILT_IN_VPRINTF_CHK:
9451 return fold_builtin_printf (fndecl, arglist, ignore,
9452 DECL_FUNCTION_CODE (fndecl));
9453
9454 case BUILT_IN_FPRINTF:
9455 case BUILT_IN_FPRINTF_UNLOCKED:
9456 case BUILT_IN_VFPRINTF:
9457 case BUILT_IN_FPRINTF_CHK:
9458 case BUILT_IN_VFPRINTF_CHK:
9459 return fold_builtin_fprintf (fndecl, arglist, ignore,
9460 DECL_FUNCTION_CODE (fndecl));
9461
9462 default:
9463 break;
9464 }
9465
9466 return 0;
9467 }
9468
9469 /* A wrapper function for builtin folding that prevents warnings for
9470 "statement without effect" and the like, caused by removing the
9471 call node earlier than the warning is generated. */
9472
9473 tree
9474 fold_builtin (tree fndecl, tree arglist, bool ignore)
9475 {
9476 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9477 if (exp && !ignore)
9478 {
9479 exp = build1 (NOP_EXPR, GENERIC_TREE_TYPE (exp), exp);
9480 TREE_NO_WARNING (exp) = 1;
9481 }
9482
9483 return exp;
9484 }
9485
9486 /* Conveniently construct a function call expression. */
9487
9488 tree
9489 build_function_call_expr (tree fn, tree arglist)
9490 {
9491 tree call_expr;
9492
9493 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9494 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9495 call_expr, arglist, NULL_TREE);
9496 }
9497
9498 /* This function validates the types of a function call argument list
9499 represented as a tree chain of parameters against a specified list
9500 of tree_codes. If the last specifier is a 0, that represents an
9501 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9502
9503 int
9504 validate_arglist (tree arglist, ...)
9505 {
9506 enum tree_code code;
9507 int res = 0;
9508 va_list ap;
9509
9510 va_start (ap, arglist);
9511
9512 do
9513 {
9514 code = va_arg (ap, enum tree_code);
9515 switch (code)
9516 {
9517 case 0:
9518 /* This signifies an ellipses, any further arguments are all ok. */
9519 res = 1;
9520 goto end;
9521 case VOID_TYPE:
9522 /* This signifies an endlink, if no arguments remain, return
9523 true, otherwise return false. */
9524 res = arglist == 0;
9525 goto end;
9526 default:
9527 /* If no parameters remain or the parameter's code does not
9528 match the specified code, return false. Otherwise continue
9529 checking any remaining arguments. */
9530 if (arglist == 0)
9531 goto end;
9532 if (code == POINTER_TYPE)
9533 {
9534 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9535 goto end;
9536 }
9537 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9538 goto end;
9539 break;
9540 }
9541 arglist = TREE_CHAIN (arglist);
9542 }
9543 while (1);
9544
9545 /* We need gotos here since we can only have one VA_CLOSE in a
9546 function. */
9547 end: ;
9548 va_end (ap);
9549
9550 return res;
9551 }
9552
9553 /* Default target-specific builtin expander that does nothing. */
9554
9555 rtx
9556 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9557 rtx target ATTRIBUTE_UNUSED,
9558 rtx subtarget ATTRIBUTE_UNUSED,
9559 enum machine_mode mode ATTRIBUTE_UNUSED,
9560 int ignore ATTRIBUTE_UNUSED)
9561 {
9562 return NULL_RTX;
9563 }
9564
9565 /* Returns true is EXP represents data that would potentially reside
9566 in a readonly section. */
9567
9568 static bool
9569 readonly_data_expr (tree exp)
9570 {
9571 STRIP_NOPS (exp);
9572
9573 if (TREE_CODE (exp) != ADDR_EXPR)
9574 return false;
9575
9576 exp = get_base_address (TREE_OPERAND (exp, 0));
9577 if (!exp)
9578 return false;
9579
9580 /* Make sure we call decl_readonly_section only for trees it
9581 can handle (since it returns true for everything it doesn't
9582 understand). */
9583 if (TREE_CODE (exp) == STRING_CST
9584 || TREE_CODE (exp) == CONSTRUCTOR
9585 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9586 return decl_readonly_section (exp, 0);
9587 else
9588 return false;
9589 }
9590
9591 /* Simplify a call to the strstr builtin.
9592
9593 Return 0 if no simplification was possible, otherwise return the
9594 simplified form of the call as a tree.
9595
9596 The simplified form may be a constant or other expression which
9597 computes the same value, but in a more efficient manner (including
9598 calls to other builtin functions).
9599
9600 The call may contain arguments which need to be evaluated, but
9601 which are not useful to determine the result of the call. In
9602 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9603 COMPOUND_EXPR will be an argument which must be evaluated.
9604 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9605 COMPOUND_EXPR in the chain will contain the tree for the simplified
9606 form of the builtin function call. */
9607
9608 static tree
9609 fold_builtin_strstr (tree arglist, tree type)
9610 {
9611 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9612 return 0;
9613 else
9614 {
9615 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9616 tree fn;
9617 const char *p1, *p2;
9618
9619 p2 = c_getstr (s2);
9620 if (p2 == NULL)
9621 return 0;
9622
9623 p1 = c_getstr (s1);
9624 if (p1 != NULL)
9625 {
9626 const char *r = strstr (p1, p2);
9627 tree tem;
9628
9629 if (r == NULL)
9630 return build_int_cst (TREE_TYPE (s1), 0);
9631
9632 /* Return an offset into the constant string argument. */
9633 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9634 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9635 return fold_convert (type, tem);
9636 }
9637
9638 /* The argument is const char *, and the result is char *, so we need
9639 a type conversion here to avoid a warning. */
9640 if (p2[0] == '\0')
9641 return fold_convert (type, s1);
9642
9643 if (p2[1] != '\0')
9644 return 0;
9645
9646 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9647 if (!fn)
9648 return 0;
9649
9650 /* New argument list transforming strstr(s1, s2) to
9651 strchr(s1, s2[0]). */
9652 arglist = build_tree_list (NULL_TREE,
9653 build_int_cst (NULL_TREE, p2[0]));
9654 arglist = tree_cons (NULL_TREE, s1, arglist);
9655 return build_function_call_expr (fn, arglist);
9656 }
9657 }
9658
9659 /* Simplify a call to the strchr builtin.
9660
9661 Return 0 if no simplification was possible, otherwise return the
9662 simplified form of the call as a tree.
9663
9664 The simplified form may be a constant or other expression which
9665 computes the same value, but in a more efficient manner (including
9666 calls to other builtin functions).
9667
9668 The call may contain arguments which need to be evaluated, but
9669 which are not useful to determine the result of the call. In
9670 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9671 COMPOUND_EXPR will be an argument which must be evaluated.
9672 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9673 COMPOUND_EXPR in the chain will contain the tree for the simplified
9674 form of the builtin function call. */
9675
9676 static tree
9677 fold_builtin_strchr (tree arglist, tree type)
9678 {
9679 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9680 return 0;
9681 else
9682 {
9683 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9684 const char *p1;
9685
9686 if (TREE_CODE (s2) != INTEGER_CST)
9687 return 0;
9688
9689 p1 = c_getstr (s1);
9690 if (p1 != NULL)
9691 {
9692 char c;
9693 const char *r;
9694 tree tem;
9695
9696 if (target_char_cast (s2, &c))
9697 return 0;
9698
9699 r = strchr (p1, c);
9700
9701 if (r == NULL)
9702 return build_int_cst (TREE_TYPE (s1), 0);
9703
9704 /* Return an offset into the constant string argument. */
9705 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9706 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9707 return fold_convert (type, tem);
9708 }
9709 return 0;
9710 }
9711 }
9712
9713 /* Simplify a call to the strrchr builtin.
9714
9715 Return 0 if no simplification was possible, otherwise return the
9716 simplified form of the call as a tree.
9717
9718 The simplified form may be a constant or other expression which
9719 computes the same value, but in a more efficient manner (including
9720 calls to other builtin functions).
9721
9722 The call may contain arguments which need to be evaluated, but
9723 which are not useful to determine the result of the call. In
9724 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9725 COMPOUND_EXPR will be an argument which must be evaluated.
9726 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9727 COMPOUND_EXPR in the chain will contain the tree for the simplified
9728 form of the builtin function call. */
9729
9730 static tree
9731 fold_builtin_strrchr (tree arglist, tree type)
9732 {
9733 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9734 return 0;
9735 else
9736 {
9737 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9738 tree fn;
9739 const char *p1;
9740
9741 if (TREE_CODE (s2) != INTEGER_CST)
9742 return 0;
9743
9744 p1 = c_getstr (s1);
9745 if (p1 != NULL)
9746 {
9747 char c;
9748 const char *r;
9749 tree tem;
9750
9751 if (target_char_cast (s2, &c))
9752 return 0;
9753
9754 r = strrchr (p1, c);
9755
9756 if (r == NULL)
9757 return build_int_cst (TREE_TYPE (s1), 0);
9758
9759 /* Return an offset into the constant string argument. */
9760 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9761 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9762 return fold_convert (type, tem);
9763 }
9764
9765 if (! integer_zerop (s2))
9766 return 0;
9767
9768 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9769 if (!fn)
9770 return 0;
9771
9772 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9773 return build_function_call_expr (fn, arglist);
9774 }
9775 }
9776
9777 /* Simplify a call to the strpbrk builtin.
9778
9779 Return 0 if no simplification was possible, otherwise return the
9780 simplified form of the call as a tree.
9781
9782 The simplified form may be a constant or other expression which
9783 computes the same value, but in a more efficient manner (including
9784 calls to other builtin functions).
9785
9786 The call may contain arguments which need to be evaluated, but
9787 which are not useful to determine the result of the call. In
9788 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9789 COMPOUND_EXPR will be an argument which must be evaluated.
9790 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9791 COMPOUND_EXPR in the chain will contain the tree for the simplified
9792 form of the builtin function call. */
9793
9794 static tree
9795 fold_builtin_strpbrk (tree arglist, tree type)
9796 {
9797 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9798 return 0;
9799 else
9800 {
9801 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9802 tree fn;
9803 const char *p1, *p2;
9804
9805 p2 = c_getstr (s2);
9806 if (p2 == NULL)
9807 return 0;
9808
9809 p1 = c_getstr (s1);
9810 if (p1 != NULL)
9811 {
9812 const char *r = strpbrk (p1, p2);
9813 tree tem;
9814
9815 if (r == NULL)
9816 return build_int_cst (TREE_TYPE (s1), 0);
9817
9818 /* Return an offset into the constant string argument. */
9819 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9820 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9821 return fold_convert (type, tem);
9822 }
9823
9824 if (p2[0] == '\0')
9825 /* strpbrk(x, "") == NULL.
9826 Evaluate and ignore s1 in case it had side-effects. */
9827 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9828
9829 if (p2[1] != '\0')
9830 return 0; /* Really call strpbrk. */
9831
9832 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9833 if (!fn)
9834 return 0;
9835
9836 /* New argument list transforming strpbrk(s1, s2) to
9837 strchr(s1, s2[0]). */
9838 arglist = build_tree_list (NULL_TREE,
9839 build_int_cst (NULL_TREE, p2[0]));
9840 arglist = tree_cons (NULL_TREE, s1, arglist);
9841 return build_function_call_expr (fn, arglist);
9842 }
9843 }
9844
9845 /* Simplify a call to the strcat builtin.
9846
9847 Return 0 if no simplification was possible, otherwise return the
9848 simplified form of the call as a tree.
9849
9850 The simplified form may be a constant or other expression which
9851 computes the same value, but in a more efficient manner (including
9852 calls to other builtin functions).
9853
9854 The call may contain arguments which need to be evaluated, but
9855 which are not useful to determine the result of the call. In
9856 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9857 COMPOUND_EXPR will be an argument which must be evaluated.
9858 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9859 COMPOUND_EXPR in the chain will contain the tree for the simplified
9860 form of the builtin function call. */
9861
9862 static tree
9863 fold_builtin_strcat (tree arglist)
9864 {
9865 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9866 return 0;
9867 else
9868 {
9869 tree dst = TREE_VALUE (arglist),
9870 src = TREE_VALUE (TREE_CHAIN (arglist));
9871 const char *p = c_getstr (src);
9872
9873 /* If the string length is zero, return the dst parameter. */
9874 if (p && *p == '\0')
9875 return dst;
9876
9877 return 0;
9878 }
9879 }
9880
9881 /* Simplify a call to the strncat builtin.
9882
9883 Return 0 if no simplification was possible, otherwise return the
9884 simplified form of the call as a tree.
9885
9886 The simplified form may be a constant or other expression which
9887 computes the same value, but in a more efficient manner (including
9888 calls to other builtin functions).
9889
9890 The call may contain arguments which need to be evaluated, but
9891 which are not useful to determine the result of the call. In
9892 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9893 COMPOUND_EXPR will be an argument which must be evaluated.
9894 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9895 COMPOUND_EXPR in the chain will contain the tree for the simplified
9896 form of the builtin function call. */
9897
9898 static tree
9899 fold_builtin_strncat (tree arglist)
9900 {
9901 if (!validate_arglist (arglist,
9902 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9903 return 0;
9904 else
9905 {
9906 tree dst = TREE_VALUE (arglist);
9907 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9908 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9909 const char *p = c_getstr (src);
9910
9911 /* If the requested length is zero, or the src parameter string
9912 length is zero, return the dst parameter. */
9913 if (integer_zerop (len) || (p && *p == '\0'))
9914 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9915
9916 /* If the requested len is greater than or equal to the string
9917 length, call strcat. */
9918 if (TREE_CODE (len) == INTEGER_CST && p
9919 && compare_tree_int (len, strlen (p)) >= 0)
9920 {
9921 tree newarglist
9922 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9923 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9924
9925 /* If the replacement _DECL isn't initialized, don't do the
9926 transformation. */
9927 if (!fn)
9928 return 0;
9929
9930 return build_function_call_expr (fn, newarglist);
9931 }
9932 return 0;
9933 }
9934 }
9935
9936 /* Simplify a call to the strspn builtin.
9937
9938 Return 0 if no simplification was possible, otherwise return the
9939 simplified form of the call as a tree.
9940
9941 The simplified form may be a constant or other expression which
9942 computes the same value, but in a more efficient manner (including
9943 calls to other builtin functions).
9944
9945 The call may contain arguments which need to be evaluated, but
9946 which are not useful to determine the result of the call. In
9947 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9948 COMPOUND_EXPR will be an argument which must be evaluated.
9949 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9950 COMPOUND_EXPR in the chain will contain the tree for the simplified
9951 form of the builtin function call. */
9952
9953 static tree
9954 fold_builtin_strspn (tree arglist)
9955 {
9956 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9957 return 0;
9958 else
9959 {
9960 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9961 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9962
9963 /* If both arguments are constants, evaluate at compile-time. */
9964 if (p1 && p2)
9965 {
9966 const size_t r = strspn (p1, p2);
9967 return size_int (r);
9968 }
9969
9970 /* If either argument is "", return 0. */
9971 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9972 /* Evaluate and ignore both arguments in case either one has
9973 side-effects. */
9974 return omit_two_operands (integer_type_node, integer_zero_node,
9975 s1, s2);
9976 return 0;
9977 }
9978 }
9979
9980 /* Simplify a call to the strcspn builtin.
9981
9982 Return 0 if no simplification was possible, otherwise return the
9983 simplified form of the call as a tree.
9984
9985 The simplified form may be a constant or other expression which
9986 computes the same value, but in a more efficient manner (including
9987 calls to other builtin functions).
9988
9989 The call may contain arguments which need to be evaluated, but
9990 which are not useful to determine the result of the call. In
9991 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9992 COMPOUND_EXPR will be an argument which must be evaluated.
9993 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9994 COMPOUND_EXPR in the chain will contain the tree for the simplified
9995 form of the builtin function call. */
9996
9997 static tree
9998 fold_builtin_strcspn (tree arglist)
9999 {
10000 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10001 return 0;
10002 else
10003 {
10004 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10005 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10006
10007 /* If both arguments are constants, evaluate at compile-time. */
10008 if (p1 && p2)
10009 {
10010 const size_t r = strcspn (p1, p2);
10011 return size_int (r);
10012 }
10013
10014 /* If the first argument is "", return 0. */
10015 if (p1 && *p1 == '\0')
10016 {
10017 /* Evaluate and ignore argument s2 in case it has
10018 side-effects. */
10019 return omit_one_operand (integer_type_node,
10020 integer_zero_node, s2);
10021 }
10022
10023 /* If the second argument is "", return __builtin_strlen(s1). */
10024 if (p2 && *p2 == '\0')
10025 {
10026 tree newarglist = build_tree_list (NULL_TREE, s1),
10027 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10028
10029 /* If the replacement _DECL isn't initialized, don't do the
10030 transformation. */
10031 if (!fn)
10032 return 0;
10033
10034 return build_function_call_expr (fn, newarglist);
10035 }
10036 return 0;
10037 }
10038 }
10039
10040 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
10041 by the builtin will be ignored. UNLOCKED is true is true if this
10042 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
10043 the known length of the string. Return NULL_TREE if no simplification
10044 was possible. */
10045
10046 tree
10047 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10048 {
10049 tree fn;
10050 /* If we're using an unlocked function, assume the other unlocked
10051 functions exist explicitly. */
10052 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10053 : implicit_built_in_decls[BUILT_IN_FPUTC];
10054 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10055 : implicit_built_in_decls[BUILT_IN_FWRITE];
10056
10057 /* If the return value is used, don't do the transformation. */
10058 if (!ignore)
10059 return 0;
10060
10061 /* Verify the arguments in the original call. */
10062 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10063 return 0;
10064
10065 if (! len)
10066 len = c_strlen (TREE_VALUE (arglist), 0);
10067
10068 /* Get the length of the string passed to fputs. If the length
10069 can't be determined, punt. */
10070 if (!len
10071 || TREE_CODE (len) != INTEGER_CST)
10072 return 0;
10073
10074 switch (compare_tree_int (len, 1))
10075 {
10076 case -1: /* length is 0, delete the call entirely . */
10077 return omit_one_operand (integer_type_node, integer_zero_node,
10078 TREE_VALUE (TREE_CHAIN (arglist)));
10079
10080 case 0: /* length is 1, call fputc. */
10081 {
10082 const char *p = c_getstr (TREE_VALUE (arglist));
10083
10084 if (p != NULL)
10085 {
10086 /* New argument list transforming fputs(string, stream) to
10087 fputc(string[0], stream). */
10088 arglist = build_tree_list (NULL_TREE,
10089 TREE_VALUE (TREE_CHAIN (arglist)));
10090 arglist = tree_cons (NULL_TREE,
10091 build_int_cst (NULL_TREE, p[0]),
10092 arglist);
10093 fn = fn_fputc;
10094 break;
10095 }
10096 }
10097 /* FALLTHROUGH */
10098 case 1: /* length is greater than 1, call fwrite. */
10099 {
10100 tree string_arg;
10101
10102 /* If optimizing for size keep fputs. */
10103 if (optimize_size)
10104 return 0;
10105 string_arg = TREE_VALUE (arglist);
10106 /* New argument list transforming fputs(string, stream) to
10107 fwrite(string, 1, len, stream). */
10108 arglist = build_tree_list (NULL_TREE,
10109 TREE_VALUE (TREE_CHAIN (arglist)));
10110 arglist = tree_cons (NULL_TREE, len, arglist);
10111 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10112 arglist = tree_cons (NULL_TREE, string_arg, arglist);
10113 fn = fn_fwrite;
10114 break;
10115 }
10116 default:
10117 gcc_unreachable ();
10118 }
10119
10120 /* If the replacement _DECL isn't initialized, don't do the
10121 transformation. */
10122 if (!fn)
10123 return 0;
10124
10125 /* These optimizations are only performed when the result is ignored,
10126 hence there's no need to cast the result to integer_type_node. */
10127 return build_function_call_expr (fn, arglist);
10128 }
10129
10130 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10131 produced. False otherwise. This is done so that we don't output the error
10132 or warning twice or three times. */
10133 bool
10134 fold_builtin_next_arg (tree arglist)
10135 {
10136 tree fntype = TREE_TYPE (current_function_decl);
10137
10138 if (TYPE_ARG_TYPES (fntype) == 0
10139 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10140 == void_type_node))
10141 {
10142 error ("%<va_start%> used in function with fixed args");
10143 return true;
10144 }
10145 else if (!arglist)
10146 {
10147 /* Evidently an out of date version of <stdarg.h>; can't validate
10148 va_start's second argument, but can still work as intended. */
10149 warning (0, "%<__builtin_next_arg%> called without an argument");
10150 return true;
10151 }
10152 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10153 when we checked the arguments and if needed issued a warning. */
10154 else if (!TREE_CHAIN (arglist)
10155 || !integer_zerop (TREE_VALUE (arglist))
10156 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10157 || TREE_CHAIN (TREE_CHAIN (arglist)))
10158 {
10159 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10160 tree arg = TREE_VALUE (arglist);
10161
10162 if (TREE_CHAIN (arglist))
10163 {
10164 error ("%<va_start%> used with too many arguments");
10165 return true;
10166 }
10167
10168 /* Strip off all nops for the sake of the comparison. This
10169 is not quite the same as STRIP_NOPS. It does more.
10170 We must also strip off INDIRECT_EXPR for C++ reference
10171 parameters. */
10172 while (TREE_CODE (arg) == NOP_EXPR
10173 || TREE_CODE (arg) == CONVERT_EXPR
10174 || TREE_CODE (arg) == NON_LVALUE_EXPR
10175 || TREE_CODE (arg) == INDIRECT_REF)
10176 arg = TREE_OPERAND (arg, 0);
10177 if (arg != last_parm)
10178 {
10179 /* FIXME: Sometimes with the tree optimizers we can get the
10180 not the last argument even though the user used the last
10181 argument. We just warn and set the arg to be the last
10182 argument so that we will get wrong-code because of
10183 it. */
10184 warning (0, "second parameter of %<va_start%> not last named argument");
10185 }
10186 /* We want to verify the second parameter just once before the tree
10187 optimizers are run and then avoid keeping it in the tree,
10188 as otherwise we could warn even for correct code like:
10189 void foo (int i, ...)
10190 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
10191 TREE_VALUE (arglist) = integer_zero_node;
10192 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10193 }
10194 return false;
10195 }
10196
10197
10198 /* Simplify a call to the sprintf builtin.
10199
10200 Return 0 if no simplification was possible, otherwise return the
10201 simplified form of the call as a tree. If IGNORED is true, it means that
10202 the caller does not use the returned value of the function. */
10203
10204 static tree
10205 fold_builtin_sprintf (tree arglist, int ignored)
10206 {
10207 tree call, retval, dest, fmt;
10208 const char *fmt_str = NULL;
10209
10210 /* Verify the required arguments in the original call. We deal with two
10211 types of sprintf() calls: 'sprintf (str, fmt)' and
10212 'sprintf (dest, "%s", orig)'. */
10213 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10214 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10215 VOID_TYPE))
10216 return NULL_TREE;
10217
10218 /* Get the destination string and the format specifier. */
10219 dest = TREE_VALUE (arglist);
10220 fmt = TREE_VALUE (TREE_CHAIN (arglist));
10221
10222 /* Check whether the format is a literal string constant. */
10223 fmt_str = c_getstr (fmt);
10224 if (fmt_str == NULL)
10225 return NULL_TREE;
10226
10227 call = NULL_TREE;
10228 retval = NULL_TREE;
10229
10230 if (!init_target_chars())
10231 return 0;
10232
10233 /* If the format doesn't contain % args or %%, use strcpy. */
10234 if (strchr (fmt_str, target_percent) == NULL)
10235 {
10236 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10237
10238 if (!fn)
10239 return NULL_TREE;
10240
10241 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10242 'format' is known to contain no % formats. */
10243 arglist = build_tree_list (NULL_TREE, fmt);
10244 arglist = tree_cons (NULL_TREE, dest, arglist);
10245 call = build_function_call_expr (fn, arglist);
10246 if (!ignored)
10247 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10248 }
10249
10250 /* If the format is "%s", use strcpy if the result isn't used. */
10251 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10252 {
10253 tree fn, orig;
10254 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10255
10256 if (!fn)
10257 return NULL_TREE;
10258
10259 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10260 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10261 arglist = build_tree_list (NULL_TREE, orig);
10262 arglist = tree_cons (NULL_TREE, dest, arglist);
10263 if (!ignored)
10264 {
10265 retval = c_strlen (orig, 1);
10266 if (!retval || TREE_CODE (retval) != INTEGER_CST)
10267 return NULL_TREE;
10268 }
10269 call = build_function_call_expr (fn, arglist);
10270 }
10271
10272 if (call && retval)
10273 {
10274 retval = fold_convert
10275 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10276 retval);
10277 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10278 }
10279 else
10280 return call;
10281 }
10282
10283 /* Expand a call to __builtin_object_size. */
10284
10285 rtx
10286 expand_builtin_object_size (tree exp)
10287 {
10288 tree ost;
10289 int object_size_type;
10290 tree fndecl = get_callee_fndecl (exp);
10291 tree arglist = TREE_OPERAND (exp, 1);
10292 location_t locus = EXPR_LOCATION (exp);
10293
10294 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10295 {
10296 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10297 &locus, fndecl);
10298 expand_builtin_trap ();
10299 return const0_rtx;
10300 }
10301
10302 ost = TREE_VALUE (TREE_CHAIN (arglist));
10303 STRIP_NOPS (ost);
10304
10305 if (TREE_CODE (ost) != INTEGER_CST
10306 || tree_int_cst_sgn (ost) < 0
10307 || compare_tree_int (ost, 3) > 0)
10308 {
10309 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10310 &locus, fndecl);
10311 expand_builtin_trap ();
10312 return const0_rtx;
10313 }
10314
10315 object_size_type = tree_low_cst (ost, 0);
10316
10317 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10318 }
10319
10320 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10321 FCODE is the BUILT_IN_* to use.
10322 Return 0 if we failed; the caller should emit a normal call,
10323 otherwise try to get the result in TARGET, if convenient (and in
10324 mode MODE if that's convenient). */
10325
10326 static rtx
10327 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10328 enum built_in_function fcode)
10329 {
10330 tree arglist = TREE_OPERAND (exp, 1);
10331 tree dest, src, len, size;
10332
10333 if (!validate_arglist (arglist,
10334 POINTER_TYPE,
10335 fcode == BUILT_IN_MEMSET_CHK
10336 ? INTEGER_TYPE : POINTER_TYPE,
10337 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10338 return 0;
10339
10340 dest = TREE_VALUE (arglist);
10341 src = TREE_VALUE (TREE_CHAIN (arglist));
10342 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10343 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10344
10345 if (! host_integerp (size, 1))
10346 return 0;
10347
10348 if (host_integerp (len, 1) || integer_all_onesp (size))
10349 {
10350 tree fn;
10351
10352 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10353 {
10354 location_t locus = EXPR_LOCATION (exp);
10355 warning (0, "%Hcall to %D will always overflow destination buffer",
10356 &locus, get_callee_fndecl (exp));
10357 return 0;
10358 }
10359
10360 arglist = build_tree_list (NULL_TREE, len);
10361 arglist = tree_cons (NULL_TREE, src, arglist);
10362 arglist = tree_cons (NULL_TREE, dest, arglist);
10363
10364 fn = NULL_TREE;
10365 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10366 mem{cpy,pcpy,move,set} is available. */
10367 switch (fcode)
10368 {
10369 case BUILT_IN_MEMCPY_CHK:
10370 fn = built_in_decls[BUILT_IN_MEMCPY];
10371 break;
10372 case BUILT_IN_MEMPCPY_CHK:
10373 fn = built_in_decls[BUILT_IN_MEMPCPY];
10374 break;
10375 case BUILT_IN_MEMMOVE_CHK:
10376 fn = built_in_decls[BUILT_IN_MEMMOVE];
10377 break;
10378 case BUILT_IN_MEMSET_CHK:
10379 fn = built_in_decls[BUILT_IN_MEMSET];
10380 break;
10381 default:
10382 break;
10383 }
10384
10385 if (! fn)
10386 return 0;
10387
10388 fn = build_function_call_expr (fn, arglist);
10389 if (TREE_CODE (fn) == CALL_EXPR)
10390 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10391 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10392 }
10393 else if (fcode == BUILT_IN_MEMSET_CHK)
10394 return 0;
10395 else
10396 {
10397 unsigned int dest_align
10398 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10399
10400 /* If DEST is not a pointer type, call the normal function. */
10401 if (dest_align == 0)
10402 return 0;
10403
10404 /* If SRC and DEST are the same (and not volatile), do nothing. */
10405 if (operand_equal_p (src, dest, 0))
10406 {
10407 tree expr;
10408
10409 if (fcode != BUILT_IN_MEMPCPY_CHK)
10410 {
10411 /* Evaluate and ignore LEN in case it has side-effects. */
10412 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10413 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10414 }
10415
10416 len = fold_convert (TREE_TYPE (dest), len);
10417 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10418 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10419 }
10420
10421 /* __memmove_chk special case. */
10422 if (fcode == BUILT_IN_MEMMOVE_CHK)
10423 {
10424 unsigned int src_align
10425 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10426
10427 if (src_align == 0)
10428 return 0;
10429
10430 /* If src is categorized for a readonly section we can use
10431 normal __memcpy_chk. */
10432 if (readonly_data_expr (src))
10433 {
10434 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10435 if (!fn)
10436 return 0;
10437 fn = build_function_call_expr (fn, arglist);
10438 if (TREE_CODE (fn) == CALL_EXPR)
10439 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10440 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10441 }
10442 }
10443 return 0;
10444 }
10445 }
10446
10447 /* Emit warning if a buffer overflow is detected at compile time. */
10448
10449 static void
10450 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10451 {
10452 int arg_mask, is_strlen = 0;
10453 tree arglist = TREE_OPERAND (exp, 1), a;
10454 tree len, size;
10455 location_t locus;
10456
10457 switch (fcode)
10458 {
10459 case BUILT_IN_STRCPY_CHK:
10460 case BUILT_IN_STPCPY_CHK:
10461 /* For __strcat_chk the warning will be emitted only if overflowing
10462 by at least strlen (dest) + 1 bytes. */
10463 case BUILT_IN_STRCAT_CHK:
10464 arg_mask = 6;
10465 is_strlen = 1;
10466 break;
10467 case BUILT_IN_STRNCAT_CHK:
10468 /* For __strncat_chk the warning will be emitted only if overflowing
10469 by at least strlen (dest) + 1 bytes. */
10470 arg_mask = 12;
10471 break;
10472 case BUILT_IN_STRNCPY_CHK:
10473 arg_mask = 12;
10474 break;
10475 case BUILT_IN_SNPRINTF_CHK:
10476 case BUILT_IN_VSNPRINTF_CHK:
10477 arg_mask = 10;
10478 break;
10479 default:
10480 gcc_unreachable ();
10481 }
10482
10483 len = NULL_TREE;
10484 size = NULL_TREE;
10485 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10486 if (arg_mask & 1)
10487 {
10488 if (len)
10489 size = a;
10490 else
10491 len = a;
10492 }
10493
10494 if (!len || !size)
10495 return;
10496
10497 len = TREE_VALUE (len);
10498 size = TREE_VALUE (size);
10499
10500 if (! host_integerp (size, 1) || integer_all_onesp (size))
10501 return;
10502
10503 if (is_strlen)
10504 {
10505 len = c_strlen (len, 1);
10506 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10507 return;
10508 }
10509 else if (fcode == BUILT_IN_STRNCAT_CHK)
10510 {
10511 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10512 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10513 return;
10514 src = c_strlen (src, 1);
10515 if (! src || ! host_integerp (src, 1))
10516 {
10517 locus = EXPR_LOCATION (exp);
10518 warning (0, "%Hcall to %D might overflow destination buffer",
10519 &locus, get_callee_fndecl (exp));
10520 return;
10521 }
10522 else if (tree_int_cst_lt (src, size))
10523 return;
10524 }
10525 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10526 return;
10527
10528 locus = EXPR_LOCATION (exp);
10529 warning (0, "%Hcall to %D will always overflow destination buffer",
10530 &locus, get_callee_fndecl (exp));
10531 }
10532
10533 /* Emit warning if a buffer overflow is detected at compile time
10534 in __sprintf_chk/__vsprintf_chk calls. */
10535
10536 static void
10537 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10538 {
10539 tree arglist = TREE_OPERAND (exp, 1);
10540 tree dest, size, len, fmt, flag;
10541 const char *fmt_str;
10542
10543 /* Verify the required arguments in the original call. */
10544 if (! arglist)
10545 return;
10546 dest = TREE_VALUE (arglist);
10547 arglist = TREE_CHAIN (arglist);
10548 if (! arglist)
10549 return;
10550 flag = TREE_VALUE (arglist);
10551 arglist = TREE_CHAIN (arglist);
10552 if (! arglist)
10553 return;
10554 size = TREE_VALUE (arglist);
10555 arglist = TREE_CHAIN (arglist);
10556 if (! arglist)
10557 return;
10558 fmt = TREE_VALUE (arglist);
10559 arglist = TREE_CHAIN (arglist);
10560
10561 if (! host_integerp (size, 1) || integer_all_onesp (size))
10562 return;
10563
10564 /* Check whether the format is a literal string constant. */
10565 fmt_str = c_getstr (fmt);
10566 if (fmt_str == NULL)
10567 return;
10568
10569 if (!init_target_chars())
10570 return;
10571
10572 /* If the format doesn't contain % args or %%, we know its size. */
10573 if (strchr (fmt_str, target_percent) == 0)
10574 len = build_int_cstu (size_type_node, strlen (fmt_str));
10575 /* If the format is "%s" and first ... argument is a string literal,
10576 we know it too. */
10577 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10578 {
10579 tree arg;
10580
10581 if (! arglist)
10582 return;
10583 arg = TREE_VALUE (arglist);
10584 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10585 return;
10586
10587 len = c_strlen (arg, 1);
10588 if (!len || ! host_integerp (len, 1))
10589 return;
10590 }
10591 else
10592 return;
10593
10594 if (! tree_int_cst_lt (len, size))
10595 {
10596 location_t locus = EXPR_LOCATION (exp);
10597 warning (0, "%Hcall to %D will always overflow destination buffer",
10598 &locus, get_callee_fndecl (exp));
10599 }
10600 }
10601
10602 /* Fold a call to __builtin_object_size, if possible. */
10603
10604 tree
10605 fold_builtin_object_size (tree arglist)
10606 {
10607 tree ptr, ost, ret = 0;
10608 int object_size_type;
10609
10610 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10611 return 0;
10612
10613 ptr = TREE_VALUE (arglist);
10614 ost = TREE_VALUE (TREE_CHAIN (arglist));
10615 STRIP_NOPS (ost);
10616
10617 if (TREE_CODE (ost) != INTEGER_CST
10618 || tree_int_cst_sgn (ost) < 0
10619 || compare_tree_int (ost, 3) > 0)
10620 return 0;
10621
10622 object_size_type = tree_low_cst (ost, 0);
10623
10624 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10625 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10626 and (size_t) 0 for types 2 and 3. */
10627 if (TREE_SIDE_EFFECTS (ptr))
10628 return fold_convert (size_type_node,
10629 object_size_type < 2
10630 ? integer_minus_one_node : integer_zero_node);
10631
10632 if (TREE_CODE (ptr) == ADDR_EXPR)
10633 ret = build_int_cstu (size_type_node,
10634 compute_builtin_object_size (ptr, object_size_type));
10635
10636 else if (TREE_CODE (ptr) == SSA_NAME)
10637 {
10638 unsigned HOST_WIDE_INT bytes;
10639
10640 /* If object size is not known yet, delay folding until
10641 later. Maybe subsequent passes will help determining
10642 it. */
10643 bytes = compute_builtin_object_size (ptr, object_size_type);
10644 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10645 ? -1 : 0))
10646 ret = build_int_cstu (size_type_node, bytes);
10647 }
10648
10649 if (ret)
10650 {
10651 ret = force_fit_type (ret, -1, false, false);
10652 if (TREE_CONSTANT_OVERFLOW (ret))
10653 ret = 0;
10654 }
10655
10656 return ret;
10657 }
10658
10659 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10660 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10661 code of the builtin. If MAXLEN is not NULL, it is maximum length
10662 passed as third argument. */
10663
10664 tree
10665 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10666 enum built_in_function fcode)
10667 {
10668 tree dest, src, len, size, fn;
10669
10670 if (!validate_arglist (arglist,
10671 POINTER_TYPE,
10672 fcode == BUILT_IN_MEMSET_CHK
10673 ? INTEGER_TYPE : POINTER_TYPE,
10674 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10675 return 0;
10676
10677 dest = TREE_VALUE (arglist);
10678 /* Actually val for __memset_chk, but it doesn't matter. */
10679 src = TREE_VALUE (TREE_CHAIN (arglist));
10680 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10681 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10682
10683 /* If SRC and DEST are the same (and not volatile), return DEST
10684 (resp. DEST+LEN for __mempcpy_chk). */
10685 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10686 {
10687 if (fcode != BUILT_IN_MEMPCPY_CHK)
10688 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10689 else
10690 {
10691 tree temp = fold_convert (TREE_TYPE (dest), len);
10692 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10693 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10694 }
10695 }
10696
10697 if (! host_integerp (size, 1))
10698 return 0;
10699
10700 if (! integer_all_onesp (size))
10701 {
10702 if (! host_integerp (len, 1))
10703 {
10704 /* If LEN is not constant, try MAXLEN too.
10705 For MAXLEN only allow optimizing into non-_ocs function
10706 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10707 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10708 {
10709 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10710 {
10711 /* (void) __mempcpy_chk () can be optimized into
10712 (void) __memcpy_chk (). */
10713 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10714 if (!fn)
10715 return 0;
10716
10717 return build_function_call_expr (fn, arglist);
10718 }
10719 return 0;
10720 }
10721 }
10722 else
10723 maxlen = len;
10724
10725 if (tree_int_cst_lt (size, maxlen))
10726 return 0;
10727 }
10728
10729 arglist = build_tree_list (NULL_TREE, len);
10730 arglist = tree_cons (NULL_TREE, src, arglist);
10731 arglist = tree_cons (NULL_TREE, dest, arglist);
10732
10733 fn = NULL_TREE;
10734 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10735 mem{cpy,pcpy,move,set} is available. */
10736 switch (fcode)
10737 {
10738 case BUILT_IN_MEMCPY_CHK:
10739 fn = built_in_decls[BUILT_IN_MEMCPY];
10740 break;
10741 case BUILT_IN_MEMPCPY_CHK:
10742 fn = built_in_decls[BUILT_IN_MEMPCPY];
10743 break;
10744 case BUILT_IN_MEMMOVE_CHK:
10745 fn = built_in_decls[BUILT_IN_MEMMOVE];
10746 break;
10747 case BUILT_IN_MEMSET_CHK:
10748 fn = built_in_decls[BUILT_IN_MEMSET];
10749 break;
10750 default:
10751 break;
10752 }
10753
10754 if (!fn)
10755 return 0;
10756
10757 return build_function_call_expr (fn, arglist);
10758 }
10759
10760 /* Fold a call to the __st[rp]cpy_chk builtin.
10761 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10762 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10763 strings passed as second argument. */
10764
10765 tree
10766 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10767 enum built_in_function fcode)
10768 {
10769 tree dest, src, size, len, fn;
10770
10771 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10772 VOID_TYPE))
10773 return 0;
10774
10775 dest = TREE_VALUE (arglist);
10776 src = TREE_VALUE (TREE_CHAIN (arglist));
10777 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10778
10779 /* If SRC and DEST are the same (and not volatile), return DEST. */
10780 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10781 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10782
10783 if (! host_integerp (size, 1))
10784 return 0;
10785
10786 if (! integer_all_onesp (size))
10787 {
10788 len = c_strlen (src, 1);
10789 if (! len || ! host_integerp (len, 1))
10790 {
10791 /* If LEN is not constant, try MAXLEN too.
10792 For MAXLEN only allow optimizing into non-_ocs function
10793 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10794 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10795 {
10796 if (fcode == BUILT_IN_STPCPY_CHK)
10797 {
10798 if (! ignore)
10799 return 0;
10800
10801 /* If return value of __stpcpy_chk is ignored,
10802 optimize into __strcpy_chk. */
10803 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10804 if (!fn)
10805 return 0;
10806
10807 return build_function_call_expr (fn, arglist);
10808 }
10809
10810 if (! len || TREE_SIDE_EFFECTS (len))
10811 return 0;
10812
10813 /* If c_strlen returned something, but not a constant,
10814 transform __strcpy_chk into __memcpy_chk. */
10815 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10816 if (!fn)
10817 return 0;
10818
10819 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10820 arglist = build_tree_list (NULL_TREE, size);
10821 arglist = tree_cons (NULL_TREE, len, arglist);
10822 arglist = tree_cons (NULL_TREE, src, arglist);
10823 arglist = tree_cons (NULL_TREE, dest, arglist);
10824 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10825 build_function_call_expr (fn, arglist));
10826 }
10827 }
10828 else
10829 maxlen = len;
10830
10831 if (! tree_int_cst_lt (maxlen, size))
10832 return 0;
10833 }
10834
10835 arglist = build_tree_list (NULL_TREE, src);
10836 arglist = tree_cons (NULL_TREE, dest, arglist);
10837
10838 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10839 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10840 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10841 if (!fn)
10842 return 0;
10843
10844 return build_function_call_expr (fn, arglist);
10845 }
10846
10847 /* Fold a call to the __strncpy_chk builtin.
10848 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10849
10850 tree
10851 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10852 {
10853 tree dest, src, size, len, fn;
10854
10855 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10856 INTEGER_TYPE, VOID_TYPE))
10857 return 0;
10858
10859 dest = TREE_VALUE (arglist);
10860 src = TREE_VALUE (TREE_CHAIN (arglist));
10861 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10862 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10863
10864 if (! host_integerp (size, 1))
10865 return 0;
10866
10867 if (! integer_all_onesp (size))
10868 {
10869 if (! host_integerp (len, 1))
10870 {
10871 /* If LEN is not constant, try MAXLEN too.
10872 For MAXLEN only allow optimizing into non-_ocs function
10873 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10874 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10875 return 0;
10876 }
10877 else
10878 maxlen = len;
10879
10880 if (tree_int_cst_lt (size, maxlen))
10881 return 0;
10882 }
10883
10884 arglist = build_tree_list (NULL_TREE, len);
10885 arglist = tree_cons (NULL_TREE, src, arglist);
10886 arglist = tree_cons (NULL_TREE, dest, arglist);
10887
10888 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10889 fn = built_in_decls[BUILT_IN_STRNCPY];
10890 if (!fn)
10891 return 0;
10892
10893 return build_function_call_expr (fn, arglist);
10894 }
10895
10896 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10897
10898 static tree
10899 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10900 {
10901 tree dest, src, size, fn;
10902 const char *p;
10903
10904 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10905 VOID_TYPE))
10906 return 0;
10907
10908 dest = TREE_VALUE (arglist);
10909 src = TREE_VALUE (TREE_CHAIN (arglist));
10910 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10911
10912 p = c_getstr (src);
10913 /* If the SRC parameter is "", return DEST. */
10914 if (p && *p == '\0')
10915 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10916
10917 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10918 return 0;
10919
10920 arglist = build_tree_list (NULL_TREE, src);
10921 arglist = tree_cons (NULL_TREE, dest, arglist);
10922
10923 /* If __builtin_strcat_chk is used, assume strcat is available. */
10924 fn = built_in_decls[BUILT_IN_STRCAT];
10925 if (!fn)
10926 return 0;
10927
10928 return build_function_call_expr (fn, arglist);
10929 }
10930
10931 /* Fold a call to the __strncat_chk builtin EXP. */
10932
10933 static tree
10934 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10935 {
10936 tree dest, src, size, len, fn;
10937 const char *p;
10938
10939 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10940 INTEGER_TYPE, VOID_TYPE))
10941 return 0;
10942
10943 dest = TREE_VALUE (arglist);
10944 src = TREE_VALUE (TREE_CHAIN (arglist));
10945 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10946 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10947
10948 p = c_getstr (src);
10949 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10950 if (p && *p == '\0')
10951 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10952 else if (integer_zerop (len))
10953 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10954
10955 if (! host_integerp (size, 1))
10956 return 0;
10957
10958 if (! integer_all_onesp (size))
10959 {
10960 tree src_len = c_strlen (src, 1);
10961 if (src_len
10962 && host_integerp (src_len, 1)
10963 && host_integerp (len, 1)
10964 && ! tree_int_cst_lt (len, src_len))
10965 {
10966 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10967 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10968 if (!fn)
10969 return 0;
10970
10971 arglist = build_tree_list (NULL_TREE, size);
10972 arglist = tree_cons (NULL_TREE, src, arglist);
10973 arglist = tree_cons (NULL_TREE, dest, arglist);
10974 return build_function_call_expr (fn, arglist);
10975 }
10976 return 0;
10977 }
10978
10979 arglist = build_tree_list (NULL_TREE, len);
10980 arglist = tree_cons (NULL_TREE, src, arglist);
10981 arglist = tree_cons (NULL_TREE, dest, arglist);
10982
10983 /* If __builtin_strncat_chk is used, assume strncat is available. */
10984 fn = built_in_decls[BUILT_IN_STRNCAT];
10985 if (!fn)
10986 return 0;
10987
10988 return build_function_call_expr (fn, arglist);
10989 }
10990
10991 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10992 a normal call should be emitted rather than expanding the function
10993 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10994
10995 static tree
10996 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10997 {
10998 tree dest, size, len, fn, fmt, flag;
10999 const char *fmt_str;
11000
11001 /* Verify the required arguments in the original call. */
11002 if (! arglist)
11003 return 0;
11004 dest = TREE_VALUE (arglist);
11005 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11006 return 0;
11007 arglist = TREE_CHAIN (arglist);
11008 if (! arglist)
11009 return 0;
11010 flag = TREE_VALUE (arglist);
11011 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11012 return 0;
11013 arglist = TREE_CHAIN (arglist);
11014 if (! arglist)
11015 return 0;
11016 size = TREE_VALUE (arglist);
11017 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11018 return 0;
11019 arglist = TREE_CHAIN (arglist);
11020 if (! arglist)
11021 return 0;
11022 fmt = TREE_VALUE (arglist);
11023 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11024 return 0;
11025 arglist = TREE_CHAIN (arglist);
11026
11027 if (! host_integerp (size, 1))
11028 return 0;
11029
11030 len = NULL_TREE;
11031
11032 if (!init_target_chars())
11033 return 0;
11034
11035 /* Check whether the format is a literal string constant. */
11036 fmt_str = c_getstr (fmt);
11037 if (fmt_str != NULL)
11038 {
11039 /* If the format doesn't contain % args or %%, we know the size. */
11040 if (strchr (fmt_str, target_percent) == 0)
11041 {
11042 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11043 len = build_int_cstu (size_type_node, strlen (fmt_str));
11044 }
11045 /* If the format is "%s" and first ... argument is a string literal,
11046 we know the size too. */
11047 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11048 {
11049 tree arg;
11050
11051 if (arglist && !TREE_CHAIN (arglist))
11052 {
11053 arg = TREE_VALUE (arglist);
11054 if (POINTER_TYPE_P (TREE_TYPE (arg)))
11055 {
11056 len = c_strlen (arg, 1);
11057 if (! len || ! host_integerp (len, 1))
11058 len = NULL_TREE;
11059 }
11060 }
11061 }
11062 }
11063
11064 if (! integer_all_onesp (size))
11065 {
11066 if (! len || ! tree_int_cst_lt (len, size))
11067 return 0;
11068 }
11069
11070 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11071 or if format doesn't contain % chars or is "%s". */
11072 if (! integer_zerop (flag))
11073 {
11074 if (fmt_str == NULL)
11075 return 0;
11076 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11077 return 0;
11078 }
11079
11080 arglist = tree_cons (NULL_TREE, fmt, arglist);
11081 arglist = tree_cons (NULL_TREE, dest, arglist);
11082
11083 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
11084 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11085 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11086 if (!fn)
11087 return 0;
11088
11089 return build_function_call_expr (fn, arglist);
11090 }
11091
11092 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
11093 a normal call should be emitted rather than expanding the function
11094 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
11095 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
11096 passed as second argument. */
11097
11098 tree
11099 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11100 enum built_in_function fcode)
11101 {
11102 tree dest, size, len, fn, fmt, flag;
11103 const char *fmt_str;
11104
11105 /* Verify the required arguments in the original call. */
11106 if (! arglist)
11107 return 0;
11108 dest = TREE_VALUE (arglist);
11109 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11110 return 0;
11111 arglist = TREE_CHAIN (arglist);
11112 if (! arglist)
11113 return 0;
11114 len = TREE_VALUE (arglist);
11115 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11116 return 0;
11117 arglist = TREE_CHAIN (arglist);
11118 if (! arglist)
11119 return 0;
11120 flag = TREE_VALUE (arglist);
11121 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11122 return 0;
11123 arglist = TREE_CHAIN (arglist);
11124 if (! arglist)
11125 return 0;
11126 size = TREE_VALUE (arglist);
11127 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11128 return 0;
11129 arglist = TREE_CHAIN (arglist);
11130 if (! arglist)
11131 return 0;
11132 fmt = TREE_VALUE (arglist);
11133 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11134 return 0;
11135 arglist = TREE_CHAIN (arglist);
11136
11137 if (! host_integerp (size, 1))
11138 return 0;
11139
11140 if (! integer_all_onesp (size))
11141 {
11142 if (! host_integerp (len, 1))
11143 {
11144 /* If LEN is not constant, try MAXLEN too.
11145 For MAXLEN only allow optimizing into non-_ocs function
11146 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11147 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11148 return 0;
11149 }
11150 else
11151 maxlen = len;
11152
11153 if (tree_int_cst_lt (size, maxlen))
11154 return 0;
11155 }
11156
11157 if (!init_target_chars())
11158 return 0;
11159
11160 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11161 or if format doesn't contain % chars or is "%s". */
11162 if (! integer_zerop (flag))
11163 {
11164 fmt_str = c_getstr (fmt);
11165 if (fmt_str == NULL)
11166 return 0;
11167 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11168 return 0;
11169 }
11170
11171 arglist = tree_cons (NULL_TREE, fmt, arglist);
11172 arglist = tree_cons (NULL_TREE, len, arglist);
11173 arglist = tree_cons (NULL_TREE, dest, arglist);
11174
11175 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11176 available. */
11177 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11178 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11179 if (!fn)
11180 return 0;
11181
11182 return build_function_call_expr (fn, arglist);
11183 }
11184
11185 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11186
11187 Return 0 if no simplification was possible, otherwise return the
11188 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11189 code of the function to be simplified. */
11190
11191 static tree
11192 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11193 enum built_in_function fcode)
11194 {
11195 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11196 const char *fmt_str = NULL;
11197
11198 /* If the return value is used, don't do the transformation. */
11199 if (! ignore)
11200 return 0;
11201
11202 /* Verify the required arguments in the original call. */
11203 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11204 {
11205 tree flag;
11206
11207 if (! arglist)
11208 return 0;
11209 flag = TREE_VALUE (arglist);
11210 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11211 || TREE_SIDE_EFFECTS (flag))
11212 return 0;
11213 arglist = TREE_CHAIN (arglist);
11214 }
11215
11216 if (! arglist)
11217 return 0;
11218 fmt = TREE_VALUE (arglist);
11219 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11220 return 0;
11221 arglist = TREE_CHAIN (arglist);
11222
11223 /* Check whether the format is a literal string constant. */
11224 fmt_str = c_getstr (fmt);
11225 if (fmt_str == NULL)
11226 return NULL_TREE;
11227
11228 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11229 {
11230 /* If we're using an unlocked function, assume the other
11231 unlocked functions exist explicitly. */
11232 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11233 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11234 }
11235 else
11236 {
11237 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11238 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11239 }
11240
11241 if (!init_target_chars())
11242 return 0;
11243
11244 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11245 {
11246 const char *str;
11247
11248 if (strcmp (fmt_str, target_percent_s) == 0)
11249 {
11250 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11251 return 0;
11252
11253 if (! arglist
11254 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11255 || TREE_CHAIN (arglist))
11256 return 0;
11257
11258 str = c_getstr (TREE_VALUE (arglist));
11259 if (str == NULL)
11260 return 0;
11261 }
11262 else
11263 {
11264 /* The format specifier doesn't contain any '%' characters. */
11265 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11266 && arglist)
11267 return 0;
11268 str = fmt_str;
11269 }
11270
11271 /* If the string was "", printf does nothing. */
11272 if (str[0] == '\0')
11273 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11274
11275 /* If the string has length of 1, call putchar. */
11276 if (str[1] == '\0')
11277 {
11278 /* Given printf("c"), (where c is any one character,)
11279 convert "c"[0] to an int and pass that to the replacement
11280 function. */
11281 arg = build_int_cst (NULL_TREE, str[0]);
11282 arglist = build_tree_list (NULL_TREE, arg);
11283 fn = fn_putchar;
11284 }
11285 else
11286 {
11287 /* If the string was "string\n", call puts("string"). */
11288 size_t len = strlen (str);
11289 if ((unsigned char)str[len - 1] == target_newline)
11290 {
11291 /* Create a NUL-terminated string that's one char shorter
11292 than the original, stripping off the trailing '\n'. */
11293 char *newstr = alloca (len);
11294 memcpy (newstr, str, len - 1);
11295 newstr[len - 1] = 0;
11296
11297 arg = build_string_literal (len, newstr);
11298 arglist = build_tree_list (NULL_TREE, arg);
11299 fn = fn_puts;
11300 }
11301 else
11302 /* We'd like to arrange to call fputs(string,stdout) here,
11303 but we need stdout and don't have a way to get it yet. */
11304 return 0;
11305 }
11306 }
11307
11308 /* The other optimizations can be done only on the non-va_list variants. */
11309 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11310 return 0;
11311
11312 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11313 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11314 {
11315 if (! arglist
11316 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11317 || TREE_CHAIN (arglist))
11318 return 0;
11319 fn = fn_puts;
11320 }
11321
11322 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11323 else if (strcmp (fmt_str, target_percent_c) == 0)
11324 {
11325 if (! arglist
11326 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11327 || TREE_CHAIN (arglist))
11328 return 0;
11329 fn = fn_putchar;
11330 }
11331
11332 if (!fn)
11333 return 0;
11334
11335 call = build_function_call_expr (fn, arglist);
11336 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11337 }
11338
11339 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11340
11341 Return 0 if no simplification was possible, otherwise return the
11342 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11343 code of the function to be simplified. */
11344
11345 static tree
11346 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11347 enum built_in_function fcode)
11348 {
11349 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11350 const char *fmt_str = NULL;
11351
11352 /* If the return value is used, don't do the transformation. */
11353 if (! ignore)
11354 return 0;
11355
11356 /* Verify the required arguments in the original call. */
11357 if (! arglist)
11358 return 0;
11359 fp = TREE_VALUE (arglist);
11360 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11361 return 0;
11362 arglist = TREE_CHAIN (arglist);
11363
11364 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11365 {
11366 tree flag;
11367
11368 if (! arglist)
11369 return 0;
11370 flag = TREE_VALUE (arglist);
11371 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11372 || TREE_SIDE_EFFECTS (flag))
11373 return 0;
11374 arglist = TREE_CHAIN (arglist);
11375 }
11376
11377 if (! arglist)
11378 return 0;
11379 fmt = TREE_VALUE (arglist);
11380 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11381 return 0;
11382 arglist = TREE_CHAIN (arglist);
11383
11384 /* Check whether the format is a literal string constant. */
11385 fmt_str = c_getstr (fmt);
11386 if (fmt_str == NULL)
11387 return NULL_TREE;
11388
11389 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11390 {
11391 /* If we're using an unlocked function, assume the other
11392 unlocked functions exist explicitly. */
11393 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11394 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11395 }
11396 else
11397 {
11398 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11399 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11400 }
11401
11402 if (!init_target_chars())
11403 return 0;
11404
11405 /* If the format doesn't contain % args or %%, use strcpy. */
11406 if (strchr (fmt_str, target_percent) == NULL)
11407 {
11408 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11409 && arglist)
11410 return 0;
11411
11412 /* If the format specifier was "", fprintf does nothing. */
11413 if (fmt_str[0] == '\0')
11414 {
11415 /* If FP has side-effects, just wait until gimplification is
11416 done. */
11417 if (TREE_SIDE_EFFECTS (fp))
11418 return 0;
11419
11420 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11421 }
11422
11423 /* When "string" doesn't contain %, replace all cases of
11424 fprintf (fp, string) with fputs (string, fp). The fputs
11425 builtin will take care of special cases like length == 1. */
11426 arglist = build_tree_list (NULL_TREE, fp);
11427 arglist = tree_cons (NULL_TREE, fmt, arglist);
11428 fn = fn_fputs;
11429 }
11430
11431 /* The other optimizations can be done only on the non-va_list variants. */
11432 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11433 return 0;
11434
11435 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11436 else if (strcmp (fmt_str, target_percent_s) == 0)
11437 {
11438 if (! arglist
11439 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11440 || TREE_CHAIN (arglist))
11441 return 0;
11442 arg = TREE_VALUE (arglist);
11443 arglist = build_tree_list (NULL_TREE, fp);
11444 arglist = tree_cons (NULL_TREE, arg, arglist);
11445 fn = fn_fputs;
11446 }
11447
11448 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11449 else if (strcmp (fmt_str, target_percent_c) == 0)
11450 {
11451 if (! arglist
11452 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11453 || TREE_CHAIN (arglist))
11454 return 0;
11455 arg = TREE_VALUE (arglist);
11456 arglist = build_tree_list (NULL_TREE, fp);
11457 arglist = tree_cons (NULL_TREE, arg, arglist);
11458 fn = fn_fputc;
11459 }
11460
11461 if (!fn)
11462 return 0;
11463
11464 call = build_function_call_expr (fn, arglist);
11465 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11466 }
11467
11468 /* Initialize format string characters in the target charset. */
11469
11470 static bool
11471 init_target_chars (void)
11472 {
11473 static bool init;
11474 if (!init)
11475 {
11476 target_newline = lang_hooks.to_target_charset ('\n');
11477 target_percent = lang_hooks.to_target_charset ('%');
11478 target_c = lang_hooks.to_target_charset ('c');
11479 target_s = lang_hooks.to_target_charset ('s');
11480 if (target_newline == 0 || target_percent == 0 || target_c == 0
11481 || target_s == 0)
11482 return false;
11483
11484 target_percent_c[0] = target_percent;
11485 target_percent_c[1] = target_c;
11486 target_percent_c[2] = '\0';
11487
11488 target_percent_s[0] = target_percent;
11489 target_percent_s[1] = target_s;
11490 target_percent_s[2] = '\0';
11491
11492 target_percent_s_newline[0] = target_percent;
11493 target_percent_s_newline[1] = target_s;
11494 target_percent_s_newline[2] = target_newline;
11495 target_percent_s_newline[3] = '\0';
11496
11497 init = true;
11498 }
11499 return true;
11500 }
11501
11502 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
11503 and no overflow/underflow occurred. INEXACT is true if M was not
11504 exactly calculated. TYPE is the tree type for the result. This
11505 function assumes that you cleared the MPFR flags and then
11506 calculated M to see if anything subsequently set a flag prior to
11507 entering this function. Return NULL_TREE if any checks fail. */
11508
11509 static tree
11510 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11511 {
11512 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11513 overflow/underflow occurred. If -frounding-math, proceed iff the
11514 result of calling FUNC was exact. */
11515 if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11516 && (!flag_rounding_math || !inexact))
11517 {
11518 REAL_VALUE_TYPE rr;
11519
11520 real_from_mpfr (&rr, m);
11521 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11522 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
11523 but the mpft_t is not, then we underflowed in the
11524 conversion. */
11525 if (!real_isnan (&rr) && !real_isinf (&rr)
11526 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11527 {
11528 REAL_VALUE_TYPE rmode;
11529
11530 real_convert (&rmode, TYPE_MODE (type), &rr);
11531 /* Proceed iff the specified mode can hold the value. */
11532 if (real_identical (&rmode, &rr))
11533 return build_real (type, rmode);
11534 }
11535 }
11536 return NULL_TREE;
11537 }
11538
11539 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11540 FUNC on it and return the resulting value as a tree with type TYPE.
11541 If MIN and/or MAX are not NULL, then the supplied ARG must be
11542 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11543 acceptable values, otherwise they are not. The mpfr precision is
11544 set to the precision of TYPE. We assume that function FUNC returns
11545 zero if the result could be calculated exactly within the requested
11546 precision. */
11547
11548 static tree
11549 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11550 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11551 bool inclusive)
11552 {
11553 tree result = NULL_TREE;
11554
11555 STRIP_NOPS (arg);
11556
11557 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11558 {
11559 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11560
11561 if (!real_isnan (ra) && !real_isinf (ra)
11562 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11563 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11564 {
11565 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11566 int inexact;
11567 mpfr_t m;
11568
11569 mpfr_init2 (m, prec);
11570 mpfr_from_real (m, ra);
11571 mpfr_clear_flags();
11572 inexact = func (m, m, GMP_RNDN);
11573 result = do_mpfr_ckconv (m, type, inexact);
11574 mpfr_clear (m);
11575 }
11576 }
11577
11578 return result;
11579 }
11580
11581 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11582 FUNC on it and return the resulting value as a tree with type TYPE.
11583 The mpfr precision is set to the precision of TYPE. We assume that
11584 function FUNC returns zero if the result could be calculated
11585 exactly within the requested precision. */
11586
11587 static tree
11588 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11589 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11590 {
11591 tree result = NULL_TREE;
11592
11593 STRIP_NOPS (arg1);
11594 STRIP_NOPS (arg2);
11595
11596 if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11597 && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2))
11598 {
11599 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11600 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11601
11602 if (!real_isnan (ra1) && !real_isinf (ra1)
11603 && !real_isnan (ra2) && !real_isinf (ra2))
11604 {
11605 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11606 int inexact;
11607 mpfr_t m1, m2;
11608
11609 mpfr_inits2 (prec, m1, m2, NULL);
11610 mpfr_from_real (m1, ra1);
11611 mpfr_from_real (m2, ra2);
11612 mpfr_clear_flags();
11613 inexact = func (m1, m1, m2, GMP_RNDN);
11614 result = do_mpfr_ckconv (m1, type, inexact);
11615 mpfr_clears (m1, m2, NULL);
11616 }
11617 }
11618
11619 return result;
11620 }
11621
11622 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11623 FUNC on it and return the resulting value as a tree with type TYPE.
11624 The mpfr precision is set to the precision of TYPE. We assume that
11625 function FUNC returns zero if the result could be calculated
11626 exactly within the requested precision. */
11627
11628 static tree
11629 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11630 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11631 {
11632 tree result = NULL_TREE;
11633
11634 STRIP_NOPS (arg1);
11635 STRIP_NOPS (arg2);
11636 STRIP_NOPS (arg3);
11637
11638 if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11639 && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2)
11640 && TREE_CODE (arg3) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg3))
11641 {
11642 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11643 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11644 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11645
11646 if (!real_isnan (ra1) && !real_isinf (ra1)
11647 && !real_isnan (ra2) && !real_isinf (ra2)
11648 && !real_isnan (ra3) && !real_isinf (ra3))
11649 {
11650 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11651 int inexact;
11652 mpfr_t m1, m2, m3;
11653
11654 mpfr_inits2 (prec, m1, m2, m3, NULL);
11655 mpfr_from_real (m1, ra1);
11656 mpfr_from_real (m2, ra2);
11657 mpfr_from_real (m3, ra3);
11658 mpfr_clear_flags();
11659 inexact = func (m1, m1, m2, m3, GMP_RNDN);
11660 result = do_mpfr_ckconv (m1, type, inexact);
11661 mpfr_clears (m1, m2, m3, NULL);
11662 }
11663 }
11664
11665 return result;
11666 }
11667
11668 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11669 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11670 The type is taken from the type of ARG and is used for setting the
11671 precision of the calculation and results. */
11672
11673 static tree
11674 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11675 {
11676 tree result = NULL_TREE;
11677
11678 STRIP_NOPS (arg);
11679
11680 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11681 {
11682 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11683
11684 if (!real_isnan (ra) && !real_isinf (ra))
11685 {
11686 tree const type = TREE_TYPE (arg);
11687 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11688 tree result_s, result_c;
11689 int inexact;
11690 mpfr_t m, ms, mc;
11691
11692 mpfr_inits2 (prec, m, ms, mc, NULL);
11693 mpfr_from_real (m, ra);
11694 mpfr_clear_flags();
11695 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11696 result_s = do_mpfr_ckconv (ms, type, inexact);
11697 result_c = do_mpfr_ckconv (mc, type, inexact);
11698 mpfr_clears (m, ms, mc, NULL);
11699 if (result_s && result_c)
11700 {
11701 /* Dereference the sin/cos pointer arguments. */
11702 arg_sinp = build_fold_indirect_ref (arg_sinp);
11703 arg_cosp = build_fold_indirect_ref (arg_cosp);
11704 /* Proceed if valid pointer type were passed in. */
11705 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11706 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11707 {
11708 /* Set the values. */
11709 result_s = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_sinp,
11710 result_s);
11711 TREE_SIDE_EFFECTS (result_s) = 1;
11712 result_c = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_cosp,
11713 result_c);
11714 TREE_SIDE_EFFECTS (result_c) = 1;
11715 /* Combine the assignments into a compound expr. */
11716 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11717 result_s, result_c));
11718 }
11719 }
11720 }
11721 }
11722 return result;
11723 }