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