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