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