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