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