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