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