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