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