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