tree.h (CASE_FLT_FN, [...]): New macros.
[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 {
4167 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4168 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4169 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4170 gimplify_and_add (t, pre_p);
4171
4172 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4173 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4174 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4175 gimplify_and_add (t, pre_p);
4176 }
4177 else
4178 boundary = align;
4179
4180 /* If the actual alignment is less than the alignment of the type,
4181 adjust the type accordingly so that we don't assume strict alignment
4182 when deferencing the pointer. */
4183 boundary *= BITS_PER_UNIT;
4184 if (boundary < TYPE_ALIGN (type))
4185 {
4186 type = build_variant_type_copy (type);
4187 TYPE_ALIGN (type) = boundary;
4188 }
4189
4190 /* Compute the rounded size of the type. */
4191 type_size = size_in_bytes (type);
4192 rounded_size = round_up (type_size, align);
4193
4194 /* Reduce rounded_size so it's sharable with the postqueue. */
4195 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4196
4197 /* Get AP. */
4198 addr = valist_tmp;
4199 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4200 {
4201 /* Small args are padded downward. */
4202 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4203 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4204 size_binop (MINUS_EXPR, rounded_size, type_size));
4205 t = fold_convert (TREE_TYPE (addr), t);
4206 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4207 }
4208
4209 /* Compute new value for AP. */
4210 t = fold_convert (TREE_TYPE (valist), rounded_size);
4211 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4212 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4213 gimplify_and_add (t, pre_p);
4214
4215 addr = fold_convert (build_pointer_type (type), addr);
4216
4217 if (indirect)
4218 addr = build_va_arg_indirect_ref (addr);
4219
4220 return build_va_arg_indirect_ref (addr);
4221 }
4222
4223 /* Build an indirect-ref expression over the given TREE, which represents a
4224 piece of a va_arg() expansion. */
4225 tree
4226 build_va_arg_indirect_ref (tree addr)
4227 {
4228 addr = build_fold_indirect_ref (addr);
4229
4230 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4231 mf_mark (addr);
4232
4233 return addr;
4234 }
4235
4236 /* Return a dummy expression of type TYPE in order to keep going after an
4237 error. */
4238
4239 static tree
4240 dummy_object (tree type)
4241 {
4242 tree t = convert (build_pointer_type (type), null_pointer_node);
4243 return build1 (INDIRECT_REF, type, t);
4244 }
4245
4246 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4247 builtin function, but a very special sort of operator. */
4248
4249 enum gimplify_status
4250 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4251 {
4252 tree promoted_type, want_va_type, have_va_type;
4253 tree valist = TREE_OPERAND (*expr_p, 0);
4254 tree type = TREE_TYPE (*expr_p);
4255 tree t;
4256
4257 /* Verify that valist is of the proper type. */
4258 want_va_type = va_list_type_node;
4259 have_va_type = TREE_TYPE (valist);
4260
4261 if (have_va_type == error_mark_node)
4262 return GS_ERROR;
4263
4264 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4265 {
4266 /* If va_list is an array type, the argument may have decayed
4267 to a pointer type, e.g. by being passed to another function.
4268 In that case, unwrap both types so that we can compare the
4269 underlying records. */
4270 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4271 || POINTER_TYPE_P (have_va_type))
4272 {
4273 want_va_type = TREE_TYPE (want_va_type);
4274 have_va_type = TREE_TYPE (have_va_type);
4275 }
4276 }
4277
4278 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4279 {
4280 error ("first argument to %<va_arg%> not of type %<va_list%>");
4281 return GS_ERROR;
4282 }
4283
4284 /* Generate a diagnostic for requesting data of a type that cannot
4285 be passed through `...' due to type promotion at the call site. */
4286 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4287 != type)
4288 {
4289 static bool gave_help;
4290
4291 /* Unfortunately, this is merely undefined, rather than a constraint
4292 violation, so we cannot make this an error. If this call is never
4293 executed, the program is still strictly conforming. */
4294 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4295 type, promoted_type);
4296 if (! gave_help)
4297 {
4298 gave_help = true;
4299 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4300 promoted_type, type);
4301 }
4302
4303 /* We can, however, treat "undefined" any way we please.
4304 Call abort to encourage the user to fix the program. */
4305 inform ("if this code is reached, the program will abort");
4306 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4307 NULL);
4308 append_to_statement_list (t, pre_p);
4309
4310 /* This is dead code, but go ahead and finish so that the
4311 mode of the result comes out right. */
4312 *expr_p = dummy_object (type);
4313 return GS_ALL_DONE;
4314 }
4315 else
4316 {
4317 /* Make it easier for the backends by protecting the valist argument
4318 from multiple evaluations. */
4319 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4320 {
4321 /* For this case, the backends will be expecting a pointer to
4322 TREE_TYPE (va_list_type_node), but it's possible we've
4323 actually been given an array (an actual va_list_type_node).
4324 So fix it. */
4325 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4326 {
4327 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4328 valist = build_fold_addr_expr_with_type (valist, p1);
4329 }
4330 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4331 }
4332 else
4333 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4334
4335 if (!targetm.gimplify_va_arg_expr)
4336 /* FIXME:Once most targets are converted we should merely
4337 assert this is non-null. */
4338 return GS_ALL_DONE;
4339
4340 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4341 return GS_OK;
4342 }
4343 }
4344
4345 /* Expand ARGLIST, from a call to __builtin_va_end. */
4346
4347 static rtx
4348 expand_builtin_va_end (tree arglist)
4349 {
4350 tree valist = TREE_VALUE (arglist);
4351
4352 /* Evaluate for side effects, if needed. I hate macros that don't
4353 do that. */
4354 if (TREE_SIDE_EFFECTS (valist))
4355 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4356
4357 return const0_rtx;
4358 }
4359
4360 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4361 builtin rather than just as an assignment in stdarg.h because of the
4362 nastiness of array-type va_list types. */
4363
4364 static rtx
4365 expand_builtin_va_copy (tree arglist)
4366 {
4367 tree dst, src, t;
4368
4369 dst = TREE_VALUE (arglist);
4370 src = TREE_VALUE (TREE_CHAIN (arglist));
4371
4372 dst = stabilize_va_list (dst, 1);
4373 src = stabilize_va_list (src, 0);
4374
4375 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4376 {
4377 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4378 TREE_SIDE_EFFECTS (t) = 1;
4379 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4380 }
4381 else
4382 {
4383 rtx dstb, srcb, size;
4384
4385 /* Evaluate to pointers. */
4386 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4387 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4388 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4389 VOIDmode, EXPAND_NORMAL);
4390
4391 dstb = convert_memory_address (Pmode, dstb);
4392 srcb = convert_memory_address (Pmode, srcb);
4393
4394 /* "Dereference" to BLKmode memories. */
4395 dstb = gen_rtx_MEM (BLKmode, dstb);
4396 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4397 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4398 srcb = gen_rtx_MEM (BLKmode, srcb);
4399 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4400 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4401
4402 /* Copy. */
4403 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4404 }
4405
4406 return const0_rtx;
4407 }
4408
4409 /* Expand a call to one of the builtin functions __builtin_frame_address or
4410 __builtin_return_address. */
4411
4412 static rtx
4413 expand_builtin_frame_address (tree fndecl, tree arglist)
4414 {
4415 /* The argument must be a nonnegative integer constant.
4416 It counts the number of frames to scan up the stack.
4417 The value is the return address saved in that frame. */
4418 if (arglist == 0)
4419 /* Warning about missing arg was already issued. */
4420 return const0_rtx;
4421 else if (! host_integerp (TREE_VALUE (arglist), 1))
4422 {
4423 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4424 error ("invalid argument to %<__builtin_frame_address%>");
4425 else
4426 error ("invalid argument to %<__builtin_return_address%>");
4427 return const0_rtx;
4428 }
4429 else
4430 {
4431 rtx tem
4432 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4433 tree_low_cst (TREE_VALUE (arglist), 1));
4434
4435 /* Some ports cannot access arbitrary stack frames. */
4436 if (tem == NULL)
4437 {
4438 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4439 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4440 else
4441 warning (0, "unsupported argument to %<__builtin_return_address%>");
4442 return const0_rtx;
4443 }
4444
4445 /* For __builtin_frame_address, return what we've got. */
4446 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4447 return tem;
4448
4449 if (!REG_P (tem)
4450 && ! CONSTANT_P (tem))
4451 tem = copy_to_mode_reg (Pmode, tem);
4452 return tem;
4453 }
4454 }
4455
4456 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4457 we failed and the caller should emit a normal call, otherwise try to get
4458 the result in TARGET, if convenient. */
4459
4460 static rtx
4461 expand_builtin_alloca (tree arglist, rtx target)
4462 {
4463 rtx op0;
4464 rtx result;
4465
4466 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4467 should always expand to function calls. These can be intercepted
4468 in libmudflap. */
4469 if (flag_mudflap)
4470 return 0;
4471
4472 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4473 return 0;
4474
4475 /* Compute the argument. */
4476 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4477
4478 /* Allocate the desired space. */
4479 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4480 result = convert_memory_address (ptr_mode, result);
4481
4482 return result;
4483 }
4484
4485 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4486 Return 0 if a normal call should be emitted rather than expanding the
4487 function in-line. If convenient, the result should be placed in TARGET.
4488 SUBTARGET may be used as the target for computing one of EXP's operands. */
4489
4490 static rtx
4491 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4492 rtx subtarget, optab op_optab)
4493 {
4494 rtx op0;
4495 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4496 return 0;
4497
4498 /* Compute the argument. */
4499 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4500 /* Compute op, into TARGET if possible.
4501 Set TARGET to wherever the result comes back. */
4502 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4503 op_optab, op0, target, 1);
4504 gcc_assert (target);
4505
4506 return convert_to_mode (target_mode, target, 0);
4507 }
4508
4509 /* If the string passed to fputs is a constant and is one character
4510 long, we attempt to transform this call into __builtin_fputc(). */
4511
4512 static rtx
4513 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4514 {
4515 /* Verify the arguments in the original call. */
4516 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4517 {
4518 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4519 unlocked, NULL_TREE);
4520 if (result)
4521 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4522 }
4523 return 0;
4524 }
4525
4526 /* Expand a call to __builtin_expect. We return our argument and emit a
4527 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4528 a non-jump context. */
4529
4530 static rtx
4531 expand_builtin_expect (tree arglist, rtx target)
4532 {
4533 tree exp, c;
4534 rtx note, rtx_c;
4535
4536 if (arglist == NULL_TREE
4537 || TREE_CHAIN (arglist) == NULL_TREE)
4538 return const0_rtx;
4539 exp = TREE_VALUE (arglist);
4540 c = TREE_VALUE (TREE_CHAIN (arglist));
4541
4542 if (TREE_CODE (c) != INTEGER_CST)
4543 {
4544 error ("second argument to %<__builtin_expect%> must be a constant");
4545 c = integer_zero_node;
4546 }
4547
4548 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4549
4550 /* Don't bother with expected value notes for integral constants. */
4551 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4552 {
4553 /* We do need to force this into a register so that we can be
4554 moderately sure to be able to correctly interpret the branch
4555 condition later. */
4556 target = force_reg (GET_MODE (target), target);
4557
4558 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4559
4560 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4561 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4562 }
4563
4564 return target;
4565 }
4566
4567 /* Like expand_builtin_expect, except do this in a jump context. This is
4568 called from do_jump if the conditional is a __builtin_expect. Return either
4569 a list of insns to emit the jump or NULL if we cannot optimize
4570 __builtin_expect. We need to optimize this at jump time so that machines
4571 like the PowerPC don't turn the test into a SCC operation, and then jump
4572 based on the test being 0/1. */
4573
4574 rtx
4575 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4576 {
4577 tree arglist = TREE_OPERAND (exp, 1);
4578 tree arg0 = TREE_VALUE (arglist);
4579 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4580 rtx ret = NULL_RTX;
4581
4582 /* Only handle __builtin_expect (test, 0) and
4583 __builtin_expect (test, 1). */
4584 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4585 && (integer_zerop (arg1) || integer_onep (arg1)))
4586 {
4587 rtx insn, drop_through_label, temp;
4588
4589 /* Expand the jump insns. */
4590 start_sequence ();
4591 do_jump (arg0, if_false_label, if_true_label);
4592 ret = get_insns ();
4593
4594 drop_through_label = get_last_insn ();
4595 if (drop_through_label && NOTE_P (drop_through_label))
4596 drop_through_label = prev_nonnote_insn (drop_through_label);
4597 if (drop_through_label && !LABEL_P (drop_through_label))
4598 drop_through_label = NULL_RTX;
4599 end_sequence ();
4600
4601 if (! if_true_label)
4602 if_true_label = drop_through_label;
4603 if (! if_false_label)
4604 if_false_label = drop_through_label;
4605
4606 /* Go through and add the expect's to each of the conditional jumps. */
4607 insn = ret;
4608 while (insn != NULL_RTX)
4609 {
4610 rtx next = NEXT_INSN (insn);
4611
4612 if (JUMP_P (insn) && any_condjump_p (insn))
4613 {
4614 rtx ifelse = SET_SRC (pc_set (insn));
4615 rtx then_dest = XEXP (ifelse, 1);
4616 rtx else_dest = XEXP (ifelse, 2);
4617 int taken = -1;
4618
4619 /* First check if we recognize any of the labels. */
4620 if (GET_CODE (then_dest) == LABEL_REF
4621 && XEXP (then_dest, 0) == if_true_label)
4622 taken = 1;
4623 else if (GET_CODE (then_dest) == LABEL_REF
4624 && XEXP (then_dest, 0) == if_false_label)
4625 taken = 0;
4626 else if (GET_CODE (else_dest) == LABEL_REF
4627 && XEXP (else_dest, 0) == if_false_label)
4628 taken = 1;
4629 else if (GET_CODE (else_dest) == LABEL_REF
4630 && XEXP (else_dest, 0) == if_true_label)
4631 taken = 0;
4632 /* Otherwise check where we drop through. */
4633 else if (else_dest == pc_rtx)
4634 {
4635 if (next && NOTE_P (next))
4636 next = next_nonnote_insn (next);
4637
4638 if (next && JUMP_P (next)
4639 && any_uncondjump_p (next))
4640 temp = XEXP (SET_SRC (pc_set (next)), 0);
4641 else
4642 temp = next;
4643
4644 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4645 else that can't possibly match either target label. */
4646 if (temp == if_false_label)
4647 taken = 1;
4648 else if (temp == if_true_label)
4649 taken = 0;
4650 }
4651 else if (then_dest == pc_rtx)
4652 {
4653 if (next && NOTE_P (next))
4654 next = next_nonnote_insn (next);
4655
4656 if (next && JUMP_P (next)
4657 && any_uncondjump_p (next))
4658 temp = XEXP (SET_SRC (pc_set (next)), 0);
4659 else
4660 temp = next;
4661
4662 if (temp == if_false_label)
4663 taken = 0;
4664 else if (temp == if_true_label)
4665 taken = 1;
4666 }
4667
4668 if (taken != -1)
4669 {
4670 /* If the test is expected to fail, reverse the
4671 probabilities. */
4672 if (integer_zerop (arg1))
4673 taken = 1 - taken;
4674 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4675 }
4676 }
4677
4678 insn = next;
4679 }
4680 }
4681
4682 return ret;
4683 }
4684
4685 void
4686 expand_builtin_trap (void)
4687 {
4688 #ifdef HAVE_trap
4689 if (HAVE_trap)
4690 emit_insn (gen_trap ());
4691 else
4692 #endif
4693 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4694 emit_barrier ();
4695 }
4696
4697 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4698 Return 0 if a normal call should be emitted rather than expanding
4699 the function inline. If convenient, the result should be placed
4700 in TARGET. SUBTARGET may be used as the target for computing
4701 the operand. */
4702
4703 static rtx
4704 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4705 {
4706 enum machine_mode mode;
4707 tree arg;
4708 rtx op0;
4709
4710 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4711 return 0;
4712
4713 arg = TREE_VALUE (arglist);
4714 mode = TYPE_MODE (TREE_TYPE (arg));
4715 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4716 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4717 }
4718
4719 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4720 Return NULL is a normal call should be emitted rather than expanding the
4721 function inline. If convenient, the result should be placed in TARGET.
4722 SUBTARGET may be used as the target for computing the operand. */
4723
4724 static rtx
4725 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4726 {
4727 rtx op0, op1;
4728 tree arg;
4729
4730 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4731 return 0;
4732
4733 arg = TREE_VALUE (arglist);
4734 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4735
4736 arg = TREE_VALUE (TREE_CHAIN (arglist));
4737 op1 = expand_expr (arg, NULL, VOIDmode, 0);
4738
4739 return expand_copysign (op0, op1, target);
4740 }
4741
4742 /* Create a new constant string literal and return a char* pointer to it.
4743 The STRING_CST value is the LEN characters at STR. */
4744 static tree
4745 build_string_literal (int len, const char *str)
4746 {
4747 tree t, elem, index, type;
4748
4749 t = build_string (len, str);
4750 elem = build_type_variant (char_type_node, 1, 0);
4751 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4752 type = build_array_type (elem, index);
4753 TREE_TYPE (t) = type;
4754 TREE_CONSTANT (t) = 1;
4755 TREE_INVARIANT (t) = 1;
4756 TREE_READONLY (t) = 1;
4757 TREE_STATIC (t) = 1;
4758
4759 type = build_pointer_type (type);
4760 t = build1 (ADDR_EXPR, type, t);
4761
4762 type = build_pointer_type (elem);
4763 t = build1 (NOP_EXPR, type, t);
4764 return t;
4765 }
4766
4767 /* Expand EXP, a call to printf or printf_unlocked.
4768 Return 0 if a normal call should be emitted rather than transforming
4769 the function inline. If convenient, the result should be placed in
4770 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4771 call. */
4772 static rtx
4773 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4774 bool unlocked)
4775 {
4776 tree arglist = TREE_OPERAND (exp, 1);
4777 /* If we're using an unlocked function, assume the other unlocked
4778 functions exist explicitly. */
4779 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4780 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4781 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4782 : implicit_built_in_decls[BUILT_IN_PUTS];
4783 const char *fmt_str;
4784 tree fn, fmt, arg;
4785
4786 /* If the return value is used, don't do the transformation. */
4787 if (target != const0_rtx)
4788 return 0;
4789
4790 /* Verify the required arguments in the original call. */
4791 if (! arglist)
4792 return 0;
4793 fmt = TREE_VALUE (arglist);
4794 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4795 return 0;
4796 arglist = TREE_CHAIN (arglist);
4797
4798 /* Check whether the format is a literal string constant. */
4799 fmt_str = c_getstr (fmt);
4800 if (fmt_str == NULL)
4801 return 0;
4802
4803 if (!init_target_chars())
4804 return 0;
4805
4806 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4807 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4808 {
4809 if (! arglist
4810 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4811 || TREE_CHAIN (arglist))
4812 return 0;
4813 fn = fn_puts;
4814 }
4815 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4816 else if (strcmp (fmt_str, target_percent_c) == 0)
4817 {
4818 if (! arglist
4819 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4820 || TREE_CHAIN (arglist))
4821 return 0;
4822 fn = fn_putchar;
4823 }
4824 else
4825 {
4826 /* We can't handle anything else with % args or %% ... yet. */
4827 if (strchr (fmt_str, target_percent))
4828 return 0;
4829
4830 if (arglist)
4831 return 0;
4832
4833 /* If the format specifier was "", printf does nothing. */
4834 if (fmt_str[0] == '\0')
4835 return const0_rtx;
4836 /* If the format specifier has length of 1, call putchar. */
4837 if (fmt_str[1] == '\0')
4838 {
4839 /* Given printf("c"), (where c is any one character,)
4840 convert "c"[0] to an int and pass that to the replacement
4841 function. */
4842 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4843 arglist = build_tree_list (NULL_TREE, arg);
4844 fn = fn_putchar;
4845 }
4846 else
4847 {
4848 /* If the format specifier was "string\n", call puts("string"). */
4849 size_t len = strlen (fmt_str);
4850 if ((unsigned char)fmt_str[len - 1] == target_newline)
4851 {
4852 /* Create a NUL-terminated string that's one char shorter
4853 than the original, stripping off the trailing '\n'. */
4854 char *newstr = alloca (len);
4855 memcpy (newstr, fmt_str, len - 1);
4856 newstr[len - 1] = 0;
4857
4858 arg = build_string_literal (len, newstr);
4859 arglist = build_tree_list (NULL_TREE, arg);
4860 fn = fn_puts;
4861 }
4862 else
4863 /* We'd like to arrange to call fputs(string,stdout) here,
4864 but we need stdout and don't have a way to get it yet. */
4865 return 0;
4866 }
4867 }
4868
4869 if (!fn)
4870 return 0;
4871 fn = build_function_call_expr (fn, arglist);
4872 if (TREE_CODE (fn) == CALL_EXPR)
4873 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4874 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4875 }
4876
4877 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4878 Return 0 if a normal call should be emitted rather than transforming
4879 the function inline. If convenient, the result should be placed in
4880 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4881 call. */
4882 static rtx
4883 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4884 bool unlocked)
4885 {
4886 tree arglist = TREE_OPERAND (exp, 1);
4887 /* If we're using an unlocked function, assume the other unlocked
4888 functions exist explicitly. */
4889 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4890 : implicit_built_in_decls[BUILT_IN_FPUTC];
4891 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4892 : implicit_built_in_decls[BUILT_IN_FPUTS];
4893 const char *fmt_str;
4894 tree fn, fmt, fp, arg;
4895
4896 /* If the return value is used, don't do the transformation. */
4897 if (target != const0_rtx)
4898 return 0;
4899
4900 /* Verify the required arguments in the original call. */
4901 if (! arglist)
4902 return 0;
4903 fp = TREE_VALUE (arglist);
4904 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4905 return 0;
4906 arglist = TREE_CHAIN (arglist);
4907 if (! arglist)
4908 return 0;
4909 fmt = TREE_VALUE (arglist);
4910 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4911 return 0;
4912 arglist = TREE_CHAIN (arglist);
4913
4914 /* Check whether the format is a literal string constant. */
4915 fmt_str = c_getstr (fmt);
4916 if (fmt_str == NULL)
4917 return 0;
4918
4919 if (!init_target_chars())
4920 return 0;
4921
4922 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4923 if (strcmp (fmt_str, target_percent_s) == 0)
4924 {
4925 if (! arglist
4926 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4927 || TREE_CHAIN (arglist))
4928 return 0;
4929 arg = TREE_VALUE (arglist);
4930 arglist = build_tree_list (NULL_TREE, fp);
4931 arglist = tree_cons (NULL_TREE, arg, arglist);
4932 fn = fn_fputs;
4933 }
4934 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4935 else if (strcmp (fmt_str, target_percent_c) == 0)
4936 {
4937 if (! arglist
4938 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4939 || TREE_CHAIN (arglist))
4940 return 0;
4941 arg = TREE_VALUE (arglist);
4942 arglist = build_tree_list (NULL_TREE, fp);
4943 arglist = tree_cons (NULL_TREE, arg, arglist);
4944 fn = fn_fputc;
4945 }
4946 else
4947 {
4948 /* We can't handle anything else with % args or %% ... yet. */
4949 if (strchr (fmt_str, target_percent))
4950 return 0;
4951
4952 if (arglist)
4953 return 0;
4954
4955 /* If the format specifier was "", fprintf does nothing. */
4956 if (fmt_str[0] == '\0')
4957 {
4958 /* Evaluate and ignore FILE* argument for side-effects. */
4959 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4960 return const0_rtx;
4961 }
4962
4963 /* When "string" doesn't contain %, replace all cases of
4964 fprintf(stream,string) with fputs(string,stream). The fputs
4965 builtin will take care of special cases like length == 1. */
4966 arglist = build_tree_list (NULL_TREE, fp);
4967 arglist = tree_cons (NULL_TREE, fmt, arglist);
4968 fn = fn_fputs;
4969 }
4970
4971 if (!fn)
4972 return 0;
4973 fn = build_function_call_expr (fn, arglist);
4974 if (TREE_CODE (fn) == CALL_EXPR)
4975 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4976 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4977 }
4978
4979 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4980 a normal call should be emitted rather than expanding the function
4981 inline. If convenient, the result should be placed in TARGET with
4982 mode MODE. */
4983
4984 static rtx
4985 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4986 {
4987 tree orig_arglist, dest, fmt;
4988 const char *fmt_str;
4989
4990 orig_arglist = arglist;
4991
4992 /* Verify the required arguments in the original call. */
4993 if (! arglist)
4994 return 0;
4995 dest = TREE_VALUE (arglist);
4996 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
4997 return 0;
4998 arglist = TREE_CHAIN (arglist);
4999 if (! arglist)
5000 return 0;
5001 fmt = TREE_VALUE (arglist);
5002 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5003 return 0;
5004 arglist = TREE_CHAIN (arglist);
5005
5006 /* Check whether the format is a literal string constant. */
5007 fmt_str = c_getstr (fmt);
5008 if (fmt_str == NULL)
5009 return 0;
5010
5011 if (!init_target_chars())
5012 return 0;
5013
5014 /* If the format doesn't contain % args or %%, use strcpy. */
5015 if (strchr (fmt_str, target_percent) == 0)
5016 {
5017 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5018 tree exp;
5019
5020 if (arglist || ! fn)
5021 return 0;
5022 expand_expr (build_function_call_expr (fn, orig_arglist),
5023 const0_rtx, VOIDmode, EXPAND_NORMAL);
5024 if (target == const0_rtx)
5025 return const0_rtx;
5026 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5027 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5028 }
5029 /* If the format is "%s", use strcpy if the result isn't used. */
5030 else if (strcmp (fmt_str, target_percent_s) == 0)
5031 {
5032 tree fn, arg, len;
5033 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5034
5035 if (! fn)
5036 return 0;
5037
5038 if (! arglist || TREE_CHAIN (arglist))
5039 return 0;
5040 arg = TREE_VALUE (arglist);
5041 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5042 return 0;
5043
5044 if (target != const0_rtx)
5045 {
5046 len = c_strlen (arg, 1);
5047 if (! len || TREE_CODE (len) != INTEGER_CST)
5048 return 0;
5049 }
5050 else
5051 len = NULL_TREE;
5052
5053 arglist = build_tree_list (NULL_TREE, arg);
5054 arglist = tree_cons (NULL_TREE, dest, arglist);
5055 expand_expr (build_function_call_expr (fn, arglist),
5056 const0_rtx, VOIDmode, EXPAND_NORMAL);
5057
5058 if (target == const0_rtx)
5059 return const0_rtx;
5060 return expand_expr (len, target, mode, EXPAND_NORMAL);
5061 }
5062
5063 return 0;
5064 }
5065
5066 /* Expand a call to either the entry or exit function profiler. */
5067
5068 static rtx
5069 expand_builtin_profile_func (bool exitp)
5070 {
5071 rtx this, which;
5072
5073 this = DECL_RTL (current_function_decl);
5074 gcc_assert (MEM_P (this));
5075 this = XEXP (this, 0);
5076
5077 if (exitp)
5078 which = profile_function_exit_libfunc;
5079 else
5080 which = profile_function_entry_libfunc;
5081
5082 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5083 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5084 0),
5085 Pmode);
5086
5087 return const0_rtx;
5088 }
5089
5090 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5091
5092 static rtx
5093 round_trampoline_addr (rtx tramp)
5094 {
5095 rtx temp, addend, mask;
5096
5097 /* If we don't need too much alignment, we'll have been guaranteed
5098 proper alignment by get_trampoline_type. */
5099 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5100 return tramp;
5101
5102 /* Round address up to desired boundary. */
5103 temp = gen_reg_rtx (Pmode);
5104 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5105 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5106
5107 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5108 temp, 0, OPTAB_LIB_WIDEN);
5109 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5110 temp, 0, OPTAB_LIB_WIDEN);
5111
5112 return tramp;
5113 }
5114
5115 static rtx
5116 expand_builtin_init_trampoline (tree arglist)
5117 {
5118 tree t_tramp, t_func, t_chain;
5119 rtx r_tramp, r_func, r_chain;
5120 #ifdef TRAMPOLINE_TEMPLATE
5121 rtx blktramp;
5122 #endif
5123
5124 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5125 POINTER_TYPE, VOID_TYPE))
5126 return NULL_RTX;
5127
5128 t_tramp = TREE_VALUE (arglist);
5129 arglist = TREE_CHAIN (arglist);
5130 t_func = TREE_VALUE (arglist);
5131 arglist = TREE_CHAIN (arglist);
5132 t_chain = TREE_VALUE (arglist);
5133
5134 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5135 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5136 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5137
5138 /* Generate insns to initialize the trampoline. */
5139 r_tramp = round_trampoline_addr (r_tramp);
5140 #ifdef TRAMPOLINE_TEMPLATE
5141 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5142 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5143 emit_block_move (blktramp, assemble_trampoline_template (),
5144 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5145 #endif
5146 trampolines_created = 1;
5147 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5148
5149 return const0_rtx;
5150 }
5151
5152 static rtx
5153 expand_builtin_adjust_trampoline (tree arglist)
5154 {
5155 rtx tramp;
5156
5157 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5158 return NULL_RTX;
5159
5160 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5161 tramp = round_trampoline_addr (tramp);
5162 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5163 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5164 #endif
5165
5166 return tramp;
5167 }
5168
5169 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5170 Return NULL_RTX if a normal call should be emitted rather than expanding
5171 the function in-line. EXP is the expression that is a call to the builtin
5172 function; if convenient, the result should be placed in TARGET. */
5173
5174 static rtx
5175 expand_builtin_signbit (tree exp, rtx target)
5176 {
5177 const struct real_format *fmt;
5178 enum machine_mode fmode, imode, rmode;
5179 HOST_WIDE_INT hi, lo;
5180 tree arg, arglist;
5181 int word, bitpos;
5182 rtx temp;
5183
5184 arglist = TREE_OPERAND (exp, 1);
5185 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5186 return 0;
5187
5188 arg = TREE_VALUE (arglist);
5189 fmode = TYPE_MODE (TREE_TYPE (arg));
5190 rmode = TYPE_MODE (TREE_TYPE (exp));
5191 fmt = REAL_MODE_FORMAT (fmode);
5192
5193 /* For floating point formats without a sign bit, implement signbit
5194 as "ARG < 0.0". */
5195 bitpos = fmt->signbit_ro;
5196 if (bitpos < 0)
5197 {
5198 /* But we can't do this if the format supports signed zero. */
5199 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5200 return 0;
5201
5202 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5203 build_real (TREE_TYPE (arg), dconst0));
5204 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5205 }
5206
5207 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5208 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5209 {
5210 imode = int_mode_for_mode (fmode);
5211 if (imode == BLKmode)
5212 return 0;
5213 temp = gen_lowpart (imode, temp);
5214 }
5215 else
5216 {
5217 imode = word_mode;
5218 /* Handle targets with different FP word orders. */
5219 if (FLOAT_WORDS_BIG_ENDIAN)
5220 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5221 else
5222 word = bitpos / BITS_PER_WORD;
5223 temp = operand_subword_force (temp, word, fmode);
5224 bitpos = bitpos % BITS_PER_WORD;
5225 }
5226
5227 /* Force the intermediate word_mode (or narrower) result into a
5228 register. This avoids attempting to create paradoxical SUBREGs
5229 of floating point modes below. */
5230 temp = force_reg (imode, temp);
5231
5232 /* If the bitpos is within the "result mode" lowpart, the operation
5233 can be implement with a single bitwise AND. Otherwise, we need
5234 a right shift and an AND. */
5235
5236 if (bitpos < GET_MODE_BITSIZE (rmode))
5237 {
5238 if (bitpos < HOST_BITS_PER_WIDE_INT)
5239 {
5240 hi = 0;
5241 lo = (HOST_WIDE_INT) 1 << bitpos;
5242 }
5243 else
5244 {
5245 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5246 lo = 0;
5247 }
5248
5249 if (imode != rmode)
5250 temp = gen_lowpart (rmode, temp);
5251 temp = expand_binop (rmode, and_optab, temp,
5252 immed_double_const (lo, hi, rmode),
5253 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5254 }
5255 else
5256 {
5257 /* Perform a logical right shift to place the signbit in the least
5258 significant bit, then truncate the result to the desired mode
5259 and mask just this bit. */
5260 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5261 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5262 temp = gen_lowpart (rmode, temp);
5263 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5264 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5265 }
5266
5267 return temp;
5268 }
5269
5270 /* Expand fork or exec calls. TARGET is the desired target of the
5271 call. ARGLIST is the list of arguments of the call. FN is the
5272 identificator of the actual function. IGNORE is nonzero if the
5273 value is to be ignored. */
5274
5275 static rtx
5276 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5277 {
5278 tree id, decl;
5279 tree call;
5280
5281 /* If we are not profiling, just call the function. */
5282 if (!profile_arc_flag)
5283 return NULL_RTX;
5284
5285 /* Otherwise call the wrapper. This should be equivalent for the rest of
5286 compiler, so the code does not diverge, and the wrapper may run the
5287 code necessary for keeping the profiling sane. */
5288
5289 switch (DECL_FUNCTION_CODE (fn))
5290 {
5291 case BUILT_IN_FORK:
5292 id = get_identifier ("__gcov_fork");
5293 break;
5294
5295 case BUILT_IN_EXECL:
5296 id = get_identifier ("__gcov_execl");
5297 break;
5298
5299 case BUILT_IN_EXECV:
5300 id = get_identifier ("__gcov_execv");
5301 break;
5302
5303 case BUILT_IN_EXECLP:
5304 id = get_identifier ("__gcov_execlp");
5305 break;
5306
5307 case BUILT_IN_EXECLE:
5308 id = get_identifier ("__gcov_execle");
5309 break;
5310
5311 case BUILT_IN_EXECVP:
5312 id = get_identifier ("__gcov_execvp");
5313 break;
5314
5315 case BUILT_IN_EXECVE:
5316 id = get_identifier ("__gcov_execve");
5317 break;
5318
5319 default:
5320 gcc_unreachable ();
5321 }
5322
5323 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5324 DECL_EXTERNAL (decl) = 1;
5325 TREE_PUBLIC (decl) = 1;
5326 DECL_ARTIFICIAL (decl) = 1;
5327 TREE_NOTHROW (decl) = 1;
5328 call = build_function_call_expr (decl, arglist);
5329
5330 return expand_call (call, target, ignore);
5331 }
5332
5333 \f
5334 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5335 the pointer in these functions is void*, the tree optimizers may remove
5336 casts. The mode computed in expand_builtin isn't reliable either, due
5337 to __sync_bool_compare_and_swap.
5338
5339 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5340 group of builtins. This gives us log2 of the mode size. */
5341
5342 static inline enum machine_mode
5343 get_builtin_sync_mode (int fcode_diff)
5344 {
5345 /* The size is not negotiable, so ask not to get BLKmode in return
5346 if the target indicates that a smaller size would be better. */
5347 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5348 }
5349
5350 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5351 ARGLIST is the operands list to the function. CODE is the rtx code
5352 that corresponds to the arithmetic or logical operation from the name;
5353 an exception here is that NOT actually means NAND. TARGET is an optional
5354 place for us to store the results; AFTER is true if this is the
5355 fetch_and_xxx form. IGNORE is true if we don't actually care about
5356 the result of the operation at all. */
5357
5358 static rtx
5359 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5360 enum rtx_code code, bool after,
5361 rtx target, bool ignore)
5362 {
5363 rtx addr, val, mem;
5364
5365 /* Expand the operands. */
5366 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5367
5368 arglist = TREE_CHAIN (arglist);
5369 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5370
5371 /* Note that we explicitly do not want any alias information for this
5372 memory, so that we kill all other live memories. Otherwise we don't
5373 satisfy the full barrier semantics of the intrinsic. */
5374 mem = validize_mem (gen_rtx_MEM (mode, addr));
5375 MEM_VOLATILE_P (mem) = 1;
5376
5377 if (ignore)
5378 return expand_sync_operation (mem, val, code);
5379 else
5380 return expand_sync_fetch_operation (mem, val, code, after, target);
5381 }
5382
5383 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5384 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5385 true if this is the boolean form. TARGET is a place for us to store the
5386 results; this is NOT optional if IS_BOOL is true. */
5387
5388 static rtx
5389 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5390 bool is_bool, rtx target)
5391 {
5392 rtx addr, old_val, new_val, mem;
5393
5394 /* Expand the operands. */
5395 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5396
5397 arglist = TREE_CHAIN (arglist);
5398 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5399
5400 arglist = TREE_CHAIN (arglist);
5401 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5402
5403 /* Note that we explicitly do not want any alias information for this
5404 memory, so that we kill all other live memories. Otherwise we don't
5405 satisfy the full barrier semantics of the intrinsic. */
5406 mem = validize_mem (gen_rtx_MEM (mode, addr));
5407 MEM_VOLATILE_P (mem) = 1;
5408
5409 if (is_bool)
5410 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5411 else
5412 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5413 }
5414
5415 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5416 general form is actually an atomic exchange, and some targets only
5417 support a reduced form with the second argument being a constant 1.
5418 ARGLIST is the operands list to the function; TARGET is an optional
5419 place for us to store the results. */
5420
5421 static rtx
5422 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5423 rtx target)
5424 {
5425 rtx addr, val, mem;
5426
5427 /* Expand the operands. */
5428 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5429
5430 arglist = TREE_CHAIN (arglist);
5431 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5432
5433 /* Note that we explicitly do not want any alias information for this
5434 memory, so that we kill all other live memories. Otherwise we don't
5435 satisfy the barrier semantics of the intrinsic. */
5436 mem = validize_mem (gen_rtx_MEM (mode, addr));
5437 MEM_VOLATILE_P (mem) = 1;
5438
5439 return expand_sync_lock_test_and_set (mem, val, target);
5440 }
5441
5442 /* Expand the __sync_synchronize intrinsic. */
5443
5444 static void
5445 expand_builtin_synchronize (void)
5446 {
5447 tree x;
5448
5449 #ifdef HAVE_memory_barrier
5450 if (HAVE_memory_barrier)
5451 {
5452 emit_insn (gen_memory_barrier ());
5453 return;
5454 }
5455 #endif
5456
5457 /* If no explicit memory barrier instruction is available, create an
5458 empty asm stmt with a memory clobber. */
5459 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5460 tree_cons (NULL, build_string (6, "memory"), NULL));
5461 ASM_VOLATILE_P (x) = 1;
5462 expand_asm_expr (x);
5463 }
5464
5465 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5466 to the function. */
5467
5468 static void
5469 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5470 {
5471 enum insn_code icode;
5472 rtx addr, mem, insn;
5473 rtx val = const0_rtx;
5474
5475 /* Expand the operands. */
5476 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5477
5478 /* Note that we explicitly do not want any alias information for this
5479 memory, so that we kill all other live memories. Otherwise we don't
5480 satisfy the barrier semantics of the intrinsic. */
5481 mem = validize_mem (gen_rtx_MEM (mode, addr));
5482 MEM_VOLATILE_P (mem) = 1;
5483
5484 /* If there is an explicit operation in the md file, use it. */
5485 icode = sync_lock_release[mode];
5486 if (icode != CODE_FOR_nothing)
5487 {
5488 if (!insn_data[icode].operand[1].predicate (val, mode))
5489 val = force_reg (mode, val);
5490
5491 insn = GEN_FCN (icode) (mem, val);
5492 if (insn)
5493 {
5494 emit_insn (insn);
5495 return;
5496 }
5497 }
5498
5499 /* Otherwise we can implement this operation by emitting a barrier
5500 followed by a store of zero. */
5501 expand_builtin_synchronize ();
5502 emit_move_insn (mem, val);
5503 }
5504 \f
5505 /* Expand an expression EXP that calls a built-in function,
5506 with result going to TARGET if that's convenient
5507 (and in mode MODE if that's convenient).
5508 SUBTARGET may be used as the target for computing one of EXP's operands.
5509 IGNORE is nonzero if the value is to be ignored. */
5510
5511 rtx
5512 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5513 int ignore)
5514 {
5515 tree fndecl = get_callee_fndecl (exp);
5516 tree arglist = TREE_OPERAND (exp, 1);
5517 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5518 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5519
5520 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5521 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5522
5523 /* When not optimizing, generate calls to library functions for a certain
5524 set of builtins. */
5525 if (!optimize
5526 && !called_as_built_in (fndecl)
5527 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5528 && fcode != BUILT_IN_ALLOCA)
5529 return expand_call (exp, target, ignore);
5530
5531 /* The built-in function expanders test for target == const0_rtx
5532 to determine whether the function's result will be ignored. */
5533 if (ignore)
5534 target = const0_rtx;
5535
5536 /* If the result of a pure or const built-in function is ignored, and
5537 none of its arguments are volatile, we can avoid expanding the
5538 built-in call and just evaluate the arguments for side-effects. */
5539 if (target == const0_rtx
5540 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5541 {
5542 bool volatilep = false;
5543 tree arg;
5544
5545 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5546 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5547 {
5548 volatilep = true;
5549 break;
5550 }
5551
5552 if (! volatilep)
5553 {
5554 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5555 expand_expr (TREE_VALUE (arg), const0_rtx,
5556 VOIDmode, EXPAND_NORMAL);
5557 return const0_rtx;
5558 }
5559 }
5560
5561 switch (fcode)
5562 {
5563 CASE_FLT_FN (BUILT_IN_FABS):
5564 target = expand_builtin_fabs (arglist, target, subtarget);
5565 if (target)
5566 return target;
5567 break;
5568
5569 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5570 target = expand_builtin_copysign (arglist, target, subtarget);
5571 if (target)
5572 return target;
5573 break;
5574
5575 /* Just do a normal library call if we were unable to fold
5576 the values. */
5577 CASE_FLT_FN (BUILT_IN_CABS):
5578 break;
5579
5580 CASE_FLT_FN (BUILT_IN_EXP):
5581 CASE_FLT_FN (BUILT_IN_EXP10):
5582 CASE_FLT_FN (BUILT_IN_POW10):
5583 CASE_FLT_FN (BUILT_IN_EXP2):
5584 CASE_FLT_FN (BUILT_IN_EXPM1):
5585 CASE_FLT_FN (BUILT_IN_LOGB):
5586 CASE_FLT_FN (BUILT_IN_ILOGB):
5587 CASE_FLT_FN (BUILT_IN_LOG):
5588 CASE_FLT_FN (BUILT_IN_LOG10):
5589 CASE_FLT_FN (BUILT_IN_LOG2):
5590 CASE_FLT_FN (BUILT_IN_LOG1P):
5591 CASE_FLT_FN (BUILT_IN_TAN):
5592 CASE_FLT_FN (BUILT_IN_ASIN):
5593 CASE_FLT_FN (BUILT_IN_ACOS):
5594 CASE_FLT_FN (BUILT_IN_ATAN):
5595 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5596 because of possible accuracy problems. */
5597 if (! flag_unsafe_math_optimizations)
5598 break;
5599 CASE_FLT_FN (BUILT_IN_SQRT):
5600 CASE_FLT_FN (BUILT_IN_FLOOR):
5601 CASE_FLT_FN (BUILT_IN_CEIL):
5602 CASE_FLT_FN (BUILT_IN_TRUNC):
5603 CASE_FLT_FN (BUILT_IN_ROUND):
5604 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5605 CASE_FLT_FN (BUILT_IN_RINT):
5606 CASE_FLT_FN (BUILT_IN_LRINT):
5607 CASE_FLT_FN (BUILT_IN_LLRINT):
5608 target = expand_builtin_mathfn (exp, target, subtarget);
5609 if (target)
5610 return target;
5611 break;
5612
5613 CASE_FLT_FN (BUILT_IN_LCEIL):
5614 CASE_FLT_FN (BUILT_IN_LLCEIL):
5615 CASE_FLT_FN (BUILT_IN_LFLOOR):
5616 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5617 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5618 if (target)
5619 return target;
5620 break;
5621
5622 CASE_FLT_FN (BUILT_IN_POW):
5623 target = expand_builtin_pow (exp, target, subtarget);
5624 if (target)
5625 return target;
5626 break;
5627
5628 CASE_FLT_FN (BUILT_IN_POWI):
5629 target = expand_builtin_powi (exp, target, subtarget);
5630 if (target)
5631 return target;
5632 break;
5633
5634 CASE_FLT_FN (BUILT_IN_ATAN2):
5635 CASE_FLT_FN (BUILT_IN_LDEXP):
5636 CASE_FLT_FN (BUILT_IN_FMOD):
5637 CASE_FLT_FN (BUILT_IN_DREM):
5638 if (! flag_unsafe_math_optimizations)
5639 break;
5640 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5641 if (target)
5642 return target;
5643 break;
5644
5645 CASE_FLT_FN (BUILT_IN_SIN):
5646 CASE_FLT_FN (BUILT_IN_COS):
5647 if (! flag_unsafe_math_optimizations)
5648 break;
5649 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5650 if (target)
5651 return target;
5652 break;
5653
5654 case BUILT_IN_APPLY_ARGS:
5655 return expand_builtin_apply_args ();
5656
5657 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5658 FUNCTION with a copy of the parameters described by
5659 ARGUMENTS, and ARGSIZE. It returns a block of memory
5660 allocated on the stack into which is stored all the registers
5661 that might possibly be used for returning the result of a
5662 function. ARGUMENTS is the value returned by
5663 __builtin_apply_args. ARGSIZE is the number of bytes of
5664 arguments that must be copied. ??? How should this value be
5665 computed? We'll also need a safe worst case value for varargs
5666 functions. */
5667 case BUILT_IN_APPLY:
5668 if (!validate_arglist (arglist, POINTER_TYPE,
5669 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5670 && !validate_arglist (arglist, REFERENCE_TYPE,
5671 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5672 return const0_rtx;
5673 else
5674 {
5675 int i;
5676 tree t;
5677 rtx ops[3];
5678
5679 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5680 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5681
5682 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5683 }
5684
5685 /* __builtin_return (RESULT) causes the function to return the
5686 value described by RESULT. RESULT is address of the block of
5687 memory returned by __builtin_apply. */
5688 case BUILT_IN_RETURN:
5689 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5690 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5691 NULL_RTX, VOIDmode, 0));
5692 return const0_rtx;
5693
5694 case BUILT_IN_SAVEREGS:
5695 return expand_builtin_saveregs ();
5696
5697 case BUILT_IN_ARGS_INFO:
5698 return expand_builtin_args_info (arglist);
5699
5700 /* Return the address of the first anonymous stack arg. */
5701 case BUILT_IN_NEXT_ARG:
5702 if (fold_builtin_next_arg (arglist))
5703 return const0_rtx;
5704 return expand_builtin_next_arg ();
5705
5706 case BUILT_IN_CLASSIFY_TYPE:
5707 return expand_builtin_classify_type (arglist);
5708
5709 case BUILT_IN_CONSTANT_P:
5710 return const0_rtx;
5711
5712 case BUILT_IN_FRAME_ADDRESS:
5713 case BUILT_IN_RETURN_ADDRESS:
5714 return expand_builtin_frame_address (fndecl, arglist);
5715
5716 /* Returns the address of the area where the structure is returned.
5717 0 otherwise. */
5718 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5719 if (arglist != 0
5720 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5721 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5722 return const0_rtx;
5723 else
5724 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5725
5726 case BUILT_IN_ALLOCA:
5727 target = expand_builtin_alloca (arglist, target);
5728 if (target)
5729 return target;
5730 break;
5731
5732 case BUILT_IN_STACK_SAVE:
5733 return expand_stack_save ();
5734
5735 case BUILT_IN_STACK_RESTORE:
5736 expand_stack_restore (TREE_VALUE (arglist));
5737 return const0_rtx;
5738
5739 CASE_INT_FN (BUILT_IN_FFS):
5740 case BUILT_IN_FFSIMAX:
5741 target = expand_builtin_unop (target_mode, arglist, target,
5742 subtarget, ffs_optab);
5743 if (target)
5744 return target;
5745 break;
5746
5747 CASE_INT_FN (BUILT_IN_CLZ):
5748 case BUILT_IN_CLZIMAX:
5749 target = expand_builtin_unop (target_mode, arglist, target,
5750 subtarget, clz_optab);
5751 if (target)
5752 return target;
5753 break;
5754
5755 CASE_INT_FN (BUILT_IN_CTZ):
5756 case BUILT_IN_CTZIMAX:
5757 target = expand_builtin_unop (target_mode, arglist, target,
5758 subtarget, ctz_optab);
5759 if (target)
5760 return target;
5761 break;
5762
5763 CASE_INT_FN (BUILT_IN_POPCOUNT):
5764 case BUILT_IN_POPCOUNTIMAX:
5765 target = expand_builtin_unop (target_mode, arglist, target,
5766 subtarget, popcount_optab);
5767 if (target)
5768 return target;
5769 break;
5770
5771 CASE_INT_FN (BUILT_IN_PARITY):
5772 case BUILT_IN_PARITYIMAX:
5773 target = expand_builtin_unop (target_mode, arglist, target,
5774 subtarget, parity_optab);
5775 if (target)
5776 return target;
5777 break;
5778
5779 case BUILT_IN_STRLEN:
5780 target = expand_builtin_strlen (arglist, target, target_mode);
5781 if (target)
5782 return target;
5783 break;
5784
5785 case BUILT_IN_STRCPY:
5786 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5787 if (target)
5788 return target;
5789 break;
5790
5791 case BUILT_IN_STRNCPY:
5792 target = expand_builtin_strncpy (exp, target, mode);
5793 if (target)
5794 return target;
5795 break;
5796
5797 case BUILT_IN_STPCPY:
5798 target = expand_builtin_stpcpy (exp, target, mode);
5799 if (target)
5800 return target;
5801 break;
5802
5803 case BUILT_IN_STRCAT:
5804 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5805 if (target)
5806 return target;
5807 break;
5808
5809 case BUILT_IN_STRNCAT:
5810 target = expand_builtin_strncat (arglist, target, mode);
5811 if (target)
5812 return target;
5813 break;
5814
5815 case BUILT_IN_STRSPN:
5816 target = expand_builtin_strspn (arglist, target, mode);
5817 if (target)
5818 return target;
5819 break;
5820
5821 case BUILT_IN_STRCSPN:
5822 target = expand_builtin_strcspn (arglist, target, mode);
5823 if (target)
5824 return target;
5825 break;
5826
5827 case BUILT_IN_STRSTR:
5828 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5829 if (target)
5830 return target;
5831 break;
5832
5833 case BUILT_IN_STRPBRK:
5834 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5835 if (target)
5836 return target;
5837 break;
5838
5839 case BUILT_IN_INDEX:
5840 case BUILT_IN_STRCHR:
5841 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5842 if (target)
5843 return target;
5844 break;
5845
5846 case BUILT_IN_RINDEX:
5847 case BUILT_IN_STRRCHR:
5848 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5849 if (target)
5850 return target;
5851 break;
5852
5853 case BUILT_IN_MEMCPY:
5854 target = expand_builtin_memcpy (exp, target, mode);
5855 if (target)
5856 return target;
5857 break;
5858
5859 case BUILT_IN_MEMPCPY:
5860 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5861 if (target)
5862 return target;
5863 break;
5864
5865 case BUILT_IN_MEMMOVE:
5866 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5867 mode, exp);
5868 if (target)
5869 return target;
5870 break;
5871
5872 case BUILT_IN_BCOPY:
5873 target = expand_builtin_bcopy (exp);
5874 if (target)
5875 return target;
5876 break;
5877
5878 case BUILT_IN_MEMSET:
5879 target = expand_builtin_memset (arglist, target, mode, exp);
5880 if (target)
5881 return target;
5882 break;
5883
5884 case BUILT_IN_BZERO:
5885 target = expand_builtin_bzero (exp);
5886 if (target)
5887 return target;
5888 break;
5889
5890 case BUILT_IN_STRCMP:
5891 target = expand_builtin_strcmp (exp, target, mode);
5892 if (target)
5893 return target;
5894 break;
5895
5896 case BUILT_IN_STRNCMP:
5897 target = expand_builtin_strncmp (exp, target, mode);
5898 if (target)
5899 return target;
5900 break;
5901
5902 case BUILT_IN_BCMP:
5903 case BUILT_IN_MEMCMP:
5904 target = expand_builtin_memcmp (exp, arglist, target, mode);
5905 if (target)
5906 return target;
5907 break;
5908
5909 case BUILT_IN_SETJMP:
5910 target = expand_builtin_setjmp (arglist, target);
5911 if (target)
5912 return target;
5913 break;
5914
5915 /* __builtin_longjmp is passed a pointer to an array of five words.
5916 It's similar to the C library longjmp function but works with
5917 __builtin_setjmp above. */
5918 case BUILT_IN_LONGJMP:
5919 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5920 break;
5921 else
5922 {
5923 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5924 VOIDmode, 0);
5925 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5926 NULL_RTX, VOIDmode, 0);
5927
5928 if (value != const1_rtx)
5929 {
5930 error ("%<__builtin_longjmp%> second argument must be 1");
5931 return const0_rtx;
5932 }
5933
5934 expand_builtin_longjmp (buf_addr, value);
5935 return const0_rtx;
5936 }
5937
5938 case BUILT_IN_NONLOCAL_GOTO:
5939 target = expand_builtin_nonlocal_goto (arglist);
5940 if (target)
5941 return target;
5942 break;
5943
5944 /* This updates the setjmp buffer that is its argument with the value
5945 of the current stack pointer. */
5946 case BUILT_IN_UPDATE_SETJMP_BUF:
5947 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5948 {
5949 rtx buf_addr
5950 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5951
5952 expand_builtin_update_setjmp_buf (buf_addr);
5953 return const0_rtx;
5954 }
5955 break;
5956
5957 case BUILT_IN_TRAP:
5958 expand_builtin_trap ();
5959 return const0_rtx;
5960
5961 case BUILT_IN_PRINTF:
5962 target = expand_builtin_printf (exp, target, mode, false);
5963 if (target)
5964 return target;
5965 break;
5966
5967 case BUILT_IN_PRINTF_UNLOCKED:
5968 target = expand_builtin_printf (exp, target, mode, true);
5969 if (target)
5970 return target;
5971 break;
5972
5973 case BUILT_IN_FPUTS:
5974 target = expand_builtin_fputs (arglist, target, false);
5975 if (target)
5976 return target;
5977 break;
5978 case BUILT_IN_FPUTS_UNLOCKED:
5979 target = expand_builtin_fputs (arglist, target, true);
5980 if (target)
5981 return target;
5982 break;
5983
5984 case BUILT_IN_FPRINTF:
5985 target = expand_builtin_fprintf (exp, target, mode, false);
5986 if (target)
5987 return target;
5988 break;
5989
5990 case BUILT_IN_FPRINTF_UNLOCKED:
5991 target = expand_builtin_fprintf (exp, target, mode, true);
5992 if (target)
5993 return target;
5994 break;
5995
5996 case BUILT_IN_SPRINTF:
5997 target = expand_builtin_sprintf (arglist, target, mode);
5998 if (target)
5999 return target;
6000 break;
6001
6002 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6003 target = expand_builtin_signbit (exp, target);
6004 if (target)
6005 return target;
6006 break;
6007
6008 /* Various hooks for the DWARF 2 __throw routine. */
6009 case BUILT_IN_UNWIND_INIT:
6010 expand_builtin_unwind_init ();
6011 return const0_rtx;
6012 case BUILT_IN_DWARF_CFA:
6013 return virtual_cfa_rtx;
6014 #ifdef DWARF2_UNWIND_INFO
6015 case BUILT_IN_DWARF_SP_COLUMN:
6016 return expand_builtin_dwarf_sp_column ();
6017 case BUILT_IN_INIT_DWARF_REG_SIZES:
6018 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6019 return const0_rtx;
6020 #endif
6021 case BUILT_IN_FROB_RETURN_ADDR:
6022 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6023 case BUILT_IN_EXTRACT_RETURN_ADDR:
6024 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6025 case BUILT_IN_EH_RETURN:
6026 expand_builtin_eh_return (TREE_VALUE (arglist),
6027 TREE_VALUE (TREE_CHAIN (arglist)));
6028 return const0_rtx;
6029 #ifdef EH_RETURN_DATA_REGNO
6030 case BUILT_IN_EH_RETURN_DATA_REGNO:
6031 return expand_builtin_eh_return_data_regno (arglist);
6032 #endif
6033 case BUILT_IN_EXTEND_POINTER:
6034 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6035
6036 case BUILT_IN_VA_START:
6037 case BUILT_IN_STDARG_START:
6038 return expand_builtin_va_start (arglist);
6039 case BUILT_IN_VA_END:
6040 return expand_builtin_va_end (arglist);
6041 case BUILT_IN_VA_COPY:
6042 return expand_builtin_va_copy (arglist);
6043 case BUILT_IN_EXPECT:
6044 return expand_builtin_expect (arglist, target);
6045 case BUILT_IN_PREFETCH:
6046 expand_builtin_prefetch (arglist);
6047 return const0_rtx;
6048
6049 case BUILT_IN_PROFILE_FUNC_ENTER:
6050 return expand_builtin_profile_func (false);
6051 case BUILT_IN_PROFILE_FUNC_EXIT:
6052 return expand_builtin_profile_func (true);
6053
6054 case BUILT_IN_INIT_TRAMPOLINE:
6055 return expand_builtin_init_trampoline (arglist);
6056 case BUILT_IN_ADJUST_TRAMPOLINE:
6057 return expand_builtin_adjust_trampoline (arglist);
6058
6059 case BUILT_IN_FORK:
6060 case BUILT_IN_EXECL:
6061 case BUILT_IN_EXECV:
6062 case BUILT_IN_EXECLP:
6063 case BUILT_IN_EXECLE:
6064 case BUILT_IN_EXECVP:
6065 case BUILT_IN_EXECVE:
6066 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6067 if (target)
6068 return target;
6069 break;
6070
6071 case BUILT_IN_FETCH_AND_ADD_1:
6072 case BUILT_IN_FETCH_AND_ADD_2:
6073 case BUILT_IN_FETCH_AND_ADD_4:
6074 case BUILT_IN_FETCH_AND_ADD_8:
6075 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6076 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6077 false, target, ignore);
6078 if (target)
6079 return target;
6080 break;
6081
6082 case BUILT_IN_FETCH_AND_SUB_1:
6083 case BUILT_IN_FETCH_AND_SUB_2:
6084 case BUILT_IN_FETCH_AND_SUB_4:
6085 case BUILT_IN_FETCH_AND_SUB_8:
6086 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6087 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6088 false, target, ignore);
6089 if (target)
6090 return target;
6091 break;
6092
6093 case BUILT_IN_FETCH_AND_OR_1:
6094 case BUILT_IN_FETCH_AND_OR_2:
6095 case BUILT_IN_FETCH_AND_OR_4:
6096 case BUILT_IN_FETCH_AND_OR_8:
6097 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6098 target = expand_builtin_sync_operation (mode, arglist, IOR,
6099 false, target, ignore);
6100 if (target)
6101 return target;
6102 break;
6103
6104 case BUILT_IN_FETCH_AND_AND_1:
6105 case BUILT_IN_FETCH_AND_AND_2:
6106 case BUILT_IN_FETCH_AND_AND_4:
6107 case BUILT_IN_FETCH_AND_AND_8:
6108 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6109 target = expand_builtin_sync_operation (mode, arglist, AND,
6110 false, target, ignore);
6111 if (target)
6112 return target;
6113 break;
6114
6115 case BUILT_IN_FETCH_AND_XOR_1:
6116 case BUILT_IN_FETCH_AND_XOR_2:
6117 case BUILT_IN_FETCH_AND_XOR_4:
6118 case BUILT_IN_FETCH_AND_XOR_8:
6119 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6120 target = expand_builtin_sync_operation (mode, arglist, XOR,
6121 false, target, ignore);
6122 if (target)
6123 return target;
6124 break;
6125
6126 case BUILT_IN_FETCH_AND_NAND_1:
6127 case BUILT_IN_FETCH_AND_NAND_2:
6128 case BUILT_IN_FETCH_AND_NAND_4:
6129 case BUILT_IN_FETCH_AND_NAND_8:
6130 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6131 target = expand_builtin_sync_operation (mode, arglist, NOT,
6132 false, target, ignore);
6133 if (target)
6134 return target;
6135 break;
6136
6137 case BUILT_IN_ADD_AND_FETCH_1:
6138 case BUILT_IN_ADD_AND_FETCH_2:
6139 case BUILT_IN_ADD_AND_FETCH_4:
6140 case BUILT_IN_ADD_AND_FETCH_8:
6141 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6142 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6143 true, target, ignore);
6144 if (target)
6145 return target;
6146 break;
6147
6148 case BUILT_IN_SUB_AND_FETCH_1:
6149 case BUILT_IN_SUB_AND_FETCH_2:
6150 case BUILT_IN_SUB_AND_FETCH_4:
6151 case BUILT_IN_SUB_AND_FETCH_8:
6152 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6153 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6154 true, target, ignore);
6155 if (target)
6156 return target;
6157 break;
6158
6159 case BUILT_IN_OR_AND_FETCH_1:
6160 case BUILT_IN_OR_AND_FETCH_2:
6161 case BUILT_IN_OR_AND_FETCH_4:
6162 case BUILT_IN_OR_AND_FETCH_8:
6163 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6164 target = expand_builtin_sync_operation (mode, arglist, IOR,
6165 true, target, ignore);
6166 if (target)
6167 return target;
6168 break;
6169
6170 case BUILT_IN_AND_AND_FETCH_1:
6171 case BUILT_IN_AND_AND_FETCH_2:
6172 case BUILT_IN_AND_AND_FETCH_4:
6173 case BUILT_IN_AND_AND_FETCH_8:
6174 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6175 target = expand_builtin_sync_operation (mode, arglist, AND,
6176 true, target, ignore);
6177 if (target)
6178 return target;
6179 break;
6180
6181 case BUILT_IN_XOR_AND_FETCH_1:
6182 case BUILT_IN_XOR_AND_FETCH_2:
6183 case BUILT_IN_XOR_AND_FETCH_4:
6184 case BUILT_IN_XOR_AND_FETCH_8:
6185 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6186 target = expand_builtin_sync_operation (mode, arglist, XOR,
6187 true, target, ignore);
6188 if (target)
6189 return target;
6190 break;
6191
6192 case BUILT_IN_NAND_AND_FETCH_1:
6193 case BUILT_IN_NAND_AND_FETCH_2:
6194 case BUILT_IN_NAND_AND_FETCH_4:
6195 case BUILT_IN_NAND_AND_FETCH_8:
6196 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6197 target = expand_builtin_sync_operation (mode, arglist, NOT,
6198 true, target, ignore);
6199 if (target)
6200 return target;
6201 break;
6202
6203 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6204 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6205 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6206 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6207 if (mode == VOIDmode)
6208 mode = TYPE_MODE (boolean_type_node);
6209 if (!target || !register_operand (target, mode))
6210 target = gen_reg_rtx (mode);
6211
6212 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6213 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6214 if (target)
6215 return target;
6216 break;
6217
6218 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6219 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6220 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6221 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6222 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6223 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6224 if (target)
6225 return target;
6226 break;
6227
6228 case BUILT_IN_LOCK_TEST_AND_SET_1:
6229 case BUILT_IN_LOCK_TEST_AND_SET_2:
6230 case BUILT_IN_LOCK_TEST_AND_SET_4:
6231 case BUILT_IN_LOCK_TEST_AND_SET_8:
6232 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6233 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6234 if (target)
6235 return target;
6236 break;
6237
6238 case BUILT_IN_LOCK_RELEASE_1:
6239 case BUILT_IN_LOCK_RELEASE_2:
6240 case BUILT_IN_LOCK_RELEASE_4:
6241 case BUILT_IN_LOCK_RELEASE_8:
6242 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6243 expand_builtin_lock_release (mode, arglist);
6244 return const0_rtx;
6245
6246 case BUILT_IN_SYNCHRONIZE:
6247 expand_builtin_synchronize ();
6248 return const0_rtx;
6249
6250 case BUILT_IN_OBJECT_SIZE:
6251 return expand_builtin_object_size (exp);
6252
6253 case BUILT_IN_MEMCPY_CHK:
6254 case BUILT_IN_MEMPCPY_CHK:
6255 case BUILT_IN_MEMMOVE_CHK:
6256 case BUILT_IN_MEMSET_CHK:
6257 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6258 if (target)
6259 return target;
6260 break;
6261
6262 case BUILT_IN_STRCPY_CHK:
6263 case BUILT_IN_STPCPY_CHK:
6264 case BUILT_IN_STRNCPY_CHK:
6265 case BUILT_IN_STRCAT_CHK:
6266 case BUILT_IN_SNPRINTF_CHK:
6267 case BUILT_IN_VSNPRINTF_CHK:
6268 maybe_emit_chk_warning (exp, fcode);
6269 break;
6270
6271 case BUILT_IN_SPRINTF_CHK:
6272 case BUILT_IN_VSPRINTF_CHK:
6273 maybe_emit_sprintf_chk_warning (exp, fcode);
6274 break;
6275
6276 default: /* just do library call, if unknown builtin */
6277 break;
6278 }
6279
6280 /* The switch statement above can drop through to cause the function
6281 to be called normally. */
6282 return expand_call (exp, target, ignore);
6283 }
6284
6285 /* Determine whether a tree node represents a call to a built-in
6286 function. If the tree T is a call to a built-in function with
6287 the right number of arguments of the appropriate types, return
6288 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6289 Otherwise the return value is END_BUILTINS. */
6290
6291 enum built_in_function
6292 builtin_mathfn_code (tree t)
6293 {
6294 tree fndecl, arglist, parmlist;
6295 tree argtype, parmtype;
6296
6297 if (TREE_CODE (t) != CALL_EXPR
6298 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6299 return END_BUILTINS;
6300
6301 fndecl = get_callee_fndecl (t);
6302 if (fndecl == NULL_TREE
6303 || TREE_CODE (fndecl) != FUNCTION_DECL
6304 || ! DECL_BUILT_IN (fndecl)
6305 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6306 return END_BUILTINS;
6307
6308 arglist = TREE_OPERAND (t, 1);
6309 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6310 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6311 {
6312 /* If a function doesn't take a variable number of arguments,
6313 the last element in the list will have type `void'. */
6314 parmtype = TREE_VALUE (parmlist);
6315 if (VOID_TYPE_P (parmtype))
6316 {
6317 if (arglist)
6318 return END_BUILTINS;
6319 return DECL_FUNCTION_CODE (fndecl);
6320 }
6321
6322 if (! arglist)
6323 return END_BUILTINS;
6324
6325 argtype = TREE_TYPE (TREE_VALUE (arglist));
6326
6327 if (SCALAR_FLOAT_TYPE_P (parmtype))
6328 {
6329 if (! SCALAR_FLOAT_TYPE_P (argtype))
6330 return END_BUILTINS;
6331 }
6332 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6333 {
6334 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6335 return END_BUILTINS;
6336 }
6337 else if (POINTER_TYPE_P (parmtype))
6338 {
6339 if (! POINTER_TYPE_P (argtype))
6340 return END_BUILTINS;
6341 }
6342 else if (INTEGRAL_TYPE_P (parmtype))
6343 {
6344 if (! INTEGRAL_TYPE_P (argtype))
6345 return END_BUILTINS;
6346 }
6347 else
6348 return END_BUILTINS;
6349
6350 arglist = TREE_CHAIN (arglist);
6351 }
6352
6353 /* Variable-length argument list. */
6354 return DECL_FUNCTION_CODE (fndecl);
6355 }
6356
6357 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6358 constant. ARGLIST is the argument list of the call. */
6359
6360 static tree
6361 fold_builtin_constant_p (tree arglist)
6362 {
6363 if (arglist == 0)
6364 return 0;
6365
6366 arglist = TREE_VALUE (arglist);
6367
6368 /* We return 1 for a numeric type that's known to be a constant
6369 value at compile-time or for an aggregate type that's a
6370 literal constant. */
6371 STRIP_NOPS (arglist);
6372
6373 /* If we know this is a constant, emit the constant of one. */
6374 if (CONSTANT_CLASS_P (arglist)
6375 || (TREE_CODE (arglist) == CONSTRUCTOR
6376 && TREE_CONSTANT (arglist)))
6377 return integer_one_node;
6378 if (TREE_CODE (arglist) == ADDR_EXPR)
6379 {
6380 tree op = TREE_OPERAND (arglist, 0);
6381 if (TREE_CODE (op) == STRING_CST
6382 || (TREE_CODE (op) == ARRAY_REF
6383 && integer_zerop (TREE_OPERAND (op, 1))
6384 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6385 return integer_one_node;
6386 }
6387
6388 /* If this expression has side effects, show we don't know it to be a
6389 constant. Likewise if it's a pointer or aggregate type since in
6390 those case we only want literals, since those are only optimized
6391 when generating RTL, not later.
6392 And finally, if we are compiling an initializer, not code, we
6393 need to return a definite result now; there's not going to be any
6394 more optimization done. */
6395 if (TREE_SIDE_EFFECTS (arglist)
6396 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6397 || POINTER_TYPE_P (TREE_TYPE (arglist))
6398 || cfun == 0)
6399 return integer_zero_node;
6400
6401 return 0;
6402 }
6403
6404 /* Fold a call to __builtin_expect, if we expect that a comparison against
6405 the argument will fold to a constant. In practice, this means a true
6406 constant or the address of a non-weak symbol. ARGLIST is the argument
6407 list of the call. */
6408
6409 static tree
6410 fold_builtin_expect (tree arglist)
6411 {
6412 tree arg, inner;
6413
6414 if (arglist == 0)
6415 return 0;
6416
6417 arg = TREE_VALUE (arglist);
6418
6419 /* If the argument isn't invariant, then there's nothing we can do. */
6420 if (!TREE_INVARIANT (arg))
6421 return 0;
6422
6423 /* If we're looking at an address of a weak decl, then do not fold. */
6424 inner = arg;
6425 STRIP_NOPS (inner);
6426 if (TREE_CODE (inner) == ADDR_EXPR)
6427 {
6428 do
6429 {
6430 inner = TREE_OPERAND (inner, 0);
6431 }
6432 while (TREE_CODE (inner) == COMPONENT_REF
6433 || TREE_CODE (inner) == ARRAY_REF);
6434 if (DECL_P (inner) && DECL_WEAK (inner))
6435 return 0;
6436 }
6437
6438 /* Otherwise, ARG already has the proper type for the return value. */
6439 return arg;
6440 }
6441
6442 /* Fold a call to __builtin_classify_type. */
6443
6444 static tree
6445 fold_builtin_classify_type (tree arglist)
6446 {
6447 if (arglist == 0)
6448 return build_int_cst (NULL_TREE, no_type_class);
6449
6450 return build_int_cst (NULL_TREE,
6451 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6452 }
6453
6454 /* Fold a call to __builtin_strlen. */
6455
6456 static tree
6457 fold_builtin_strlen (tree arglist)
6458 {
6459 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6460 return NULL_TREE;
6461 else
6462 {
6463 tree len = c_strlen (TREE_VALUE (arglist), 0);
6464
6465 if (len)
6466 {
6467 /* Convert from the internal "sizetype" type to "size_t". */
6468 if (size_type_node)
6469 len = fold_convert (size_type_node, len);
6470 return len;
6471 }
6472
6473 return NULL_TREE;
6474 }
6475 }
6476
6477 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6478
6479 static tree
6480 fold_builtin_inf (tree type, int warn)
6481 {
6482 REAL_VALUE_TYPE real;
6483
6484 /* __builtin_inff is intended to be usable to define INFINITY on all
6485 targets. If an infinity is not available, INFINITY expands "to a
6486 positive constant of type float that overflows at translation
6487 time", footnote "In this case, using INFINITY will violate the
6488 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6489 Thus we pedwarn to ensure this constraint violation is
6490 diagnosed. */
6491 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6492 pedwarn ("target format does not support infinity");
6493
6494 real_inf (&real);
6495 return build_real (type, real);
6496 }
6497
6498 /* Fold a call to __builtin_nan or __builtin_nans. */
6499
6500 static tree
6501 fold_builtin_nan (tree arglist, tree type, int quiet)
6502 {
6503 REAL_VALUE_TYPE real;
6504 const char *str;
6505
6506 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6507 return 0;
6508 str = c_getstr (TREE_VALUE (arglist));
6509 if (!str)
6510 return 0;
6511
6512 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6513 return 0;
6514
6515 return build_real (type, real);
6516 }
6517
6518 /* Return true if the floating point expression T has an integer value.
6519 We also allow +Inf, -Inf and NaN to be considered integer values. */
6520
6521 static bool
6522 integer_valued_real_p (tree t)
6523 {
6524 switch (TREE_CODE (t))
6525 {
6526 case FLOAT_EXPR:
6527 return true;
6528
6529 case ABS_EXPR:
6530 case SAVE_EXPR:
6531 case NON_LVALUE_EXPR:
6532 return integer_valued_real_p (TREE_OPERAND (t, 0));
6533
6534 case COMPOUND_EXPR:
6535 case MODIFY_EXPR:
6536 case BIND_EXPR:
6537 return integer_valued_real_p (TREE_OPERAND (t, 1));
6538
6539 case PLUS_EXPR:
6540 case MINUS_EXPR:
6541 case MULT_EXPR:
6542 case MIN_EXPR:
6543 case MAX_EXPR:
6544 return integer_valued_real_p (TREE_OPERAND (t, 0))
6545 && integer_valued_real_p (TREE_OPERAND (t, 1));
6546
6547 case COND_EXPR:
6548 return integer_valued_real_p (TREE_OPERAND (t, 1))
6549 && integer_valued_real_p (TREE_OPERAND (t, 2));
6550
6551 case REAL_CST:
6552 if (! TREE_CONSTANT_OVERFLOW (t))
6553 {
6554 REAL_VALUE_TYPE c, cint;
6555
6556 c = TREE_REAL_CST (t);
6557 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6558 return real_identical (&c, &cint);
6559 }
6560 break;
6561
6562 case NOP_EXPR:
6563 {
6564 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6565 if (TREE_CODE (type) == INTEGER_TYPE)
6566 return true;
6567 if (TREE_CODE (type) == REAL_TYPE)
6568 return integer_valued_real_p (TREE_OPERAND (t, 0));
6569 break;
6570 }
6571
6572 case CALL_EXPR:
6573 switch (builtin_mathfn_code (t))
6574 {
6575 CASE_FLT_FN (BUILT_IN_CEIL):
6576 CASE_FLT_FN (BUILT_IN_FLOOR):
6577 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6578 CASE_FLT_FN (BUILT_IN_RINT):
6579 CASE_FLT_FN (BUILT_IN_ROUND):
6580 CASE_FLT_FN (BUILT_IN_TRUNC):
6581 return true;
6582
6583 default:
6584 break;
6585 }
6586 break;
6587
6588 default:
6589 break;
6590 }
6591 return false;
6592 }
6593
6594 /* EXP is assumed to be builtin call where truncation can be propagated
6595 across (for instance floor((double)f) == (double)floorf (f).
6596 Do the transformation. */
6597
6598 static tree
6599 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6600 {
6601 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6602 tree arg;
6603
6604 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6605 return 0;
6606
6607 arg = TREE_VALUE (arglist);
6608 /* Integer rounding functions are idempotent. */
6609 if (fcode == builtin_mathfn_code (arg))
6610 return arg;
6611
6612 /* If argument is already integer valued, and we don't need to worry
6613 about setting errno, there's no need to perform rounding. */
6614 if (! flag_errno_math && integer_valued_real_p (arg))
6615 return arg;
6616
6617 if (optimize)
6618 {
6619 tree arg0 = strip_float_extensions (arg);
6620 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6621 tree newtype = TREE_TYPE (arg0);
6622 tree decl;
6623
6624 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6625 && (decl = mathfn_built_in (newtype, fcode)))
6626 {
6627 arglist =
6628 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6629 return fold_convert (ftype,
6630 build_function_call_expr (decl, arglist));
6631 }
6632 }
6633 return 0;
6634 }
6635
6636 /* EXP is assumed to be builtin call which can narrow the FP type of
6637 the argument, for instance lround((double)f) -> lroundf (f). */
6638
6639 static tree
6640 fold_fixed_mathfn (tree fndecl, tree arglist)
6641 {
6642 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6643 tree arg;
6644
6645 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6646 return 0;
6647
6648 arg = TREE_VALUE (arglist);
6649
6650 /* If argument is already integer valued, and we don't need to worry
6651 about setting errno, there's no need to perform rounding. */
6652 if (! flag_errno_math && integer_valued_real_p (arg))
6653 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6654
6655 if (optimize)
6656 {
6657 tree ftype = TREE_TYPE (arg);
6658 tree arg0 = strip_float_extensions (arg);
6659 tree newtype = TREE_TYPE (arg0);
6660 tree decl;
6661
6662 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6663 && (decl = mathfn_built_in (newtype, fcode)))
6664 {
6665 arglist =
6666 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6667 return build_function_call_expr (decl, arglist);
6668 }
6669 }
6670 return 0;
6671 }
6672
6673 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6674 is the argument list and TYPE is the return type. Return
6675 NULL_TREE if no if no simplification can be made. */
6676
6677 static tree
6678 fold_builtin_cabs (tree arglist, tree type)
6679 {
6680 tree arg;
6681
6682 if (!arglist || TREE_CHAIN (arglist))
6683 return NULL_TREE;
6684
6685 arg = TREE_VALUE (arglist);
6686 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6687 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6688 return NULL_TREE;
6689
6690 /* Evaluate cabs of a constant at compile-time. */
6691 if (flag_unsafe_math_optimizations
6692 && TREE_CODE (arg) == COMPLEX_CST
6693 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6694 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6695 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6696 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6697 {
6698 REAL_VALUE_TYPE r, i;
6699
6700 r = TREE_REAL_CST (TREE_REALPART (arg));
6701 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6702
6703 real_arithmetic (&r, MULT_EXPR, &r, &r);
6704 real_arithmetic (&i, MULT_EXPR, &i, &i);
6705 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6706 if (real_sqrt (&r, TYPE_MODE (type), &r)
6707 || ! flag_trapping_math)
6708 return build_real (type, r);
6709 }
6710
6711 /* If either part is zero, cabs is fabs of the other. */
6712 if (TREE_CODE (arg) == COMPLEX_EXPR
6713 && real_zerop (TREE_OPERAND (arg, 0)))
6714 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6715 if (TREE_CODE (arg) == COMPLEX_EXPR
6716 && real_zerop (TREE_OPERAND (arg, 1)))
6717 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6718
6719 /* Don't do this when optimizing for size. */
6720 if (flag_unsafe_math_optimizations
6721 && optimize && !optimize_size)
6722 {
6723 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6724
6725 if (sqrtfn != NULL_TREE)
6726 {
6727 tree rpart, ipart, result, arglist;
6728
6729 arg = builtin_save_expr (arg);
6730
6731 rpart = fold_build1 (REALPART_EXPR, type, arg);
6732 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6733
6734 rpart = builtin_save_expr (rpart);
6735 ipart = builtin_save_expr (ipart);
6736
6737 result = fold_build2 (PLUS_EXPR, type,
6738 fold_build2 (MULT_EXPR, type,
6739 rpart, rpart),
6740 fold_build2 (MULT_EXPR, type,
6741 ipart, ipart));
6742
6743 arglist = build_tree_list (NULL_TREE, result);
6744 return build_function_call_expr (sqrtfn, arglist);
6745 }
6746 }
6747
6748 return NULL_TREE;
6749 }
6750
6751 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6752 NULL_TREE if no simplification can be made. */
6753
6754 static tree
6755 fold_builtin_sqrt (tree arglist, tree type)
6756 {
6757
6758 enum built_in_function fcode;
6759 tree arg = TREE_VALUE (arglist);
6760
6761 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6762 return NULL_TREE;
6763
6764 /* Optimize sqrt of constant value. */
6765 if (TREE_CODE (arg) == REAL_CST
6766 && ! TREE_CONSTANT_OVERFLOW (arg))
6767 {
6768 REAL_VALUE_TYPE r, x;
6769
6770 x = TREE_REAL_CST (arg);
6771 if (real_sqrt (&r, TYPE_MODE (type), &x)
6772 || (!flag_trapping_math && !flag_errno_math))
6773 return build_real (type, r);
6774 }
6775
6776 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6777 fcode = builtin_mathfn_code (arg);
6778 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6779 {
6780 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6781 arg = fold_build2 (MULT_EXPR, type,
6782 TREE_VALUE (TREE_OPERAND (arg, 1)),
6783 build_real (type, dconsthalf));
6784 arglist = build_tree_list (NULL_TREE, arg);
6785 return build_function_call_expr (expfn, arglist);
6786 }
6787
6788 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6789 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6790 {
6791 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6792
6793 if (powfn)
6794 {
6795 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6796 tree tree_root;
6797 /* The inner root was either sqrt or cbrt. */
6798 REAL_VALUE_TYPE dconstroot =
6799 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6800
6801 /* Adjust for the outer root. */
6802 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6803 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6804 tree_root = build_real (type, dconstroot);
6805 arglist = tree_cons (NULL_TREE, arg0,
6806 build_tree_list (NULL_TREE, tree_root));
6807 return build_function_call_expr (powfn, arglist);
6808 }
6809 }
6810
6811 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6812 if (flag_unsafe_math_optimizations
6813 && (fcode == BUILT_IN_POW
6814 || fcode == BUILT_IN_POWF
6815 || fcode == BUILT_IN_POWL))
6816 {
6817 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6818 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6819 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6820 tree narg1;
6821 if (!tree_expr_nonnegative_p (arg0))
6822 arg0 = build1 (ABS_EXPR, type, arg0);
6823 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6824 build_real (type, dconsthalf));
6825 arglist = tree_cons (NULL_TREE, arg0,
6826 build_tree_list (NULL_TREE, narg1));
6827 return build_function_call_expr (powfn, arglist);
6828 }
6829
6830 return NULL_TREE;
6831 }
6832
6833 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6834 NULL_TREE if no simplification can be made. */
6835 static tree
6836 fold_builtin_cbrt (tree arglist, tree type)
6837 {
6838 tree arg = TREE_VALUE (arglist);
6839 const enum built_in_function fcode = builtin_mathfn_code (arg);
6840
6841 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6842 return NULL_TREE;
6843
6844 /* Optimize cbrt of constant value. */
6845 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6846 return arg;
6847
6848 if (flag_unsafe_math_optimizations)
6849 {
6850 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6851 if (BUILTIN_EXPONENT_P (fcode))
6852 {
6853 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6854 const REAL_VALUE_TYPE third_trunc =
6855 real_value_truncate (TYPE_MODE (type), dconstthird);
6856 arg = fold_build2 (MULT_EXPR, type,
6857 TREE_VALUE (TREE_OPERAND (arg, 1)),
6858 build_real (type, third_trunc));
6859 arglist = build_tree_list (NULL_TREE, arg);
6860 return build_function_call_expr (expfn, arglist);
6861 }
6862
6863 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6864 if (BUILTIN_SQRT_P (fcode))
6865 {
6866 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6867
6868 if (powfn)
6869 {
6870 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6871 tree tree_root;
6872 REAL_VALUE_TYPE dconstroot = dconstthird;
6873
6874 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6875 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6876 tree_root = build_real (type, dconstroot);
6877 arglist = tree_cons (NULL_TREE, arg0,
6878 build_tree_list (NULL_TREE, tree_root));
6879 return build_function_call_expr (powfn, arglist);
6880 }
6881 }
6882
6883 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6884 if (BUILTIN_CBRT_P (fcode))
6885 {
6886 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6887 if (tree_expr_nonnegative_p (arg0))
6888 {
6889 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6890
6891 if (powfn)
6892 {
6893 tree tree_root;
6894 REAL_VALUE_TYPE dconstroot;
6895
6896 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6897 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6898 tree_root = build_real (type, dconstroot);
6899 arglist = tree_cons (NULL_TREE, arg0,
6900 build_tree_list (NULL_TREE, tree_root));
6901 return build_function_call_expr (powfn, arglist);
6902 }
6903 }
6904 }
6905
6906 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6907 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6908 || fcode == BUILT_IN_POWL)
6909 {
6910 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6911 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6912 if (tree_expr_nonnegative_p (arg00))
6913 {
6914 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6915 const REAL_VALUE_TYPE dconstroot
6916 = real_value_truncate (TYPE_MODE (type), dconstthird);
6917 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
6918 build_real (type, dconstroot));
6919 arglist = tree_cons (NULL_TREE, arg00,
6920 build_tree_list (NULL_TREE, narg01));
6921 return build_function_call_expr (powfn, arglist);
6922 }
6923 }
6924 }
6925 return NULL_TREE;
6926 }
6927
6928 /* Fold function call to builtin sin, sinf, or sinl. Return
6929 NULL_TREE if no simplification can be made. */
6930 static tree
6931 fold_builtin_sin (tree arglist)
6932 {
6933 tree arg = TREE_VALUE (arglist);
6934
6935 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6936 return NULL_TREE;
6937
6938 /* Optimize sin (0.0) = 0.0. */
6939 if (real_zerop (arg))
6940 return arg;
6941
6942 return NULL_TREE;
6943 }
6944
6945 /* Fold function call to builtin cos, cosf, or cosl. Return
6946 NULL_TREE if no simplification can be made. */
6947 static tree
6948 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6949 {
6950 tree arg = TREE_VALUE (arglist);
6951
6952 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6953 return NULL_TREE;
6954
6955 /* Optimize cos (0.0) = 1.0. */
6956 if (real_zerop (arg))
6957 return build_real (type, dconst1);
6958
6959 /* Optimize cos(-x) into cos (x). */
6960 if (TREE_CODE (arg) == NEGATE_EXPR)
6961 {
6962 tree args = build_tree_list (NULL_TREE,
6963 TREE_OPERAND (arg, 0));
6964 return build_function_call_expr (fndecl, args);
6965 }
6966
6967 return NULL_TREE;
6968 }
6969
6970 /* Fold function call to builtin tan, tanf, or tanl. Return
6971 NULL_TREE if no simplification can be made. */
6972 static tree
6973 fold_builtin_tan (tree arglist)
6974 {
6975 enum built_in_function fcode;
6976 tree arg = TREE_VALUE (arglist);
6977
6978 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6979 return NULL_TREE;
6980
6981 /* Optimize tan(0.0) = 0.0. */
6982 if (real_zerop (arg))
6983 return arg;
6984
6985 /* Optimize tan(atan(x)) = x. */
6986 fcode = builtin_mathfn_code (arg);
6987 if (flag_unsafe_math_optimizations
6988 && (fcode == BUILT_IN_ATAN
6989 || fcode == BUILT_IN_ATANF
6990 || fcode == BUILT_IN_ATANL))
6991 return TREE_VALUE (TREE_OPERAND (arg, 1));
6992
6993 return NULL_TREE;
6994 }
6995
6996 /* Fold function call to builtin atan, atanf, or atanl. Return
6997 NULL_TREE if no simplification can be made. */
6998
6999 static tree
7000 fold_builtin_atan (tree arglist, tree type)
7001 {
7002
7003 tree arg = TREE_VALUE (arglist);
7004
7005 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7006 return NULL_TREE;
7007
7008 /* Optimize atan(0.0) = 0.0. */
7009 if (real_zerop (arg))
7010 return arg;
7011
7012 /* Optimize atan(1.0) = pi/4. */
7013 if (real_onep (arg))
7014 {
7015 REAL_VALUE_TYPE cst;
7016
7017 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7018 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7019 return build_real (type, cst);
7020 }
7021
7022 return NULL_TREE;
7023 }
7024
7025 /* Fold function call to builtin trunc, truncf or truncl. Return
7026 NULL_TREE if no simplification can be made. */
7027
7028 static tree
7029 fold_builtin_trunc (tree fndecl, tree arglist)
7030 {
7031 tree arg;
7032
7033 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7034 return 0;
7035
7036 /* Optimize trunc of constant value. */
7037 arg = TREE_VALUE (arglist);
7038 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7039 {
7040 REAL_VALUE_TYPE r, x;
7041 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7042
7043 x = TREE_REAL_CST (arg);
7044 real_trunc (&r, TYPE_MODE (type), &x);
7045 return build_real (type, r);
7046 }
7047
7048 return fold_trunc_transparent_mathfn (fndecl, arglist);
7049 }
7050
7051 /* Fold function call to builtin floor, floorf or floorl. Return
7052 NULL_TREE if no simplification can be made. */
7053
7054 static tree
7055 fold_builtin_floor (tree fndecl, tree arglist)
7056 {
7057 tree arg;
7058
7059 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7060 return 0;
7061
7062 /* Optimize floor of constant value. */
7063 arg = TREE_VALUE (arglist);
7064 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7065 {
7066 REAL_VALUE_TYPE x;
7067
7068 x = TREE_REAL_CST (arg);
7069 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7070 {
7071 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7072 REAL_VALUE_TYPE r;
7073
7074 real_floor (&r, TYPE_MODE (type), &x);
7075 return build_real (type, r);
7076 }
7077 }
7078
7079 return fold_trunc_transparent_mathfn (fndecl, arglist);
7080 }
7081
7082 /* Fold function call to builtin ceil, ceilf or ceill. Return
7083 NULL_TREE if no simplification can be made. */
7084
7085 static tree
7086 fold_builtin_ceil (tree fndecl, tree arglist)
7087 {
7088 tree arg;
7089
7090 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7091 return 0;
7092
7093 /* Optimize ceil of constant value. */
7094 arg = TREE_VALUE (arglist);
7095 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7096 {
7097 REAL_VALUE_TYPE x;
7098
7099 x = TREE_REAL_CST (arg);
7100 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7101 {
7102 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7103 REAL_VALUE_TYPE r;
7104
7105 real_ceil (&r, TYPE_MODE (type), &x);
7106 return build_real (type, r);
7107 }
7108 }
7109
7110 return fold_trunc_transparent_mathfn (fndecl, arglist);
7111 }
7112
7113 /* Fold function call to builtin round, roundf or roundl. Return
7114 NULL_TREE if no simplification can be made. */
7115
7116 static tree
7117 fold_builtin_round (tree fndecl, tree arglist)
7118 {
7119 tree arg;
7120
7121 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7122 return 0;
7123
7124 /* Optimize round of constant value. */
7125 arg = TREE_VALUE (arglist);
7126 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7127 {
7128 REAL_VALUE_TYPE x;
7129
7130 x = TREE_REAL_CST (arg);
7131 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7132 {
7133 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7134 REAL_VALUE_TYPE r;
7135
7136 real_round (&r, TYPE_MODE (type), &x);
7137 return build_real (type, r);
7138 }
7139 }
7140
7141 return fold_trunc_transparent_mathfn (fndecl, arglist);
7142 }
7143
7144 /* Fold function call to builtin lround, lroundf or lroundl (or the
7145 corresponding long long versions) and other rounding functions.
7146 Return NULL_TREE if no simplification can be made. */
7147
7148 static tree
7149 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7150 {
7151 tree arg;
7152
7153 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7154 return 0;
7155
7156 /* Optimize lround of constant value. */
7157 arg = TREE_VALUE (arglist);
7158 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7159 {
7160 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7161
7162 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7163 {
7164 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7165 tree ftype = TREE_TYPE (arg), result;
7166 HOST_WIDE_INT hi, lo;
7167 REAL_VALUE_TYPE r;
7168
7169 switch (DECL_FUNCTION_CODE (fndecl))
7170 {
7171 CASE_FLT_FN (BUILT_IN_LFLOOR):
7172 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7173 real_floor (&r, TYPE_MODE (ftype), &x);
7174 break;
7175
7176 CASE_FLT_FN (BUILT_IN_LCEIL):
7177 CASE_FLT_FN (BUILT_IN_LLCEIL):
7178 real_ceil (&r, TYPE_MODE (ftype), &x);
7179 break;
7180
7181 CASE_FLT_FN (BUILT_IN_LROUND):
7182 CASE_FLT_FN (BUILT_IN_LLROUND):
7183 real_round (&r, TYPE_MODE (ftype), &x);
7184 break;
7185
7186 default:
7187 gcc_unreachable ();
7188 }
7189
7190 REAL_VALUE_TO_INT (&lo, &hi, r);
7191 result = build_int_cst_wide (NULL_TREE, lo, hi);
7192 if (int_fits_type_p (result, itype))
7193 return fold_convert (itype, result);
7194 }
7195 }
7196
7197 return fold_fixed_mathfn (fndecl, arglist);
7198 }
7199
7200 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7201 and their long and long long variants (i.e. ffsl and ffsll).
7202 Return NULL_TREE if no simplification can be made. */
7203
7204 static tree
7205 fold_builtin_bitop (tree fndecl, tree arglist)
7206 {
7207 tree arg;
7208
7209 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7210 return NULL_TREE;
7211
7212 /* Optimize for constant argument. */
7213 arg = TREE_VALUE (arglist);
7214 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7215 {
7216 HOST_WIDE_INT hi, width, result;
7217 unsigned HOST_WIDE_INT lo;
7218 tree type;
7219
7220 type = TREE_TYPE (arg);
7221 width = TYPE_PRECISION (type);
7222 lo = TREE_INT_CST_LOW (arg);
7223
7224 /* Clear all the bits that are beyond the type's precision. */
7225 if (width > HOST_BITS_PER_WIDE_INT)
7226 {
7227 hi = TREE_INT_CST_HIGH (arg);
7228 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7229 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7230 }
7231 else
7232 {
7233 hi = 0;
7234 if (width < HOST_BITS_PER_WIDE_INT)
7235 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7236 }
7237
7238 switch (DECL_FUNCTION_CODE (fndecl))
7239 {
7240 CASE_INT_FN (BUILT_IN_FFS):
7241 if (lo != 0)
7242 result = exact_log2 (lo & -lo) + 1;
7243 else if (hi != 0)
7244 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7245 else
7246 result = 0;
7247 break;
7248
7249 CASE_INT_FN (BUILT_IN_CLZ):
7250 if (hi != 0)
7251 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7252 else if (lo != 0)
7253 result = width - floor_log2 (lo) - 1;
7254 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7255 result = width;
7256 break;
7257
7258 CASE_INT_FN (BUILT_IN_CTZ):
7259 if (lo != 0)
7260 result = exact_log2 (lo & -lo);
7261 else if (hi != 0)
7262 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7263 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7264 result = width;
7265 break;
7266
7267 CASE_INT_FN (BUILT_IN_POPCOUNT):
7268 result = 0;
7269 while (lo)
7270 result++, lo &= lo - 1;
7271 while (hi)
7272 result++, hi &= hi - 1;
7273 break;
7274
7275 CASE_INT_FN (BUILT_IN_PARITY):
7276 result = 0;
7277 while (lo)
7278 result++, lo &= lo - 1;
7279 while (hi)
7280 result++, hi &= hi - 1;
7281 result &= 1;
7282 break;
7283
7284 default:
7285 gcc_unreachable ();
7286 }
7287
7288 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7289 }
7290
7291 return NULL_TREE;
7292 }
7293
7294 /* Return true if EXPR is the real constant contained in VALUE. */
7295
7296 static bool
7297 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7298 {
7299 STRIP_NOPS (expr);
7300
7301 return ((TREE_CODE (expr) == REAL_CST
7302 && ! TREE_CONSTANT_OVERFLOW (expr)
7303 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7304 || (TREE_CODE (expr) == COMPLEX_CST
7305 && real_dconstp (TREE_REALPART (expr), value)
7306 && real_zerop (TREE_IMAGPART (expr))));
7307 }
7308
7309 /* A subroutine of fold_builtin to fold the various logarithmic
7310 functions. EXP is the CALL_EXPR of a call to a builtin logN
7311 function. VALUE is the base of the logN function. */
7312
7313 static tree
7314 fold_builtin_logarithm (tree fndecl, tree arglist,
7315 const REAL_VALUE_TYPE *value)
7316 {
7317 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7318 {
7319 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7320 tree arg = TREE_VALUE (arglist);
7321 const enum built_in_function fcode = builtin_mathfn_code (arg);
7322
7323 /* Optimize logN(1.0) = 0.0. */
7324 if (real_onep (arg))
7325 return build_real (type, dconst0);
7326
7327 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7328 exactly, then only do this if flag_unsafe_math_optimizations. */
7329 if (exact_real_truncate (TYPE_MODE (type), value)
7330 || flag_unsafe_math_optimizations)
7331 {
7332 const REAL_VALUE_TYPE value_truncate =
7333 real_value_truncate (TYPE_MODE (type), *value);
7334 if (real_dconstp (arg, &value_truncate))
7335 return build_real (type, dconst1);
7336 }
7337
7338 /* Special case, optimize logN(expN(x)) = x. */
7339 if (flag_unsafe_math_optimizations
7340 && ((value == &dconste
7341 && (fcode == BUILT_IN_EXP
7342 || fcode == BUILT_IN_EXPF
7343 || fcode == BUILT_IN_EXPL))
7344 || (value == &dconst2
7345 && (fcode == BUILT_IN_EXP2
7346 || fcode == BUILT_IN_EXP2F
7347 || fcode == BUILT_IN_EXP2L))
7348 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7349 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7350
7351 /* Optimize logN(func()) for various exponential functions. We
7352 want to determine the value "x" and the power "exponent" in
7353 order to transform logN(x**exponent) into exponent*logN(x). */
7354 if (flag_unsafe_math_optimizations)
7355 {
7356 tree exponent = 0, x = 0;
7357
7358 switch (fcode)
7359 {
7360 CASE_FLT_FN (BUILT_IN_EXP):
7361 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7362 x = build_real (type,
7363 real_value_truncate (TYPE_MODE (type), dconste));
7364 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7365 break;
7366 CASE_FLT_FN (BUILT_IN_EXP2):
7367 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7368 x = build_real (type, dconst2);
7369 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7370 break;
7371 CASE_FLT_FN (BUILT_IN_EXP10):
7372 CASE_FLT_FN (BUILT_IN_POW10):
7373 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7374 x = build_real (type, dconst10);
7375 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7376 break;
7377 CASE_FLT_FN (BUILT_IN_SQRT):
7378 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7379 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7380 exponent = build_real (type, dconsthalf);
7381 break;
7382 CASE_FLT_FN (BUILT_IN_CBRT):
7383 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7384 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7385 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7386 dconstthird));
7387 break;
7388 CASE_FLT_FN (BUILT_IN_POW):
7389 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7390 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7391 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7392 break;
7393 default:
7394 break;
7395 }
7396
7397 /* Now perform the optimization. */
7398 if (x && exponent)
7399 {
7400 tree logfn;
7401 arglist = build_tree_list (NULL_TREE, x);
7402 logfn = build_function_call_expr (fndecl, arglist);
7403 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7404 }
7405 }
7406 }
7407
7408 return 0;
7409 }
7410
7411 /* Fold a builtin function call to pow, powf, or powl. Return
7412 NULL_TREE if no simplification can be made. */
7413 static tree
7414 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7415 {
7416 tree arg0 = TREE_VALUE (arglist);
7417 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7418
7419 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7420 return NULL_TREE;
7421
7422 /* Optimize pow(1.0,y) = 1.0. */
7423 if (real_onep (arg0))
7424 return omit_one_operand (type, build_real (type, dconst1), arg1);
7425
7426 if (TREE_CODE (arg1) == REAL_CST
7427 && ! TREE_CONSTANT_OVERFLOW (arg1))
7428 {
7429 REAL_VALUE_TYPE cint;
7430 REAL_VALUE_TYPE c;
7431 HOST_WIDE_INT n;
7432
7433 c = TREE_REAL_CST (arg1);
7434
7435 /* Optimize pow(x,0.0) = 1.0. */
7436 if (REAL_VALUES_EQUAL (c, dconst0))
7437 return omit_one_operand (type, build_real (type, dconst1),
7438 arg0);
7439
7440 /* Optimize pow(x,1.0) = x. */
7441 if (REAL_VALUES_EQUAL (c, dconst1))
7442 return arg0;
7443
7444 /* Optimize pow(x,-1.0) = 1.0/x. */
7445 if (REAL_VALUES_EQUAL (c, dconstm1))
7446 return fold_build2 (RDIV_EXPR, type,
7447 build_real (type, dconst1), arg0);
7448
7449 /* Optimize pow(x,0.5) = sqrt(x). */
7450 if (flag_unsafe_math_optimizations
7451 && REAL_VALUES_EQUAL (c, dconsthalf))
7452 {
7453 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7454
7455 if (sqrtfn != NULL_TREE)
7456 {
7457 tree arglist = build_tree_list (NULL_TREE, arg0);
7458 return build_function_call_expr (sqrtfn, arglist);
7459 }
7460 }
7461
7462 /* Check for an integer exponent. */
7463 n = real_to_integer (&c);
7464 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7465 if (real_identical (&c, &cint))
7466 {
7467 /* Attempt to evaluate pow at compile-time. */
7468 if (TREE_CODE (arg0) == REAL_CST
7469 && ! TREE_CONSTANT_OVERFLOW (arg0))
7470 {
7471 REAL_VALUE_TYPE x;
7472 bool inexact;
7473
7474 x = TREE_REAL_CST (arg0);
7475 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7476 if (flag_unsafe_math_optimizations || !inexact)
7477 return build_real (type, x);
7478 }
7479
7480 /* Strip sign ops from even integer powers. */
7481 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7482 {
7483 tree narg0 = fold_strip_sign_ops (arg0);
7484 if (narg0)
7485 {
7486 arglist = build_tree_list (NULL_TREE, arg1);
7487 arglist = tree_cons (NULL_TREE, narg0, arglist);
7488 return build_function_call_expr (fndecl, arglist);
7489 }
7490 }
7491 }
7492 }
7493
7494 if (flag_unsafe_math_optimizations)
7495 {
7496 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7497
7498 /* Optimize pow(expN(x),y) = expN(x*y). */
7499 if (BUILTIN_EXPONENT_P (fcode))
7500 {
7501 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7502 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7503 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7504 arglist = build_tree_list (NULL_TREE, arg);
7505 return build_function_call_expr (expfn, arglist);
7506 }
7507
7508 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7509 if (BUILTIN_SQRT_P (fcode))
7510 {
7511 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7512 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7513 build_real (type, dconsthalf));
7514
7515 arglist = tree_cons (NULL_TREE, narg0,
7516 build_tree_list (NULL_TREE, narg1));
7517 return build_function_call_expr (fndecl, arglist);
7518 }
7519
7520 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7521 if (BUILTIN_CBRT_P (fcode))
7522 {
7523 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7524 if (tree_expr_nonnegative_p (arg))
7525 {
7526 const REAL_VALUE_TYPE dconstroot
7527 = real_value_truncate (TYPE_MODE (type), dconstthird);
7528 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7529 build_real (type, dconstroot));
7530 arglist = tree_cons (NULL_TREE, arg,
7531 build_tree_list (NULL_TREE, narg1));
7532 return build_function_call_expr (fndecl, arglist);
7533 }
7534 }
7535
7536 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7537 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7538 || fcode == BUILT_IN_POWL)
7539 {
7540 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7541 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7542 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7543 arglist = tree_cons (NULL_TREE, arg00,
7544 build_tree_list (NULL_TREE, narg1));
7545 return build_function_call_expr (fndecl, arglist);
7546 }
7547 }
7548
7549 return NULL_TREE;
7550 }
7551
7552 /* Fold a builtin function call to powi, powif, or powil. Return
7553 NULL_TREE if no simplification can be made. */
7554 static tree
7555 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7556 {
7557 tree arg0 = TREE_VALUE (arglist);
7558 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7559
7560 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7561 return NULL_TREE;
7562
7563 /* Optimize pow(1.0,y) = 1.0. */
7564 if (real_onep (arg0))
7565 return omit_one_operand (type, build_real (type, dconst1), arg1);
7566
7567 if (host_integerp (arg1, 0))
7568 {
7569 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7570
7571 /* Evaluate powi at compile-time. */
7572 if (TREE_CODE (arg0) == REAL_CST
7573 && ! TREE_CONSTANT_OVERFLOW (arg0))
7574 {
7575 REAL_VALUE_TYPE x;
7576 x = TREE_REAL_CST (arg0);
7577 real_powi (&x, TYPE_MODE (type), &x, c);
7578 return build_real (type, x);
7579 }
7580
7581 /* Optimize pow(x,0) = 1.0. */
7582 if (c == 0)
7583 return omit_one_operand (type, build_real (type, dconst1),
7584 arg0);
7585
7586 /* Optimize pow(x,1) = x. */
7587 if (c == 1)
7588 return arg0;
7589
7590 /* Optimize pow(x,-1) = 1.0/x. */
7591 if (c == -1)
7592 return fold_build2 (RDIV_EXPR, type,
7593 build_real (type, dconst1), arg0);
7594 }
7595
7596 return NULL_TREE;
7597 }
7598
7599 /* A subroutine of fold_builtin to fold the various exponent
7600 functions. EXP is the CALL_EXPR of a call to a builtin function.
7601 VALUE is the value which will be raised to a power. */
7602
7603 static tree
7604 fold_builtin_exponent (tree fndecl, tree arglist,
7605 const REAL_VALUE_TYPE *value)
7606 {
7607 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7608 {
7609 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7610 tree arg = TREE_VALUE (arglist);
7611
7612 /* Optimize exp*(0.0) = 1.0. */
7613 if (real_zerop (arg))
7614 return build_real (type, dconst1);
7615
7616 /* Optimize expN(1.0) = N. */
7617 if (real_onep (arg))
7618 {
7619 REAL_VALUE_TYPE cst;
7620
7621 real_convert (&cst, TYPE_MODE (type), value);
7622 return build_real (type, cst);
7623 }
7624
7625 /* Attempt to evaluate expN(integer) at compile-time. */
7626 if (flag_unsafe_math_optimizations
7627 && TREE_CODE (arg) == REAL_CST
7628 && ! TREE_CONSTANT_OVERFLOW (arg))
7629 {
7630 REAL_VALUE_TYPE cint;
7631 REAL_VALUE_TYPE c;
7632 HOST_WIDE_INT n;
7633
7634 c = TREE_REAL_CST (arg);
7635 n = real_to_integer (&c);
7636 real_from_integer (&cint, VOIDmode, n,
7637 n < 0 ? -1 : 0, 0);
7638 if (real_identical (&c, &cint))
7639 {
7640 REAL_VALUE_TYPE x;
7641
7642 real_powi (&x, TYPE_MODE (type), value, n);
7643 return build_real (type, x);
7644 }
7645 }
7646
7647 /* Optimize expN(logN(x)) = x. */
7648 if (flag_unsafe_math_optimizations)
7649 {
7650 const enum built_in_function fcode = builtin_mathfn_code (arg);
7651
7652 if ((value == &dconste
7653 && (fcode == BUILT_IN_LOG
7654 || fcode == BUILT_IN_LOGF
7655 || fcode == BUILT_IN_LOGL))
7656 || (value == &dconst2
7657 && (fcode == BUILT_IN_LOG2
7658 || fcode == BUILT_IN_LOG2F
7659 || fcode == BUILT_IN_LOG2L))
7660 || (value == &dconst10
7661 && (fcode == BUILT_IN_LOG10
7662 || fcode == BUILT_IN_LOG10F
7663 || fcode == BUILT_IN_LOG10L)))
7664 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7665 }
7666 }
7667
7668 return 0;
7669 }
7670
7671 /* Fold function call to builtin memcpy. Return
7672 NULL_TREE if no simplification can be made. */
7673
7674 static tree
7675 fold_builtin_memcpy (tree fndecl, tree arglist)
7676 {
7677 tree dest, src, len;
7678
7679 if (!validate_arglist (arglist,
7680 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7681 return 0;
7682
7683 dest = TREE_VALUE (arglist);
7684 src = TREE_VALUE (TREE_CHAIN (arglist));
7685 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7686
7687 /* If the LEN parameter is zero, return DEST. */
7688 if (integer_zerop (len))
7689 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7690
7691 /* If SRC and DEST are the same (and not volatile), return DEST. */
7692 if (operand_equal_p (src, dest, 0))
7693 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7694
7695 return 0;
7696 }
7697
7698 /* Fold function call to builtin mempcpy. Return
7699 NULL_TREE if no simplification can be made. */
7700
7701 static tree
7702 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7703 {
7704 if (validate_arglist (arglist,
7705 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7706 {
7707 tree dest = TREE_VALUE (arglist);
7708 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7709 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7710
7711 /* If the LEN parameter is zero, return DEST. */
7712 if (integer_zerop (len))
7713 return omit_one_operand (type, dest, src);
7714
7715 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7716 if (operand_equal_p (src, dest, 0))
7717 {
7718 if (endp == 0)
7719 return omit_one_operand (type, dest, len);
7720
7721 if (endp == 2)
7722 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7723 ssize_int (1));
7724
7725 len = fold_convert (TREE_TYPE (dest), len);
7726 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7727 return fold_convert (type, len);
7728 }
7729 }
7730 return 0;
7731 }
7732
7733 /* Fold function call to builtin memmove. Return
7734 NULL_TREE if no simplification can be made. */
7735
7736 static tree
7737 fold_builtin_memmove (tree arglist, tree type)
7738 {
7739 tree dest, src, len;
7740
7741 if (!validate_arglist (arglist,
7742 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7743 return 0;
7744
7745 dest = TREE_VALUE (arglist);
7746 src = TREE_VALUE (TREE_CHAIN (arglist));
7747 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7748
7749 /* If the LEN parameter is zero, return DEST. */
7750 if (integer_zerop (len))
7751 return omit_one_operand (type, dest, src);
7752
7753 /* If SRC and DEST are the same (and not volatile), return DEST. */
7754 if (operand_equal_p (src, dest, 0))
7755 return omit_one_operand (type, dest, len);
7756
7757 return 0;
7758 }
7759
7760 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7761 the length of the string to be copied. Return NULL_TREE if no
7762 simplification can be made. */
7763
7764 tree
7765 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7766 {
7767 tree dest, src, fn;
7768
7769 if (!validate_arglist (arglist,
7770 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7771 return 0;
7772
7773 dest = TREE_VALUE (arglist);
7774 src = TREE_VALUE (TREE_CHAIN (arglist));
7775
7776 /* If SRC and DEST are the same (and not volatile), return DEST. */
7777 if (operand_equal_p (src, dest, 0))
7778 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7779
7780 if (optimize_size)
7781 return 0;
7782
7783 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7784 if (!fn)
7785 return 0;
7786
7787 if (!len)
7788 {
7789 len = c_strlen (src, 1);
7790 if (! len || TREE_SIDE_EFFECTS (len))
7791 return 0;
7792 }
7793
7794 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7795 arglist = build_tree_list (NULL_TREE, len);
7796 arglist = tree_cons (NULL_TREE, src, arglist);
7797 arglist = tree_cons (NULL_TREE, dest, arglist);
7798 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7799 build_function_call_expr (fn, arglist));
7800 }
7801
7802 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7803 the length of the source string. Return NULL_TREE if no simplification
7804 can be made. */
7805
7806 tree
7807 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7808 {
7809 tree dest, src, len, fn;
7810
7811 if (!validate_arglist (arglist,
7812 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7813 return 0;
7814
7815 dest = TREE_VALUE (arglist);
7816 src = TREE_VALUE (TREE_CHAIN (arglist));
7817 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7818
7819 /* If the LEN parameter is zero, return DEST. */
7820 if (integer_zerop (len))
7821 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7822
7823 /* We can't compare slen with len as constants below if len is not a
7824 constant. */
7825 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7826 return 0;
7827
7828 if (!slen)
7829 slen = c_strlen (src, 1);
7830
7831 /* Now, we must be passed a constant src ptr parameter. */
7832 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7833 return 0;
7834
7835 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7836
7837 /* We do not support simplification of this case, though we do
7838 support it when expanding trees into RTL. */
7839 /* FIXME: generate a call to __builtin_memset. */
7840 if (tree_int_cst_lt (slen, len))
7841 return 0;
7842
7843 /* OK transform into builtin memcpy. */
7844 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7845 if (!fn)
7846 return 0;
7847 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7848 build_function_call_expr (fn, arglist));
7849 }
7850
7851 /* Fold function call to builtin memcmp. Return
7852 NULL_TREE if no simplification can be made. */
7853
7854 static tree
7855 fold_builtin_memcmp (tree arglist)
7856 {
7857 tree arg1, arg2, len;
7858 const char *p1, *p2;
7859
7860 if (!validate_arglist (arglist,
7861 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7862 return 0;
7863
7864 arg1 = TREE_VALUE (arglist);
7865 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7866 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7867
7868 /* If the LEN parameter is zero, return zero. */
7869 if (integer_zerop (len))
7870 return omit_two_operands (integer_type_node, integer_zero_node,
7871 arg1, arg2);
7872
7873 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7874 if (operand_equal_p (arg1, arg2, 0))
7875 return omit_one_operand (integer_type_node, integer_zero_node, len);
7876
7877 p1 = c_getstr (arg1);
7878 p2 = c_getstr (arg2);
7879
7880 /* If all arguments are constant, and the value of len is not greater
7881 than the lengths of arg1 and arg2, evaluate at compile-time. */
7882 if (host_integerp (len, 1) && p1 && p2
7883 && compare_tree_int (len, strlen (p1) + 1) <= 0
7884 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7885 {
7886 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7887
7888 if (r > 0)
7889 return integer_one_node;
7890 else if (r < 0)
7891 return integer_minus_one_node;
7892 else
7893 return integer_zero_node;
7894 }
7895
7896 /* If len parameter is one, return an expression corresponding to
7897 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7898 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7899 {
7900 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7901 tree cst_uchar_ptr_node
7902 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7903
7904 tree ind1 = fold_convert (integer_type_node,
7905 build1 (INDIRECT_REF, cst_uchar_node,
7906 fold_convert (cst_uchar_ptr_node,
7907 arg1)));
7908 tree ind2 = fold_convert (integer_type_node,
7909 build1 (INDIRECT_REF, cst_uchar_node,
7910 fold_convert (cst_uchar_ptr_node,
7911 arg2)));
7912 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
7913 }
7914
7915 return 0;
7916 }
7917
7918 /* Fold function call to builtin strcmp. Return
7919 NULL_TREE if no simplification can be made. */
7920
7921 static tree
7922 fold_builtin_strcmp (tree arglist)
7923 {
7924 tree arg1, arg2;
7925 const char *p1, *p2;
7926
7927 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7928 return 0;
7929
7930 arg1 = TREE_VALUE (arglist);
7931 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7932
7933 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7934 if (operand_equal_p (arg1, arg2, 0))
7935 return integer_zero_node;
7936
7937 p1 = c_getstr (arg1);
7938 p2 = c_getstr (arg2);
7939
7940 if (p1 && p2)
7941 {
7942 const int i = strcmp (p1, p2);
7943 if (i < 0)
7944 return integer_minus_one_node;
7945 else if (i > 0)
7946 return integer_one_node;
7947 else
7948 return integer_zero_node;
7949 }
7950
7951 /* If the second arg is "", return *(const unsigned char*)arg1. */
7952 if (p2 && *p2 == '\0')
7953 {
7954 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7955 tree cst_uchar_ptr_node
7956 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7957
7958 return fold_convert (integer_type_node,
7959 build1 (INDIRECT_REF, cst_uchar_node,
7960 fold_convert (cst_uchar_ptr_node,
7961 arg1)));
7962 }
7963
7964 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7965 if (p1 && *p1 == '\0')
7966 {
7967 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7968 tree cst_uchar_ptr_node
7969 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7970
7971 tree temp = fold_convert (integer_type_node,
7972 build1 (INDIRECT_REF, cst_uchar_node,
7973 fold_convert (cst_uchar_ptr_node,
7974 arg2)));
7975 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
7976 }
7977
7978 return 0;
7979 }
7980
7981 /* Fold function call to builtin strncmp. Return
7982 NULL_TREE if no simplification can be made. */
7983
7984 static tree
7985 fold_builtin_strncmp (tree arglist)
7986 {
7987 tree arg1, arg2, len;
7988 const char *p1, *p2;
7989
7990 if (!validate_arglist (arglist,
7991 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7992 return 0;
7993
7994 arg1 = TREE_VALUE (arglist);
7995 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7996 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7997
7998 /* If the LEN parameter is zero, return zero. */
7999 if (integer_zerop (len))
8000 return omit_two_operands (integer_type_node, integer_zero_node,
8001 arg1, arg2);
8002
8003 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8004 if (operand_equal_p (arg1, arg2, 0))
8005 return omit_one_operand (integer_type_node, integer_zero_node, len);
8006
8007 p1 = c_getstr (arg1);
8008 p2 = c_getstr (arg2);
8009
8010 if (host_integerp (len, 1) && p1 && p2)
8011 {
8012 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8013 if (i > 0)
8014 return integer_one_node;
8015 else if (i < 0)
8016 return integer_minus_one_node;
8017 else
8018 return integer_zero_node;
8019 }
8020
8021 /* If the second arg is "", and the length is greater than zero,
8022 return *(const unsigned char*)arg1. */
8023 if (p2 && *p2 == '\0'
8024 && TREE_CODE (len) == INTEGER_CST
8025 && tree_int_cst_sgn (len) == 1)
8026 {
8027 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8028 tree cst_uchar_ptr_node
8029 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8030
8031 return fold_convert (integer_type_node,
8032 build1 (INDIRECT_REF, cst_uchar_node,
8033 fold_convert (cst_uchar_ptr_node,
8034 arg1)));
8035 }
8036
8037 /* If the first arg is "", and the length is greater than zero,
8038 return -*(const unsigned char*)arg2. */
8039 if (p1 && *p1 == '\0'
8040 && TREE_CODE (len) == INTEGER_CST
8041 && tree_int_cst_sgn (len) == 1)
8042 {
8043 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8044 tree cst_uchar_ptr_node
8045 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8046
8047 tree temp = fold_convert (integer_type_node,
8048 build1 (INDIRECT_REF, cst_uchar_node,
8049 fold_convert (cst_uchar_ptr_node,
8050 arg2)));
8051 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8052 }
8053
8054 /* If len parameter is one, return an expression corresponding to
8055 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8056 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8057 {
8058 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8059 tree cst_uchar_ptr_node
8060 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8061
8062 tree ind1 = fold_convert (integer_type_node,
8063 build1 (INDIRECT_REF, cst_uchar_node,
8064 fold_convert (cst_uchar_ptr_node,
8065 arg1)));
8066 tree ind2 = fold_convert (integer_type_node,
8067 build1 (INDIRECT_REF, cst_uchar_node,
8068 fold_convert (cst_uchar_ptr_node,
8069 arg2)));
8070 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8071 }
8072
8073 return 0;
8074 }
8075
8076 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8077 NULL_TREE if no simplification can be made. */
8078
8079 static tree
8080 fold_builtin_signbit (tree fndecl, tree arglist)
8081 {
8082 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8083 tree arg, temp;
8084
8085 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8086 return NULL_TREE;
8087
8088 arg = TREE_VALUE (arglist);
8089
8090 /* If ARG is a compile-time constant, determine the result. */
8091 if (TREE_CODE (arg) == REAL_CST
8092 && !TREE_CONSTANT_OVERFLOW (arg))
8093 {
8094 REAL_VALUE_TYPE c;
8095
8096 c = TREE_REAL_CST (arg);
8097 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8098 return fold_convert (type, temp);
8099 }
8100
8101 /* If ARG is non-negative, the result is always zero. */
8102 if (tree_expr_nonnegative_p (arg))
8103 return omit_one_operand (type, integer_zero_node, arg);
8104
8105 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8106 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8107 return fold_build2 (LT_EXPR, type, arg,
8108 build_real (TREE_TYPE (arg), dconst0));
8109
8110 return NULL_TREE;
8111 }
8112
8113 /* Fold function call to builtin copysign, copysignf or copysignl.
8114 Return NULL_TREE if no simplification can be made. */
8115
8116 static tree
8117 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8118 {
8119 tree arg1, arg2, tem;
8120
8121 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8122 return NULL_TREE;
8123
8124 arg1 = TREE_VALUE (arglist);
8125 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8126
8127 /* copysign(X,X) is X. */
8128 if (operand_equal_p (arg1, arg2, 0))
8129 return fold_convert (type, arg1);
8130
8131 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8132 if (TREE_CODE (arg1) == REAL_CST
8133 && TREE_CODE (arg2) == REAL_CST
8134 && !TREE_CONSTANT_OVERFLOW (arg1)
8135 && !TREE_CONSTANT_OVERFLOW (arg2))
8136 {
8137 REAL_VALUE_TYPE c1, c2;
8138
8139 c1 = TREE_REAL_CST (arg1);
8140 c2 = TREE_REAL_CST (arg2);
8141 real_copysign (&c1, &c2);
8142 return build_real (type, c1);
8143 c1.sign = c2.sign;
8144 }
8145
8146 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8147 Remember to evaluate Y for side-effects. */
8148 if (tree_expr_nonnegative_p (arg2))
8149 return omit_one_operand (type,
8150 fold_build1 (ABS_EXPR, type, arg1),
8151 arg2);
8152
8153 /* Strip sign changing operations for the first argument. */
8154 tem = fold_strip_sign_ops (arg1);
8155 if (tem)
8156 {
8157 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8158 return build_function_call_expr (fndecl, arglist);
8159 }
8160
8161 return NULL_TREE;
8162 }
8163
8164 /* Fold a call to builtin isascii. */
8165
8166 static tree
8167 fold_builtin_isascii (tree arglist)
8168 {
8169 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8170 return 0;
8171 else
8172 {
8173 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8174 tree arg = TREE_VALUE (arglist);
8175
8176 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8177 build_int_cst (NULL_TREE,
8178 ~ (unsigned HOST_WIDE_INT) 0x7f));
8179 arg = fold_build2 (EQ_EXPR, integer_type_node,
8180 arg, integer_zero_node);
8181
8182 if (in_gimple_form && !TREE_CONSTANT (arg))
8183 return NULL_TREE;
8184 else
8185 return arg;
8186 }
8187 }
8188
8189 /* Fold a call to builtin toascii. */
8190
8191 static tree
8192 fold_builtin_toascii (tree arglist)
8193 {
8194 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8195 return 0;
8196 else
8197 {
8198 /* Transform toascii(c) -> (c & 0x7f). */
8199 tree arg = TREE_VALUE (arglist);
8200
8201 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8202 build_int_cst (NULL_TREE, 0x7f));
8203 }
8204 }
8205
8206 /* Fold a call to builtin isdigit. */
8207
8208 static tree
8209 fold_builtin_isdigit (tree arglist)
8210 {
8211 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8212 return 0;
8213 else
8214 {
8215 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8216 /* According to the C standard, isdigit is unaffected by locale.
8217 However, it definitely is affected by the target character set. */
8218 tree arg;
8219 unsigned HOST_WIDE_INT target_digit0
8220 = lang_hooks.to_target_charset ('0');
8221
8222 if (target_digit0 == 0)
8223 return NULL_TREE;
8224
8225 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8226 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8227 build_int_cst (unsigned_type_node, target_digit0));
8228 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8229 build_int_cst (unsigned_type_node, 9));
8230 if (in_gimple_form && !TREE_CONSTANT (arg))
8231 return NULL_TREE;
8232 else
8233 return arg;
8234 }
8235 }
8236
8237 /* Fold a call to fabs, fabsf or fabsl. */
8238
8239 static tree
8240 fold_builtin_fabs (tree arglist, tree type)
8241 {
8242 tree arg;
8243
8244 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8245 return 0;
8246
8247 arg = TREE_VALUE (arglist);
8248 arg = fold_convert (type, arg);
8249 if (TREE_CODE (arg) == REAL_CST)
8250 return fold_abs_const (arg, type);
8251 return fold_build1 (ABS_EXPR, type, arg);
8252 }
8253
8254 /* Fold a call to abs, labs, llabs or imaxabs. */
8255
8256 static tree
8257 fold_builtin_abs (tree arglist, tree type)
8258 {
8259 tree arg;
8260
8261 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8262 return 0;
8263
8264 arg = TREE_VALUE (arglist);
8265 arg = fold_convert (type, arg);
8266 if (TREE_CODE (arg) == INTEGER_CST)
8267 return fold_abs_const (arg, type);
8268 return fold_build1 (ABS_EXPR, type, arg);
8269 }
8270
8271 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8272 EXP is the CALL_EXPR for the call. */
8273
8274 static tree
8275 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8276 {
8277 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8278 tree arg;
8279 REAL_VALUE_TYPE r;
8280
8281 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8282 {
8283 /* Check that we have exactly one argument. */
8284 if (arglist == 0)
8285 {
8286 error ("too few arguments to function %qs",
8287 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8288 return error_mark_node;
8289 }
8290 else if (TREE_CHAIN (arglist) != 0)
8291 {
8292 error ("too many arguments to function %qs",
8293 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8294 return error_mark_node;
8295 }
8296 else
8297 {
8298 error ("non-floating-point argument to function %qs",
8299 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8300 return error_mark_node;
8301 }
8302 }
8303
8304 arg = TREE_VALUE (arglist);
8305 switch (builtin_index)
8306 {
8307 case BUILT_IN_ISINF:
8308 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8309 return omit_one_operand (type, integer_zero_node, arg);
8310
8311 if (TREE_CODE (arg) == REAL_CST)
8312 {
8313 r = TREE_REAL_CST (arg);
8314 if (real_isinf (&r))
8315 return real_compare (GT_EXPR, &r, &dconst0)
8316 ? integer_one_node : integer_minus_one_node;
8317 else
8318 return integer_zero_node;
8319 }
8320
8321 return NULL_TREE;
8322
8323 case BUILT_IN_FINITE:
8324 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8325 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8326 return omit_one_operand (type, integer_zero_node, arg);
8327
8328 if (TREE_CODE (arg) == REAL_CST)
8329 {
8330 r = TREE_REAL_CST (arg);
8331 return real_isinf (&r) || real_isnan (&r)
8332 ? integer_zero_node : integer_one_node;
8333 }
8334
8335 return NULL_TREE;
8336
8337 case BUILT_IN_ISNAN:
8338 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8339 return omit_one_operand (type, integer_zero_node, arg);
8340
8341 if (TREE_CODE (arg) == REAL_CST)
8342 {
8343 r = TREE_REAL_CST (arg);
8344 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8345 }
8346
8347 arg = builtin_save_expr (arg);
8348 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8349
8350 default:
8351 gcc_unreachable ();
8352 }
8353 }
8354
8355 /* Fold a call to an unordered comparison function such as
8356 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8357 being called and ARGLIST is the argument list for the call.
8358 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8359 the opposite of the desired result. UNORDERED_CODE is used
8360 for modes that can hold NaNs and ORDERED_CODE is used for
8361 the rest. */
8362
8363 static tree
8364 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8365 enum tree_code unordered_code,
8366 enum tree_code ordered_code)
8367 {
8368 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8369 enum tree_code code;
8370 tree arg0, arg1;
8371 tree type0, type1;
8372 enum tree_code code0, code1;
8373 tree cmp_type = NULL_TREE;
8374
8375 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8376 {
8377 /* Check that we have exactly two arguments. */
8378 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8379 {
8380 error ("too few arguments to function %qs",
8381 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8382 return error_mark_node;
8383 }
8384 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8385 {
8386 error ("too many arguments to function %qs",
8387 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8388 return error_mark_node;
8389 }
8390 }
8391
8392 arg0 = TREE_VALUE (arglist);
8393 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8394
8395 type0 = TREE_TYPE (arg0);
8396 type1 = TREE_TYPE (arg1);
8397
8398 code0 = TREE_CODE (type0);
8399 code1 = TREE_CODE (type1);
8400
8401 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8402 /* Choose the wider of two real types. */
8403 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8404 ? type0 : type1;
8405 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8406 cmp_type = type0;
8407 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8408 cmp_type = type1;
8409 else
8410 {
8411 error ("non-floating-point argument to function %qs",
8412 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8413 return error_mark_node;
8414 }
8415
8416 arg0 = fold_convert (cmp_type, arg0);
8417 arg1 = fold_convert (cmp_type, arg1);
8418
8419 if (unordered_code == UNORDERED_EXPR)
8420 {
8421 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8422 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8423 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8424 }
8425
8426 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8427 : ordered_code;
8428 return fold_build1 (TRUTH_NOT_EXPR, type,
8429 fold_build2 (code, type, arg0, arg1));
8430 }
8431
8432 /* Used by constant folding to simplify calls to builtin functions. EXP is
8433 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8434 result of the function call is ignored. This function returns NULL_TREE
8435 if no simplification was possible. */
8436
8437 static tree
8438 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8439 {
8440 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8441 enum built_in_function fcode;
8442
8443 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8444 return targetm.fold_builtin (fndecl, arglist, ignore);
8445
8446 fcode = DECL_FUNCTION_CODE (fndecl);
8447 switch (fcode)
8448 {
8449 case BUILT_IN_FPUTS:
8450 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8451
8452 case BUILT_IN_FPUTS_UNLOCKED:
8453 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8454
8455 case BUILT_IN_STRSTR:
8456 return fold_builtin_strstr (arglist, type);
8457
8458 case BUILT_IN_STRCAT:
8459 return fold_builtin_strcat (arglist);
8460
8461 case BUILT_IN_STRNCAT:
8462 return fold_builtin_strncat (arglist);
8463
8464 case BUILT_IN_STRSPN:
8465 return fold_builtin_strspn (arglist);
8466
8467 case BUILT_IN_STRCSPN:
8468 return fold_builtin_strcspn (arglist);
8469
8470 case BUILT_IN_STRCHR:
8471 case BUILT_IN_INDEX:
8472 return fold_builtin_strchr (arglist, type);
8473
8474 case BUILT_IN_STRRCHR:
8475 case BUILT_IN_RINDEX:
8476 return fold_builtin_strrchr (arglist, type);
8477
8478 case BUILT_IN_STRCPY:
8479 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8480
8481 case BUILT_IN_STRNCPY:
8482 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8483
8484 case BUILT_IN_STRCMP:
8485 return fold_builtin_strcmp (arglist);
8486
8487 case BUILT_IN_STRNCMP:
8488 return fold_builtin_strncmp (arglist);
8489
8490 case BUILT_IN_STRPBRK:
8491 return fold_builtin_strpbrk (arglist, type);
8492
8493 case BUILT_IN_BCMP:
8494 case BUILT_IN_MEMCMP:
8495 return fold_builtin_memcmp (arglist);
8496
8497 case BUILT_IN_SPRINTF:
8498 return fold_builtin_sprintf (arglist, ignore);
8499
8500 case BUILT_IN_CONSTANT_P:
8501 {
8502 tree val;
8503
8504 val = fold_builtin_constant_p (arglist);
8505 /* Gimplification will pull the CALL_EXPR for the builtin out of
8506 an if condition. When not optimizing, we'll not CSE it back.
8507 To avoid link error types of regressions, return false now. */
8508 if (!val && !optimize)
8509 val = integer_zero_node;
8510
8511 return val;
8512 }
8513
8514 case BUILT_IN_EXPECT:
8515 return fold_builtin_expect (arglist);
8516
8517 case BUILT_IN_CLASSIFY_TYPE:
8518 return fold_builtin_classify_type (arglist);
8519
8520 case BUILT_IN_STRLEN:
8521 return fold_builtin_strlen (arglist);
8522
8523 CASE_FLT_FN (BUILT_IN_FABS):
8524 return fold_builtin_fabs (arglist, type);
8525
8526 case BUILT_IN_ABS:
8527 case BUILT_IN_LABS:
8528 case BUILT_IN_LLABS:
8529 case BUILT_IN_IMAXABS:
8530 return fold_builtin_abs (arglist, type);
8531
8532 CASE_FLT_FN (BUILT_IN_CONJ):
8533 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8534 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8535 break;
8536
8537 CASE_FLT_FN (BUILT_IN_CREAL):
8538 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8539 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8540 TREE_VALUE (arglist)));
8541 break;
8542
8543 CASE_FLT_FN (BUILT_IN_CIMAG):
8544 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8545 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8546 TREE_VALUE (arglist)));
8547 break;
8548
8549 CASE_FLT_FN (BUILT_IN_CABS):
8550 return fold_builtin_cabs (arglist, type);
8551
8552 CASE_FLT_FN (BUILT_IN_SQRT):
8553 return fold_builtin_sqrt (arglist, type);
8554
8555 CASE_FLT_FN (BUILT_IN_CBRT):
8556 return fold_builtin_cbrt (arglist, type);
8557
8558 CASE_FLT_FN (BUILT_IN_SIN):
8559 return fold_builtin_sin (arglist);
8560
8561 CASE_FLT_FN (BUILT_IN_COS):
8562 return fold_builtin_cos (arglist, type, fndecl);
8563
8564 CASE_FLT_FN (BUILT_IN_EXP):
8565 return fold_builtin_exponent (fndecl, arglist, &dconste);
8566
8567 CASE_FLT_FN (BUILT_IN_EXP2):
8568 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8569
8570 CASE_FLT_FN (BUILT_IN_EXP10):
8571 CASE_FLT_FN (BUILT_IN_POW10):
8572 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8573
8574 CASE_FLT_FN (BUILT_IN_LOG):
8575 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8576
8577 CASE_FLT_FN (BUILT_IN_LOG2):
8578 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8579
8580 CASE_FLT_FN (BUILT_IN_LOG10):
8581 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8582
8583 CASE_FLT_FN (BUILT_IN_TAN):
8584 return fold_builtin_tan (arglist);
8585
8586 CASE_FLT_FN (BUILT_IN_ATAN):
8587 return fold_builtin_atan (arglist, type);
8588
8589 CASE_FLT_FN (BUILT_IN_POW):
8590 return fold_builtin_pow (fndecl, arglist, type);
8591
8592 CASE_FLT_FN (BUILT_IN_POWI):
8593 return fold_builtin_powi (fndecl, arglist, type);
8594
8595 CASE_FLT_FN (BUILT_IN_INF):
8596 return fold_builtin_inf (type, true);
8597
8598 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8599 return fold_builtin_inf (type, false);
8600
8601 CASE_FLT_FN (BUILT_IN_NAN):
8602 return fold_builtin_nan (arglist, type, true);
8603
8604 CASE_FLT_FN (BUILT_IN_NANS):
8605 return fold_builtin_nan (arglist, type, false);
8606
8607 CASE_FLT_FN (BUILT_IN_FLOOR):
8608 return fold_builtin_floor (fndecl, arglist);
8609
8610 CASE_FLT_FN (BUILT_IN_CEIL):
8611 return fold_builtin_ceil (fndecl, arglist);
8612
8613 CASE_FLT_FN (BUILT_IN_TRUNC):
8614 return fold_builtin_trunc (fndecl, arglist);
8615
8616 CASE_FLT_FN (BUILT_IN_ROUND):
8617 return fold_builtin_round (fndecl, arglist);
8618
8619 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8620 CASE_FLT_FN (BUILT_IN_RINT):
8621 return fold_trunc_transparent_mathfn (fndecl, arglist);
8622
8623 CASE_FLT_FN (BUILT_IN_LCEIL):
8624 CASE_FLT_FN (BUILT_IN_LLCEIL):
8625 CASE_FLT_FN (BUILT_IN_LFLOOR):
8626 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8627 CASE_FLT_FN (BUILT_IN_LROUND):
8628 CASE_FLT_FN (BUILT_IN_LLROUND):
8629 return fold_builtin_int_roundingfn (fndecl, arglist);
8630
8631 CASE_FLT_FN (BUILT_IN_LRINT):
8632 CASE_FLT_FN (BUILT_IN_LLRINT):
8633 return fold_fixed_mathfn (fndecl, arglist);
8634
8635 CASE_INT_FN (BUILT_IN_FFS):
8636 CASE_INT_FN (BUILT_IN_CLZ):
8637 CASE_INT_FN (BUILT_IN_CTZ):
8638 CASE_INT_FN (BUILT_IN_POPCOUNT):
8639 CASE_INT_FN (BUILT_IN_PARITY):
8640 return fold_builtin_bitop (fndecl, arglist);
8641
8642 case BUILT_IN_MEMCPY:
8643 return fold_builtin_memcpy (fndecl, arglist);
8644
8645 case BUILT_IN_MEMPCPY:
8646 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8647
8648 case BUILT_IN_MEMMOVE:
8649 return fold_builtin_memmove (arglist, type);
8650
8651 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8652 return fold_builtin_signbit (fndecl, arglist);
8653
8654 case BUILT_IN_ISASCII:
8655 return fold_builtin_isascii (arglist);
8656
8657 case BUILT_IN_TOASCII:
8658 return fold_builtin_toascii (arglist);
8659
8660 case BUILT_IN_ISDIGIT:
8661 return fold_builtin_isdigit (arglist);
8662
8663 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8664 return fold_builtin_copysign (fndecl, arglist, type);
8665
8666 CASE_FLT_FN (BUILT_IN_FINITE):
8667 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8668
8669 CASE_FLT_FN (BUILT_IN_ISINF):
8670 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8671
8672 CASE_FLT_FN (BUILT_IN_ISNAN):
8673 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8674
8675 case BUILT_IN_ISGREATER:
8676 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8677 case BUILT_IN_ISGREATEREQUAL:
8678 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8679 case BUILT_IN_ISLESS:
8680 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8681 case BUILT_IN_ISLESSEQUAL:
8682 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8683 case BUILT_IN_ISLESSGREATER:
8684 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8685 case BUILT_IN_ISUNORDERED:
8686 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8687 NOP_EXPR);
8688
8689 /* We do the folding for va_start in the expander. */
8690 case BUILT_IN_VA_START:
8691 break;
8692
8693 case BUILT_IN_OBJECT_SIZE:
8694 return fold_builtin_object_size (arglist);
8695 case BUILT_IN_MEMCPY_CHK:
8696 case BUILT_IN_MEMPCPY_CHK:
8697 case BUILT_IN_MEMMOVE_CHK:
8698 case BUILT_IN_MEMSET_CHK:
8699 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8700 DECL_FUNCTION_CODE (fndecl));
8701 case BUILT_IN_STRCPY_CHK:
8702 case BUILT_IN_STPCPY_CHK:
8703 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8704 DECL_FUNCTION_CODE (fndecl));
8705 case BUILT_IN_STRNCPY_CHK:
8706 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8707 case BUILT_IN_STRCAT_CHK:
8708 return fold_builtin_strcat_chk (fndecl, arglist);
8709 case BUILT_IN_STRNCAT_CHK:
8710 return fold_builtin_strncat_chk (fndecl, arglist);
8711 case BUILT_IN_SPRINTF_CHK:
8712 case BUILT_IN_VSPRINTF_CHK:
8713 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8714 case BUILT_IN_SNPRINTF_CHK:
8715 case BUILT_IN_VSNPRINTF_CHK:
8716 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8717 DECL_FUNCTION_CODE (fndecl));
8718
8719 case BUILT_IN_PRINTF:
8720 case BUILT_IN_PRINTF_UNLOCKED:
8721 case BUILT_IN_VPRINTF:
8722 case BUILT_IN_PRINTF_CHK:
8723 case BUILT_IN_VPRINTF_CHK:
8724 return fold_builtin_printf (fndecl, arglist, ignore,
8725 DECL_FUNCTION_CODE (fndecl));
8726
8727 case BUILT_IN_FPRINTF:
8728 case BUILT_IN_FPRINTF_UNLOCKED:
8729 case BUILT_IN_VFPRINTF:
8730 case BUILT_IN_FPRINTF_CHK:
8731 case BUILT_IN_VFPRINTF_CHK:
8732 return fold_builtin_fprintf (fndecl, arglist, ignore,
8733 DECL_FUNCTION_CODE (fndecl));
8734
8735 default:
8736 break;
8737 }
8738
8739 return 0;
8740 }
8741
8742 /* A wrapper function for builtin folding that prevents warnings for
8743 "statement without effect" and the like, caused by removing the
8744 call node earlier than the warning is generated. */
8745
8746 tree
8747 fold_builtin (tree fndecl, tree arglist, bool ignore)
8748 {
8749 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8750 if (exp)
8751 {
8752 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8753 TREE_NO_WARNING (exp) = 1;
8754 }
8755
8756 return exp;
8757 }
8758
8759 /* Conveniently construct a function call expression. */
8760
8761 tree
8762 build_function_call_expr (tree fn, tree arglist)
8763 {
8764 tree call_expr;
8765
8766 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8767 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8768 call_expr, arglist, NULL_TREE);
8769 }
8770
8771 /* This function validates the types of a function call argument list
8772 represented as a tree chain of parameters against a specified list
8773 of tree_codes. If the last specifier is a 0, that represents an
8774 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8775
8776 static int
8777 validate_arglist (tree arglist, ...)
8778 {
8779 enum tree_code code;
8780 int res = 0;
8781 va_list ap;
8782
8783 va_start (ap, arglist);
8784
8785 do
8786 {
8787 code = va_arg (ap, enum tree_code);
8788 switch (code)
8789 {
8790 case 0:
8791 /* This signifies an ellipses, any further arguments are all ok. */
8792 res = 1;
8793 goto end;
8794 case VOID_TYPE:
8795 /* This signifies an endlink, if no arguments remain, return
8796 true, otherwise return false. */
8797 res = arglist == 0;
8798 goto end;
8799 default:
8800 /* If no parameters remain or the parameter's code does not
8801 match the specified code, return false. Otherwise continue
8802 checking any remaining arguments. */
8803 if (arglist == 0)
8804 goto end;
8805 if (code == POINTER_TYPE)
8806 {
8807 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8808 goto end;
8809 }
8810 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8811 goto end;
8812 break;
8813 }
8814 arglist = TREE_CHAIN (arglist);
8815 }
8816 while (1);
8817
8818 /* We need gotos here since we can only have one VA_CLOSE in a
8819 function. */
8820 end: ;
8821 va_end (ap);
8822
8823 return res;
8824 }
8825
8826 /* Default target-specific builtin expander that does nothing. */
8827
8828 rtx
8829 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8830 rtx target ATTRIBUTE_UNUSED,
8831 rtx subtarget ATTRIBUTE_UNUSED,
8832 enum machine_mode mode ATTRIBUTE_UNUSED,
8833 int ignore ATTRIBUTE_UNUSED)
8834 {
8835 return NULL_RTX;
8836 }
8837
8838 /* Returns true is EXP represents data that would potentially reside
8839 in a readonly section. */
8840
8841 static bool
8842 readonly_data_expr (tree exp)
8843 {
8844 STRIP_NOPS (exp);
8845
8846 if (TREE_CODE (exp) != ADDR_EXPR)
8847 return false;
8848
8849 exp = get_base_address (TREE_OPERAND (exp, 0));
8850 if (!exp)
8851 return false;
8852
8853 /* Make sure we call decl_readonly_section only for trees it
8854 can handle (since it returns true for everything it doesn't
8855 understand). */
8856 if (TREE_CODE (exp) == STRING_CST
8857 || TREE_CODE (exp) == CONSTRUCTOR
8858 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8859 return decl_readonly_section (exp, 0);
8860 else
8861 return false;
8862 }
8863
8864 /* Simplify a call to the strstr builtin.
8865
8866 Return 0 if no simplification was possible, otherwise return the
8867 simplified form of the call as a tree.
8868
8869 The simplified form may be a constant or other expression which
8870 computes the same value, but in a more efficient manner (including
8871 calls to other builtin functions).
8872
8873 The call may contain arguments which need to be evaluated, but
8874 which are not useful to determine the result of the call. In
8875 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8876 COMPOUND_EXPR will be an argument which must be evaluated.
8877 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8878 COMPOUND_EXPR in the chain will contain the tree for the simplified
8879 form of the builtin function call. */
8880
8881 static tree
8882 fold_builtin_strstr (tree arglist, tree type)
8883 {
8884 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8885 return 0;
8886 else
8887 {
8888 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8889 tree fn;
8890 const char *p1, *p2;
8891
8892 p2 = c_getstr (s2);
8893 if (p2 == NULL)
8894 return 0;
8895
8896 p1 = c_getstr (s1);
8897 if (p1 != NULL)
8898 {
8899 const char *r = strstr (p1, p2);
8900 tree tem;
8901
8902 if (r == NULL)
8903 return build_int_cst (TREE_TYPE (s1), 0);
8904
8905 /* Return an offset into the constant string argument. */
8906 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
8907 s1, build_int_cst (TREE_TYPE (s1), r - p1));
8908 return fold_convert (type, tem);
8909 }
8910
8911 /* The argument is const char *, and the result is char *, so we need
8912 a type conversion here to avoid a warning. */
8913 if (p2[0] == '\0')
8914 return fold_convert (type, s1);
8915
8916 if (p2[1] != '\0')
8917 return 0;
8918
8919 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8920 if (!fn)
8921 return 0;
8922
8923 /* New argument list transforming strstr(s1, s2) to
8924 strchr(s1, s2[0]). */
8925 arglist = build_tree_list (NULL_TREE,
8926 build_int_cst (NULL_TREE, p2[0]));
8927 arglist = tree_cons (NULL_TREE, s1, arglist);
8928 return build_function_call_expr (fn, arglist);
8929 }
8930 }
8931
8932 /* Simplify a call to the strchr builtin.
8933
8934 Return 0 if no simplification was possible, otherwise return the
8935 simplified form of the call as a tree.
8936
8937 The simplified form may be a constant or other expression which
8938 computes the same value, but in a more efficient manner (including
8939 calls to other builtin functions).
8940
8941 The call may contain arguments which need to be evaluated, but
8942 which are not useful to determine the result of the call. In
8943 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8944 COMPOUND_EXPR will be an argument which must be evaluated.
8945 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8946 COMPOUND_EXPR in the chain will contain the tree for the simplified
8947 form of the builtin function call. */
8948
8949 static tree
8950 fold_builtin_strchr (tree arglist, tree type)
8951 {
8952 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8953 return 0;
8954 else
8955 {
8956 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8957 const char *p1;
8958
8959 if (TREE_CODE (s2) != INTEGER_CST)
8960 return 0;
8961
8962 p1 = c_getstr (s1);
8963 if (p1 != NULL)
8964 {
8965 char c;
8966 const char *r;
8967 tree tem;
8968
8969 if (target_char_cast (s2, &c))
8970 return 0;
8971
8972 r = strchr (p1, c);
8973
8974 if (r == NULL)
8975 return build_int_cst (TREE_TYPE (s1), 0);
8976
8977 /* Return an offset into the constant string argument. */
8978 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
8979 s1, build_int_cst (TREE_TYPE (s1), r - p1));
8980 return fold_convert (type, tem);
8981 }
8982 return 0;
8983 }
8984 }
8985
8986 /* Simplify a call to the strrchr builtin.
8987
8988 Return 0 if no simplification was possible, otherwise return the
8989 simplified form of the call as a tree.
8990
8991 The simplified form may be a constant or other expression which
8992 computes the same value, but in a more efficient manner (including
8993 calls to other builtin functions).
8994
8995 The call may contain arguments which need to be evaluated, but
8996 which are not useful to determine the result of the call. In
8997 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8998 COMPOUND_EXPR will be an argument which must be evaluated.
8999 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9000 COMPOUND_EXPR in the chain will contain the tree for the simplified
9001 form of the builtin function call. */
9002
9003 static tree
9004 fold_builtin_strrchr (tree arglist, tree type)
9005 {
9006 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9007 return 0;
9008 else
9009 {
9010 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9011 tree fn;
9012 const char *p1;
9013
9014 if (TREE_CODE (s2) != INTEGER_CST)
9015 return 0;
9016
9017 p1 = c_getstr (s1);
9018 if (p1 != NULL)
9019 {
9020 char c;
9021 const char *r;
9022 tree tem;
9023
9024 if (target_char_cast (s2, &c))
9025 return 0;
9026
9027 r = strrchr (p1, c);
9028
9029 if (r == NULL)
9030 return build_int_cst (TREE_TYPE (s1), 0);
9031
9032 /* Return an offset into the constant string argument. */
9033 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9034 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9035 return fold_convert (type, tem);
9036 }
9037
9038 if (! integer_zerop (s2))
9039 return 0;
9040
9041 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9042 if (!fn)
9043 return 0;
9044
9045 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9046 return build_function_call_expr (fn, arglist);
9047 }
9048 }
9049
9050 /* Simplify a call to the strpbrk builtin.
9051
9052 Return 0 if no simplification was possible, otherwise return the
9053 simplified form of the call as a tree.
9054
9055 The simplified form may be a constant or other expression which
9056 computes the same value, but in a more efficient manner (including
9057 calls to other builtin functions).
9058
9059 The call may contain arguments which need to be evaluated, but
9060 which are not useful to determine the result of the call. In
9061 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9062 COMPOUND_EXPR will be an argument which must be evaluated.
9063 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9064 COMPOUND_EXPR in the chain will contain the tree for the simplified
9065 form of the builtin function call. */
9066
9067 static tree
9068 fold_builtin_strpbrk (tree arglist, tree type)
9069 {
9070 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9071 return 0;
9072 else
9073 {
9074 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9075 tree fn;
9076 const char *p1, *p2;
9077
9078 p2 = c_getstr (s2);
9079 if (p2 == NULL)
9080 return 0;
9081
9082 p1 = c_getstr (s1);
9083 if (p1 != NULL)
9084 {
9085 const char *r = strpbrk (p1, p2);
9086 tree tem;
9087
9088 if (r == NULL)
9089 return build_int_cst (TREE_TYPE (s1), 0);
9090
9091 /* Return an offset into the constant string argument. */
9092 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9093 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9094 return fold_convert (type, tem);
9095 }
9096
9097 if (p2[0] == '\0')
9098 /* strpbrk(x, "") == NULL.
9099 Evaluate and ignore s1 in case it had side-effects. */
9100 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9101
9102 if (p2[1] != '\0')
9103 return 0; /* Really call strpbrk. */
9104
9105 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9106 if (!fn)
9107 return 0;
9108
9109 /* New argument list transforming strpbrk(s1, s2) to
9110 strchr(s1, s2[0]). */
9111 arglist = build_tree_list (NULL_TREE,
9112 build_int_cst (NULL_TREE, p2[0]));
9113 arglist = tree_cons (NULL_TREE, s1, arglist);
9114 return build_function_call_expr (fn, arglist);
9115 }
9116 }
9117
9118 /* Simplify a call to the strcat builtin.
9119
9120 Return 0 if no simplification was possible, otherwise return the
9121 simplified form of the call as a tree.
9122
9123 The simplified form may be a constant or other expression which
9124 computes the same value, but in a more efficient manner (including
9125 calls to other builtin functions).
9126
9127 The call may contain arguments which need to be evaluated, but
9128 which are not useful to determine the result of the call. In
9129 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9130 COMPOUND_EXPR will be an argument which must be evaluated.
9131 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9132 COMPOUND_EXPR in the chain will contain the tree for the simplified
9133 form of the builtin function call. */
9134
9135 static tree
9136 fold_builtin_strcat (tree arglist)
9137 {
9138 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9139 return 0;
9140 else
9141 {
9142 tree dst = TREE_VALUE (arglist),
9143 src = TREE_VALUE (TREE_CHAIN (arglist));
9144 const char *p = c_getstr (src);
9145
9146 /* If the string length is zero, return the dst parameter. */
9147 if (p && *p == '\0')
9148 return dst;
9149
9150 return 0;
9151 }
9152 }
9153
9154 /* Simplify a call to the strncat builtin.
9155
9156 Return 0 if no simplification was possible, otherwise return the
9157 simplified form of the call as a tree.
9158
9159 The simplified form may be a constant or other expression which
9160 computes the same value, but in a more efficient manner (including
9161 calls to other builtin functions).
9162
9163 The call may contain arguments which need to be evaluated, but
9164 which are not useful to determine the result of the call. In
9165 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9166 COMPOUND_EXPR will be an argument which must be evaluated.
9167 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9168 COMPOUND_EXPR in the chain will contain the tree for the simplified
9169 form of the builtin function call. */
9170
9171 static tree
9172 fold_builtin_strncat (tree arglist)
9173 {
9174 if (!validate_arglist (arglist,
9175 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9176 return 0;
9177 else
9178 {
9179 tree dst = TREE_VALUE (arglist);
9180 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9181 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9182 const char *p = c_getstr (src);
9183
9184 /* If the requested length is zero, or the src parameter string
9185 length is zero, return the dst parameter. */
9186 if (integer_zerop (len) || (p && *p == '\0'))
9187 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9188
9189 /* If the requested len is greater than or equal to the string
9190 length, call strcat. */
9191 if (TREE_CODE (len) == INTEGER_CST && p
9192 && compare_tree_int (len, strlen (p)) >= 0)
9193 {
9194 tree newarglist
9195 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9196 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9197
9198 /* If the replacement _DECL isn't initialized, don't do the
9199 transformation. */
9200 if (!fn)
9201 return 0;
9202
9203 return build_function_call_expr (fn, newarglist);
9204 }
9205 return 0;
9206 }
9207 }
9208
9209 /* Simplify a call to the strspn builtin.
9210
9211 Return 0 if no simplification was possible, otherwise return the
9212 simplified form of the call as a tree.
9213
9214 The simplified form may be a constant or other expression which
9215 computes the same value, but in a more efficient manner (including
9216 calls to other builtin functions).
9217
9218 The call may contain arguments which need to be evaluated, but
9219 which are not useful to determine the result of the call. In
9220 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9221 COMPOUND_EXPR will be an argument which must be evaluated.
9222 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9223 COMPOUND_EXPR in the chain will contain the tree for the simplified
9224 form of the builtin function call. */
9225
9226 static tree
9227 fold_builtin_strspn (tree arglist)
9228 {
9229 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9230 return 0;
9231 else
9232 {
9233 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9234 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9235
9236 /* If both arguments are constants, evaluate at compile-time. */
9237 if (p1 && p2)
9238 {
9239 const size_t r = strspn (p1, p2);
9240 return size_int (r);
9241 }
9242
9243 /* If either argument is "", return 0. */
9244 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9245 /* Evaluate and ignore both arguments in case either one has
9246 side-effects. */
9247 return omit_two_operands (integer_type_node, integer_zero_node,
9248 s1, s2);
9249 return 0;
9250 }
9251 }
9252
9253 /* Simplify a call to the strcspn builtin.
9254
9255 Return 0 if no simplification was possible, otherwise return the
9256 simplified form of the call as a tree.
9257
9258 The simplified form may be a constant or other expression which
9259 computes the same value, but in a more efficient manner (including
9260 calls to other builtin functions).
9261
9262 The call may contain arguments which need to be evaluated, but
9263 which are not useful to determine the result of the call. In
9264 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9265 COMPOUND_EXPR will be an argument which must be evaluated.
9266 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9267 COMPOUND_EXPR in the chain will contain the tree for the simplified
9268 form of the builtin function call. */
9269
9270 static tree
9271 fold_builtin_strcspn (tree arglist)
9272 {
9273 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9274 return 0;
9275 else
9276 {
9277 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9278 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9279
9280 /* If both arguments are constants, evaluate at compile-time. */
9281 if (p1 && p2)
9282 {
9283 const size_t r = strcspn (p1, p2);
9284 return size_int (r);
9285 }
9286
9287 /* If the first argument is "", return 0. */
9288 if (p1 && *p1 == '\0')
9289 {
9290 /* Evaluate and ignore argument s2 in case it has
9291 side-effects. */
9292 return omit_one_operand (integer_type_node,
9293 integer_zero_node, s2);
9294 }
9295
9296 /* If the second argument is "", return __builtin_strlen(s1). */
9297 if (p2 && *p2 == '\0')
9298 {
9299 tree newarglist = build_tree_list (NULL_TREE, s1),
9300 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9301
9302 /* If the replacement _DECL isn't initialized, don't do the
9303 transformation. */
9304 if (!fn)
9305 return 0;
9306
9307 return build_function_call_expr (fn, newarglist);
9308 }
9309 return 0;
9310 }
9311 }
9312
9313 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9314 by the builtin will be ignored. UNLOCKED is true is true if this
9315 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9316 the known length of the string. Return NULL_TREE if no simplification
9317 was possible. */
9318
9319 tree
9320 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9321 {
9322 tree fn;
9323 /* If we're using an unlocked function, assume the other unlocked
9324 functions exist explicitly. */
9325 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9326 : implicit_built_in_decls[BUILT_IN_FPUTC];
9327 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9328 : implicit_built_in_decls[BUILT_IN_FWRITE];
9329
9330 /* If the return value is used, or the replacement _DECL isn't
9331 initialized, don't do the transformation. */
9332 if (!ignore || !fn_fputc || !fn_fwrite)
9333 return 0;
9334
9335 /* Verify the arguments in the original call. */
9336 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9337 return 0;
9338
9339 if (! len)
9340 len = c_strlen (TREE_VALUE (arglist), 0);
9341
9342 /* Get the length of the string passed to fputs. If the length
9343 can't be determined, punt. */
9344 if (!len
9345 || TREE_CODE (len) != INTEGER_CST)
9346 return 0;
9347
9348 switch (compare_tree_int (len, 1))
9349 {
9350 case -1: /* length is 0, delete the call entirely . */
9351 return omit_one_operand (integer_type_node, integer_zero_node,
9352 TREE_VALUE (TREE_CHAIN (arglist)));
9353
9354 case 0: /* length is 1, call fputc. */
9355 {
9356 const char *p = c_getstr (TREE_VALUE (arglist));
9357
9358 if (p != NULL)
9359 {
9360 /* New argument list transforming fputs(string, stream) to
9361 fputc(string[0], stream). */
9362 arglist = build_tree_list (NULL_TREE,
9363 TREE_VALUE (TREE_CHAIN (arglist)));
9364 arglist = tree_cons (NULL_TREE,
9365 build_int_cst (NULL_TREE, p[0]),
9366 arglist);
9367 fn = fn_fputc;
9368 break;
9369 }
9370 }
9371 /* FALLTHROUGH */
9372 case 1: /* length is greater than 1, call fwrite. */
9373 {
9374 tree string_arg;
9375
9376 /* If optimizing for size keep fputs. */
9377 if (optimize_size)
9378 return 0;
9379 string_arg = TREE_VALUE (arglist);
9380 /* New argument list transforming fputs(string, stream) to
9381 fwrite(string, 1, len, stream). */
9382 arglist = build_tree_list (NULL_TREE,
9383 TREE_VALUE (TREE_CHAIN (arglist)));
9384 arglist = tree_cons (NULL_TREE, len, arglist);
9385 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9386 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9387 fn = fn_fwrite;
9388 break;
9389 }
9390 default:
9391 gcc_unreachable ();
9392 }
9393
9394 /* These optimizations are only performed when the result is ignored,
9395 hence there's no need to cast the result to integer_type_node. */
9396 return build_function_call_expr (fn, arglist);
9397 }
9398
9399 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9400 produced. False otherwise. This is done so that we don't output the error
9401 or warning twice or three times. */
9402 bool
9403 fold_builtin_next_arg (tree arglist)
9404 {
9405 tree fntype = TREE_TYPE (current_function_decl);
9406
9407 if (TYPE_ARG_TYPES (fntype) == 0
9408 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9409 == void_type_node))
9410 {
9411 error ("%<va_start%> used in function with fixed args");
9412 return true;
9413 }
9414 else if (!arglist)
9415 {
9416 /* Evidently an out of date version of <stdarg.h>; can't validate
9417 va_start's second argument, but can still work as intended. */
9418 warning (0, "%<__builtin_next_arg%> called without an argument");
9419 return true;
9420 }
9421 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9422 when we checked the arguments and if needed issued a warning. */
9423 else if (!TREE_CHAIN (arglist)
9424 || !integer_zerop (TREE_VALUE (arglist))
9425 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9426 || TREE_CHAIN (TREE_CHAIN (arglist)))
9427 {
9428 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9429 tree arg = TREE_VALUE (arglist);
9430
9431 if (TREE_CHAIN (arglist))
9432 {
9433 error ("%<va_start%> used with too many arguments");
9434 return true;
9435 }
9436
9437 /* Strip off all nops for the sake of the comparison. This
9438 is not quite the same as STRIP_NOPS. It does more.
9439 We must also strip off INDIRECT_EXPR for C++ reference
9440 parameters. */
9441 while (TREE_CODE (arg) == NOP_EXPR
9442 || TREE_CODE (arg) == CONVERT_EXPR
9443 || TREE_CODE (arg) == NON_LVALUE_EXPR
9444 || TREE_CODE (arg) == INDIRECT_REF)
9445 arg = TREE_OPERAND (arg, 0);
9446 if (arg != last_parm)
9447 {
9448 /* FIXME: Sometimes with the tree optimizers we can get the
9449 not the last argument even though the user used the last
9450 argument. We just warn and set the arg to be the last
9451 argument so that we will get wrong-code because of
9452 it. */
9453 warning (0, "second parameter of %<va_start%> not last named argument");
9454 }
9455 /* We want to verify the second parameter just once before the tree
9456 optimizers are run and then avoid keeping it in the tree,
9457 as otherwise we could warn even for correct code like:
9458 void foo (int i, ...)
9459 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9460 TREE_VALUE (arglist) = integer_zero_node;
9461 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9462 }
9463 return false;
9464 }
9465
9466
9467 /* Simplify a call to the sprintf builtin.
9468
9469 Return 0 if no simplification was possible, otherwise return the
9470 simplified form of the call as a tree. If IGNORED is true, it means that
9471 the caller does not use the returned value of the function. */
9472
9473 static tree
9474 fold_builtin_sprintf (tree arglist, int ignored)
9475 {
9476 tree call, retval, dest, fmt;
9477 const char *fmt_str = NULL;
9478
9479 /* Verify the required arguments in the original call. We deal with two
9480 types of sprintf() calls: 'sprintf (str, fmt)' and
9481 'sprintf (dest, "%s", orig)'. */
9482 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9483 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9484 VOID_TYPE))
9485 return NULL_TREE;
9486
9487 /* Get the destination string and the format specifier. */
9488 dest = TREE_VALUE (arglist);
9489 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9490
9491 /* Check whether the format is a literal string constant. */
9492 fmt_str = c_getstr (fmt);
9493 if (fmt_str == NULL)
9494 return NULL_TREE;
9495
9496 call = NULL_TREE;
9497 retval = NULL_TREE;
9498
9499 if (!init_target_chars())
9500 return 0;
9501
9502 /* If the format doesn't contain % args or %%, use strcpy. */
9503 if (strchr (fmt_str, target_percent) == NULL)
9504 {
9505 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9506
9507 if (!fn)
9508 return NULL_TREE;
9509
9510 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9511 'format' is known to contain no % formats. */
9512 arglist = build_tree_list (NULL_TREE, fmt);
9513 arglist = tree_cons (NULL_TREE, dest, arglist);
9514 call = build_function_call_expr (fn, arglist);
9515 if (!ignored)
9516 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9517 }
9518
9519 /* If the format is "%s", use strcpy if the result isn't used. */
9520 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9521 {
9522 tree fn, orig;
9523 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9524
9525 if (!fn)
9526 return NULL_TREE;
9527
9528 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9529 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9530 arglist = build_tree_list (NULL_TREE, orig);
9531 arglist = tree_cons (NULL_TREE, dest, arglist);
9532 if (!ignored)
9533 {
9534 retval = c_strlen (orig, 1);
9535 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9536 return NULL_TREE;
9537 }
9538 call = build_function_call_expr (fn, arglist);
9539 }
9540
9541 if (call && retval)
9542 {
9543 retval = convert
9544 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9545 retval);
9546 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9547 }
9548 else
9549 return call;
9550 }
9551
9552 /* Expand a call to __builtin_object_size. */
9553
9554 rtx
9555 expand_builtin_object_size (tree exp)
9556 {
9557 tree ost;
9558 int object_size_type;
9559 tree fndecl = get_callee_fndecl (exp);
9560 tree arglist = TREE_OPERAND (exp, 1);
9561 location_t locus = EXPR_LOCATION (exp);
9562
9563 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9564 {
9565 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9566 &locus, fndecl);
9567 expand_builtin_trap ();
9568 return const0_rtx;
9569 }
9570
9571 ost = TREE_VALUE (TREE_CHAIN (arglist));
9572 STRIP_NOPS (ost);
9573
9574 if (TREE_CODE (ost) != INTEGER_CST
9575 || tree_int_cst_sgn (ost) < 0
9576 || compare_tree_int (ost, 3) > 0)
9577 {
9578 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9579 &locus, fndecl);
9580 expand_builtin_trap ();
9581 return const0_rtx;
9582 }
9583
9584 object_size_type = tree_low_cst (ost, 0);
9585
9586 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9587 }
9588
9589 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9590 FCODE is the BUILT_IN_* to use.
9591 Return 0 if we failed; the caller should emit a normal call,
9592 otherwise try to get the result in TARGET, if convenient (and in
9593 mode MODE if that's convenient). */
9594
9595 static rtx
9596 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9597 enum built_in_function fcode)
9598 {
9599 tree arglist = TREE_OPERAND (exp, 1);
9600 tree dest, src, len, size;
9601
9602 if (!validate_arglist (arglist,
9603 POINTER_TYPE,
9604 fcode == BUILT_IN_MEMSET_CHK
9605 ? INTEGER_TYPE : POINTER_TYPE,
9606 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9607 return 0;
9608
9609 dest = TREE_VALUE (arglist);
9610 src = TREE_VALUE (TREE_CHAIN (arglist));
9611 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9612 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9613
9614 if (! host_integerp (size, 1))
9615 return 0;
9616
9617 if (host_integerp (len, 1) || integer_all_onesp (size))
9618 {
9619 tree fn;
9620
9621 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9622 {
9623 location_t locus = EXPR_LOCATION (exp);
9624 warning (0, "%Hcall to %D will always overflow destination buffer",
9625 &locus, get_callee_fndecl (exp));
9626 return 0;
9627 }
9628
9629 arglist = build_tree_list (NULL_TREE, len);
9630 arglist = tree_cons (NULL_TREE, src, arglist);
9631 arglist = tree_cons (NULL_TREE, dest, arglist);
9632
9633 fn = NULL_TREE;
9634 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9635 mem{cpy,pcpy,move,set} is available. */
9636 switch (fcode)
9637 {
9638 case BUILT_IN_MEMCPY_CHK:
9639 fn = built_in_decls[BUILT_IN_MEMCPY];
9640 break;
9641 case BUILT_IN_MEMPCPY_CHK:
9642 fn = built_in_decls[BUILT_IN_MEMPCPY];
9643 break;
9644 case BUILT_IN_MEMMOVE_CHK:
9645 fn = built_in_decls[BUILT_IN_MEMMOVE];
9646 break;
9647 case BUILT_IN_MEMSET_CHK:
9648 fn = built_in_decls[BUILT_IN_MEMSET];
9649 break;
9650 default:
9651 break;
9652 }
9653
9654 if (! fn)
9655 return 0;
9656
9657 fn = build_function_call_expr (fn, arglist);
9658 if (TREE_CODE (fn) == CALL_EXPR)
9659 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9660 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9661 }
9662 else if (fcode == BUILT_IN_MEMSET_CHK)
9663 return 0;
9664 else
9665 {
9666 unsigned int dest_align
9667 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9668
9669 /* If DEST is not a pointer type, call the normal function. */
9670 if (dest_align == 0)
9671 return 0;
9672
9673 /* If SRC and DEST are the same (and not volatile), do nothing. */
9674 if (operand_equal_p (src, dest, 0))
9675 {
9676 tree expr;
9677
9678 if (fcode != BUILT_IN_MEMPCPY_CHK)
9679 {
9680 /* Evaluate and ignore LEN in case it has side-effects. */
9681 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9682 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9683 }
9684
9685 len = fold_convert (TREE_TYPE (dest), len);
9686 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9687 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9688 }
9689
9690 /* __memmove_chk special case. */
9691 if (fcode == BUILT_IN_MEMMOVE_CHK)
9692 {
9693 unsigned int src_align
9694 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9695
9696 if (src_align == 0)
9697 return 0;
9698
9699 /* If src is categorized for a readonly section we can use
9700 normal __memcpy_chk. */
9701 if (readonly_data_expr (src))
9702 {
9703 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9704 if (!fn)
9705 return 0;
9706 fn = build_function_call_expr (fn, arglist);
9707 if (TREE_CODE (fn) == CALL_EXPR)
9708 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9709 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9710 }
9711 }
9712 return 0;
9713 }
9714 }
9715
9716 /* Emit warning if a buffer overflow is detected at compile time. */
9717
9718 static void
9719 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9720 {
9721 int arg_mask, is_strlen = 0;
9722 tree arglist = TREE_OPERAND (exp, 1), a;
9723 tree len, size;
9724 location_t locus;
9725
9726 switch (fcode)
9727 {
9728 case BUILT_IN_STRCPY_CHK:
9729 case BUILT_IN_STPCPY_CHK:
9730 /* For __strcat_chk the warning will be emitted only if overflowing
9731 by at least strlen (dest) + 1 bytes. */
9732 case BUILT_IN_STRCAT_CHK:
9733 arg_mask = 6;
9734 is_strlen = 1;
9735 break;
9736 case BUILT_IN_STRNCPY_CHK:
9737 arg_mask = 12;
9738 break;
9739 case BUILT_IN_SNPRINTF_CHK:
9740 case BUILT_IN_VSNPRINTF_CHK:
9741 arg_mask = 10;
9742 break;
9743 default:
9744 gcc_unreachable ();
9745 }
9746
9747 len = NULL_TREE;
9748 size = NULL_TREE;
9749 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9750 if (arg_mask & 1)
9751 {
9752 if (len)
9753 size = a;
9754 else
9755 len = a;
9756 }
9757
9758 if (!len || !size)
9759 return;
9760
9761 len = TREE_VALUE (len);
9762 size = TREE_VALUE (size);
9763
9764 if (! host_integerp (size, 1) || integer_all_onesp (size))
9765 return;
9766
9767 if (is_strlen)
9768 {
9769 len = c_strlen (len, 1);
9770 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9771 return;
9772 }
9773 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9774 return;
9775
9776 locus = EXPR_LOCATION (exp);
9777 warning (0, "%Hcall to %D will always overflow destination buffer",
9778 &locus, get_callee_fndecl (exp));
9779 }
9780
9781 /* Emit warning if a buffer overflow is detected at compile time
9782 in __sprintf_chk/__vsprintf_chk calls. */
9783
9784 static void
9785 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9786 {
9787 tree arglist = TREE_OPERAND (exp, 1);
9788 tree dest, size, len, fmt, flag;
9789 const char *fmt_str;
9790
9791 /* Verify the required arguments in the original call. */
9792 if (! arglist)
9793 return;
9794 dest = TREE_VALUE (arglist);
9795 arglist = TREE_CHAIN (arglist);
9796 if (! arglist)
9797 return;
9798 flag = TREE_VALUE (arglist);
9799 arglist = TREE_CHAIN (arglist);
9800 if (! arglist)
9801 return;
9802 size = TREE_VALUE (arglist);
9803 arglist = TREE_CHAIN (arglist);
9804 if (! arglist)
9805 return;
9806 fmt = TREE_VALUE (arglist);
9807 arglist = TREE_CHAIN (arglist);
9808
9809 if (! host_integerp (size, 1) || integer_all_onesp (size))
9810 return;
9811
9812 /* Check whether the format is a literal string constant. */
9813 fmt_str = c_getstr (fmt);
9814 if (fmt_str == NULL)
9815 return;
9816
9817 if (!init_target_chars())
9818 return;
9819
9820 /* If the format doesn't contain % args or %%, we know its size. */
9821 if (strchr (fmt_str, target_percent) == 0)
9822 len = build_int_cstu (size_type_node, strlen (fmt_str));
9823 /* If the format is "%s" and first ... argument is a string literal,
9824 we know it too. */
9825 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9826 {
9827 tree arg;
9828
9829 if (! arglist)
9830 return;
9831 arg = TREE_VALUE (arglist);
9832 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9833 return;
9834
9835 len = c_strlen (arg, 1);
9836 if (!len || ! host_integerp (len, 1))
9837 return;
9838 }
9839 else
9840 return;
9841
9842 if (! tree_int_cst_lt (len, size))
9843 {
9844 location_t locus = EXPR_LOCATION (exp);
9845 warning (0, "%Hcall to %D will always overflow destination buffer",
9846 &locus, get_callee_fndecl (exp));
9847 }
9848 }
9849
9850 /* Fold a call to __builtin_object_size, if possible. */
9851
9852 tree
9853 fold_builtin_object_size (tree arglist)
9854 {
9855 tree ptr, ost, ret = 0;
9856 int object_size_type;
9857
9858 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9859 return 0;
9860
9861 ptr = TREE_VALUE (arglist);
9862 ost = TREE_VALUE (TREE_CHAIN (arglist));
9863 STRIP_NOPS (ost);
9864
9865 if (TREE_CODE (ost) != INTEGER_CST
9866 || tree_int_cst_sgn (ost) < 0
9867 || compare_tree_int (ost, 3) > 0)
9868 return 0;
9869
9870 object_size_type = tree_low_cst (ost, 0);
9871
9872 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9873 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9874 and (size_t) 0 for types 2 and 3. */
9875 if (TREE_SIDE_EFFECTS (ptr))
9876 return fold_convert (size_type_node,
9877 object_size_type < 2
9878 ? integer_minus_one_node : integer_zero_node);
9879
9880 if (TREE_CODE (ptr) == ADDR_EXPR)
9881 ret = build_int_cstu (size_type_node,
9882 compute_builtin_object_size (ptr, object_size_type));
9883
9884 else if (TREE_CODE (ptr) == SSA_NAME)
9885 {
9886 unsigned HOST_WIDE_INT bytes;
9887
9888 /* If object size is not known yet, delay folding until
9889 later. Maybe subsequent passes will help determining
9890 it. */
9891 bytes = compute_builtin_object_size (ptr, object_size_type);
9892 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
9893 ? -1 : 0))
9894 ret = build_int_cstu (size_type_node, bytes);
9895 }
9896
9897 if (ret)
9898 {
9899 ret = force_fit_type (ret, -1, false, false);
9900 if (TREE_CONSTANT_OVERFLOW (ret))
9901 ret = 0;
9902 }
9903
9904 return ret;
9905 }
9906
9907 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9908 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
9909 code of the builtin. If MAXLEN is not NULL, it is maximum length
9910 passed as third argument. */
9911
9912 tree
9913 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
9914 enum built_in_function fcode)
9915 {
9916 tree dest, src, len, size, fn;
9917
9918 if (!validate_arglist (arglist,
9919 POINTER_TYPE,
9920 fcode == BUILT_IN_MEMSET_CHK
9921 ? INTEGER_TYPE : POINTER_TYPE,
9922 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9923 return 0;
9924
9925 dest = TREE_VALUE (arglist);
9926 /* Actually val for __memset_chk, but it doesn't matter. */
9927 src = TREE_VALUE (TREE_CHAIN (arglist));
9928 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9929 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9930
9931 /* If SRC and DEST are the same (and not volatile), return DEST
9932 (resp. DEST+LEN for __mempcpy_chk). */
9933 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
9934 {
9935 if (fcode != BUILT_IN_MEMPCPY_CHK)
9936 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
9937 else
9938 {
9939 tree temp = fold_convert (TREE_TYPE (dest), len);
9940 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
9941 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
9942 }
9943 }
9944
9945 if (! host_integerp (size, 1))
9946 return 0;
9947
9948 if (! integer_all_onesp (size))
9949 {
9950 if (! host_integerp (len, 1))
9951 {
9952 /* If LEN is not constant, try MAXLEN too.
9953 For MAXLEN only allow optimizing into non-_ocs function
9954 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
9955 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
9956 {
9957 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
9958 {
9959 /* (void) __mempcpy_chk () can be optimized into
9960 (void) __memcpy_chk (). */
9961 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9962 if (!fn)
9963 return 0;
9964
9965 return build_function_call_expr (fn, arglist);
9966 }
9967 return 0;
9968 }
9969 }
9970 else
9971 maxlen = len;
9972
9973 if (tree_int_cst_lt (size, maxlen))
9974 return 0;
9975 }
9976
9977 arglist = build_tree_list (NULL_TREE, len);
9978 arglist = tree_cons (NULL_TREE, src, arglist);
9979 arglist = tree_cons (NULL_TREE, dest, arglist);
9980
9981 fn = NULL_TREE;
9982 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9983 mem{cpy,pcpy,move,set} is available. */
9984 switch (fcode)
9985 {
9986 case BUILT_IN_MEMCPY_CHK:
9987 fn = built_in_decls[BUILT_IN_MEMCPY];
9988 break;
9989 case BUILT_IN_MEMPCPY_CHK:
9990 fn = built_in_decls[BUILT_IN_MEMPCPY];
9991 break;
9992 case BUILT_IN_MEMMOVE_CHK:
9993 fn = built_in_decls[BUILT_IN_MEMMOVE];
9994 break;
9995 case BUILT_IN_MEMSET_CHK:
9996 fn = built_in_decls[BUILT_IN_MEMSET];
9997 break;
9998 default:
9999 break;
10000 }
10001
10002 if (!fn)
10003 return 0;
10004
10005 return build_function_call_expr (fn, arglist);
10006 }
10007
10008 /* Fold a call to the __st[rp]cpy_chk builtin.
10009 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10010 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10011 strings passed as second argument. */
10012
10013 tree
10014 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10015 enum built_in_function fcode)
10016 {
10017 tree dest, src, size, len, fn;
10018
10019 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10020 VOID_TYPE))
10021 return 0;
10022
10023 dest = TREE_VALUE (arglist);
10024 src = TREE_VALUE (TREE_CHAIN (arglist));
10025 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10026
10027 /* If SRC and DEST are the same (and not volatile), return DEST. */
10028 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10029 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10030
10031 if (! host_integerp (size, 1))
10032 return 0;
10033
10034 if (! integer_all_onesp (size))
10035 {
10036 len = c_strlen (src, 1);
10037 if (! len || ! host_integerp (len, 1))
10038 {
10039 /* If LEN is not constant, try MAXLEN too.
10040 For MAXLEN only allow optimizing into non-_ocs function
10041 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10042 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10043 {
10044 if (fcode == BUILT_IN_STPCPY_CHK)
10045 {
10046 if (! ignore)
10047 return 0;
10048
10049 /* If return value of __stpcpy_chk is ignored,
10050 optimize into __strcpy_chk. */
10051 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10052 if (!fn)
10053 return 0;
10054
10055 return build_function_call_expr (fn, arglist);
10056 }
10057
10058 if (! len || TREE_SIDE_EFFECTS (len))
10059 return 0;
10060
10061 /* If c_strlen returned something, but not a constant,
10062 transform __strcpy_chk into __memcpy_chk. */
10063 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10064 if (!fn)
10065 return 0;
10066
10067 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10068 arglist = build_tree_list (NULL_TREE, size);
10069 arglist = tree_cons (NULL_TREE, len, arglist);
10070 arglist = tree_cons (NULL_TREE, src, arglist);
10071 arglist = tree_cons (NULL_TREE, dest, arglist);
10072 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10073 build_function_call_expr (fn, arglist));
10074 }
10075 }
10076 else
10077 maxlen = len;
10078
10079 if (! tree_int_cst_lt (maxlen, size))
10080 return 0;
10081 }
10082
10083 arglist = build_tree_list (NULL_TREE, src);
10084 arglist = tree_cons (NULL_TREE, dest, arglist);
10085
10086 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10087 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10088 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10089 if (!fn)
10090 return 0;
10091
10092 return build_function_call_expr (fn, arglist);
10093 }
10094
10095 /* Fold a call to the __strncpy_chk builtin.
10096 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10097
10098 tree
10099 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10100 {
10101 tree dest, src, size, len, fn;
10102
10103 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10104 INTEGER_TYPE, VOID_TYPE))
10105 return 0;
10106
10107 dest = TREE_VALUE (arglist);
10108 src = TREE_VALUE (TREE_CHAIN (arglist));
10109 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10110 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10111
10112 if (! host_integerp (size, 1))
10113 return 0;
10114
10115 if (! integer_all_onesp (size))
10116 {
10117 if (! host_integerp (len, 1))
10118 {
10119 /* If LEN is not constant, try MAXLEN too.
10120 For MAXLEN only allow optimizing into non-_ocs function
10121 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10122 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10123 return 0;
10124 }
10125 else
10126 maxlen = len;
10127
10128 if (tree_int_cst_lt (size, maxlen))
10129 return 0;
10130 }
10131
10132 arglist = build_tree_list (NULL_TREE, len);
10133 arglist = tree_cons (NULL_TREE, src, arglist);
10134 arglist = tree_cons (NULL_TREE, dest, arglist);
10135
10136 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10137 fn = built_in_decls[BUILT_IN_STRNCPY];
10138 if (!fn)
10139 return 0;
10140
10141 return build_function_call_expr (fn, arglist);
10142 }
10143
10144 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10145
10146 static tree
10147 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10148 {
10149 tree dest, src, size, fn;
10150 const char *p;
10151
10152 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10153 VOID_TYPE))
10154 return 0;
10155
10156 dest = TREE_VALUE (arglist);
10157 src = TREE_VALUE (TREE_CHAIN (arglist));
10158 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10159
10160 p = c_getstr (src);
10161 /* If the SRC parameter is "", return DEST. */
10162 if (p && *p == '\0')
10163 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10164
10165 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10166 return 0;
10167
10168 arglist = build_tree_list (NULL_TREE, src);
10169 arglist = tree_cons (NULL_TREE, dest, arglist);
10170
10171 /* If __builtin_strcat_chk is used, assume strcat is available. */
10172 fn = built_in_decls[BUILT_IN_STRCAT];
10173 if (!fn)
10174 return 0;
10175
10176 return build_function_call_expr (fn, arglist);
10177 }
10178
10179 /* Fold a call to the __strncat_chk builtin EXP. */
10180
10181 static tree
10182 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10183 {
10184 tree dest, src, size, len, fn;
10185 const char *p;
10186
10187 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10188 INTEGER_TYPE, VOID_TYPE))
10189 return 0;
10190
10191 dest = TREE_VALUE (arglist);
10192 src = TREE_VALUE (TREE_CHAIN (arglist));
10193 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10194 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10195
10196 p = c_getstr (src);
10197 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10198 if (p && *p == '\0')
10199 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10200 else if (integer_zerop (len))
10201 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10202
10203 if (! host_integerp (size, 1))
10204 return 0;
10205
10206 if (! integer_all_onesp (size))
10207 {
10208 tree src_len = c_strlen (src, 1);
10209 if (src_len
10210 && host_integerp (src_len, 1)
10211 && host_integerp (len, 1)
10212 && ! tree_int_cst_lt (len, src_len))
10213 {
10214 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10215 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10216 if (!fn)
10217 return 0;
10218
10219 arglist = build_tree_list (NULL_TREE, size);
10220 arglist = tree_cons (NULL_TREE, src, arglist);
10221 arglist = tree_cons (NULL_TREE, dest, arglist);
10222 return build_function_call_expr (fn, arglist);
10223 }
10224 return 0;
10225 }
10226
10227 arglist = build_tree_list (NULL_TREE, len);
10228 arglist = tree_cons (NULL_TREE, src, arglist);
10229 arglist = tree_cons (NULL_TREE, dest, arglist);
10230
10231 /* If __builtin_strncat_chk is used, assume strncat is available. */
10232 fn = built_in_decls[BUILT_IN_STRNCAT];
10233 if (!fn)
10234 return 0;
10235
10236 return build_function_call_expr (fn, arglist);
10237 }
10238
10239 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10240 a normal call should be emitted rather than expanding the function
10241 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10242
10243 static tree
10244 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10245 {
10246 tree dest, size, len, fn, fmt, flag;
10247 const char *fmt_str;
10248
10249 /* Verify the required arguments in the original call. */
10250 if (! arglist)
10251 return 0;
10252 dest = TREE_VALUE (arglist);
10253 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10254 return 0;
10255 arglist = TREE_CHAIN (arglist);
10256 if (! arglist)
10257 return 0;
10258 flag = TREE_VALUE (arglist);
10259 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10260 return 0;
10261 arglist = TREE_CHAIN (arglist);
10262 if (! arglist)
10263 return 0;
10264 size = TREE_VALUE (arglist);
10265 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10266 return 0;
10267 arglist = TREE_CHAIN (arglist);
10268 if (! arglist)
10269 return 0;
10270 fmt = TREE_VALUE (arglist);
10271 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10272 return 0;
10273 arglist = TREE_CHAIN (arglist);
10274
10275 if (! host_integerp (size, 1))
10276 return 0;
10277
10278 len = NULL_TREE;
10279
10280 if (!init_target_chars())
10281 return 0;
10282
10283 /* Check whether the format is a literal string constant. */
10284 fmt_str = c_getstr (fmt);
10285 if (fmt_str != NULL)
10286 {
10287 /* If the format doesn't contain % args or %%, we know the size. */
10288 if (strchr (fmt_str, target_percent) == 0)
10289 {
10290 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10291 len = build_int_cstu (size_type_node, strlen (fmt_str));
10292 }
10293 /* If the format is "%s" and first ... argument is a string literal,
10294 we know the size too. */
10295 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10296 {
10297 tree arg;
10298
10299 if (arglist && !TREE_CHAIN (arglist))
10300 {
10301 arg = TREE_VALUE (arglist);
10302 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10303 {
10304 len = c_strlen (arg, 1);
10305 if (! len || ! host_integerp (len, 1))
10306 len = NULL_TREE;
10307 }
10308 }
10309 }
10310 }
10311
10312 if (! integer_all_onesp (size))
10313 {
10314 if (! len || ! tree_int_cst_lt (len, size))
10315 return 0;
10316 }
10317
10318 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10319 or if format doesn't contain % chars or is "%s". */
10320 if (! integer_zerop (flag))
10321 {
10322 if (fmt_str == NULL)
10323 return 0;
10324 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10325 return 0;
10326 }
10327
10328 arglist = tree_cons (NULL_TREE, fmt, arglist);
10329 arglist = tree_cons (NULL_TREE, dest, arglist);
10330
10331 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10332 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10333 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10334 if (!fn)
10335 return 0;
10336
10337 return build_function_call_expr (fn, arglist);
10338 }
10339
10340 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10341 a normal call should be emitted rather than expanding the function
10342 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10343 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10344 passed as second argument. */
10345
10346 tree
10347 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10348 enum built_in_function fcode)
10349 {
10350 tree dest, size, len, fn, fmt, flag;
10351 const char *fmt_str;
10352
10353 /* Verify the required arguments in the original call. */
10354 if (! arglist)
10355 return 0;
10356 dest = TREE_VALUE (arglist);
10357 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10358 return 0;
10359 arglist = TREE_CHAIN (arglist);
10360 if (! arglist)
10361 return 0;
10362 len = TREE_VALUE (arglist);
10363 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10364 return 0;
10365 arglist = TREE_CHAIN (arglist);
10366 if (! arglist)
10367 return 0;
10368 flag = TREE_VALUE (arglist);
10369 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10370 return 0;
10371 arglist = TREE_CHAIN (arglist);
10372 if (! arglist)
10373 return 0;
10374 size = TREE_VALUE (arglist);
10375 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10376 return 0;
10377 arglist = TREE_CHAIN (arglist);
10378 if (! arglist)
10379 return 0;
10380 fmt = TREE_VALUE (arglist);
10381 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10382 return 0;
10383 arglist = TREE_CHAIN (arglist);
10384
10385 if (! host_integerp (size, 1))
10386 return 0;
10387
10388 if (! integer_all_onesp (size))
10389 {
10390 if (! host_integerp (len, 1))
10391 {
10392 /* If LEN is not constant, try MAXLEN too.
10393 For MAXLEN only allow optimizing into non-_ocs function
10394 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10395 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10396 return 0;
10397 }
10398 else
10399 maxlen = len;
10400
10401 if (tree_int_cst_lt (size, maxlen))
10402 return 0;
10403 }
10404
10405 if (!init_target_chars())
10406 return 0;
10407
10408 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10409 or if format doesn't contain % chars or is "%s". */
10410 if (! integer_zerop (flag))
10411 {
10412 fmt_str = c_getstr (fmt);
10413 if (fmt_str == NULL)
10414 return 0;
10415 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10416 return 0;
10417 }
10418
10419 arglist = tree_cons (NULL_TREE, fmt, arglist);
10420 arglist = tree_cons (NULL_TREE, len, arglist);
10421 arglist = tree_cons (NULL_TREE, dest, arglist);
10422
10423 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10424 available. */
10425 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10426 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10427 if (!fn)
10428 return 0;
10429
10430 return build_function_call_expr (fn, arglist);
10431 }
10432
10433 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10434
10435 Return 0 if no simplification was possible, otherwise return the
10436 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10437 code of the function to be simplified. */
10438
10439 static tree
10440 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10441 enum built_in_function fcode)
10442 {
10443 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10444 const char *fmt_str = NULL;
10445
10446 /* If the return value is used, don't do the transformation. */
10447 if (! ignore)
10448 return 0;
10449
10450 /* Verify the required arguments in the original call. */
10451 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10452 {
10453 tree flag;
10454
10455 if (! arglist)
10456 return 0;
10457 flag = TREE_VALUE (arglist);
10458 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10459 || TREE_SIDE_EFFECTS (flag))
10460 return 0;
10461 arglist = TREE_CHAIN (arglist);
10462 }
10463
10464 if (! arglist)
10465 return 0;
10466 fmt = TREE_VALUE (arglist);
10467 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10468 return 0;
10469 arglist = TREE_CHAIN (arglist);
10470
10471 /* Check whether the format is a literal string constant. */
10472 fmt_str = c_getstr (fmt);
10473 if (fmt_str == NULL)
10474 return NULL_TREE;
10475
10476 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10477 {
10478 /* If we're using an unlocked function, assume the other
10479 unlocked functions exist explicitly. */
10480 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10481 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10482 }
10483 else
10484 {
10485 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10486 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10487 }
10488
10489 if (!init_target_chars())
10490 return 0;
10491
10492 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10493 {
10494 const char *str;
10495
10496 if (strcmp (fmt_str, target_percent_s) == 0)
10497 {
10498 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10499 return 0;
10500
10501 if (! arglist
10502 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10503 || TREE_CHAIN (arglist))
10504 return 0;
10505
10506 str = c_getstr (TREE_VALUE (arglist));
10507 if (str == NULL)
10508 return 0;
10509 }
10510 else
10511 {
10512 /* The format specifier doesn't contain any '%' characters. */
10513 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10514 && arglist)
10515 return 0;
10516 str = fmt_str;
10517 }
10518
10519 /* If the string was "", printf does nothing. */
10520 if (str[0] == '\0')
10521 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10522
10523 /* If the string has length of 1, call putchar. */
10524 if (str[1] == '\0')
10525 {
10526 /* Given printf("c"), (where c is any one character,)
10527 convert "c"[0] to an int and pass that to the replacement
10528 function. */
10529 arg = build_int_cst (NULL_TREE, str[0]);
10530 arglist = build_tree_list (NULL_TREE, arg);
10531 fn = fn_putchar;
10532 }
10533 else
10534 {
10535 /* If the string was "string\n", call puts("string"). */
10536 size_t len = strlen (str);
10537 if ((unsigned char)str[len - 1] == target_newline)
10538 {
10539 /* Create a NUL-terminated string that's one char shorter
10540 than the original, stripping off the trailing '\n'. */
10541 char *newstr = alloca (len);
10542 memcpy (newstr, str, len - 1);
10543 newstr[len - 1] = 0;
10544
10545 arg = build_string_literal (len, newstr);
10546 arglist = build_tree_list (NULL_TREE, arg);
10547 fn = fn_puts;
10548 }
10549 else
10550 /* We'd like to arrange to call fputs(string,stdout) here,
10551 but we need stdout and don't have a way to get it yet. */
10552 return 0;
10553 }
10554 }
10555
10556 /* The other optimizations can be done only on the non-va_list variants. */
10557 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10558 return 0;
10559
10560 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10561 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10562 {
10563 if (! arglist
10564 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10565 || TREE_CHAIN (arglist))
10566 return 0;
10567 fn = fn_puts;
10568 }
10569
10570 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10571 else if (strcmp (fmt_str, target_percent_c) == 0)
10572 {
10573 if (! arglist
10574 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10575 || TREE_CHAIN (arglist))
10576 return 0;
10577 fn = fn_putchar;
10578 }
10579
10580 if (!fn)
10581 return 0;
10582
10583 call = build_function_call_expr (fn, arglist);
10584 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10585 }
10586
10587 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10588
10589 Return 0 if no simplification was possible, otherwise return the
10590 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10591 code of the function to be simplified. */
10592
10593 static tree
10594 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10595 enum built_in_function fcode)
10596 {
10597 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10598 const char *fmt_str = NULL;
10599
10600 /* If the return value is used, don't do the transformation. */
10601 if (! ignore)
10602 return 0;
10603
10604 /* Verify the required arguments in the original call. */
10605 if (! arglist)
10606 return 0;
10607 fp = TREE_VALUE (arglist);
10608 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10609 return 0;
10610 arglist = TREE_CHAIN (arglist);
10611
10612 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10613 {
10614 tree flag;
10615
10616 if (! arglist)
10617 return 0;
10618 flag = TREE_VALUE (arglist);
10619 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10620 || TREE_SIDE_EFFECTS (flag))
10621 return 0;
10622 arglist = TREE_CHAIN (arglist);
10623 }
10624
10625 if (! arglist)
10626 return 0;
10627 fmt = TREE_VALUE (arglist);
10628 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10629 return 0;
10630 arglist = TREE_CHAIN (arglist);
10631
10632 /* Check whether the format is a literal string constant. */
10633 fmt_str = c_getstr (fmt);
10634 if (fmt_str == NULL)
10635 return NULL_TREE;
10636
10637 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10638 {
10639 /* If we're using an unlocked function, assume the other
10640 unlocked functions exist explicitly. */
10641 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10642 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10643 }
10644 else
10645 {
10646 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10647 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10648 }
10649
10650 if (!init_target_chars())
10651 return 0;
10652
10653 /* If the format doesn't contain % args or %%, use strcpy. */
10654 if (strchr (fmt_str, target_percent) == NULL)
10655 {
10656 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10657 && arglist)
10658 return 0;
10659
10660 /* If the format specifier was "", fprintf does nothing. */
10661 if (fmt_str[0] == '\0')
10662 {
10663 /* If FP has side-effects, just wait until gimplification is
10664 done. */
10665 if (TREE_SIDE_EFFECTS (fp))
10666 return 0;
10667
10668 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10669 }
10670
10671 /* When "string" doesn't contain %, replace all cases of
10672 fprintf (fp, string) with fputs (string, fp). The fputs
10673 builtin will take care of special cases like length == 1. */
10674 arglist = build_tree_list (NULL_TREE, fp);
10675 arglist = tree_cons (NULL_TREE, fmt, arglist);
10676 fn = fn_fputs;
10677 }
10678
10679 /* The other optimizations can be done only on the non-va_list variants. */
10680 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10681 return 0;
10682
10683 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10684 else if (strcmp (fmt_str, target_percent_s) == 0)
10685 {
10686 if (! arglist
10687 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10688 || TREE_CHAIN (arglist))
10689 return 0;
10690 arg = TREE_VALUE (arglist);
10691 arglist = build_tree_list (NULL_TREE, fp);
10692 arglist = tree_cons (NULL_TREE, arg, arglist);
10693 fn = fn_fputs;
10694 }
10695
10696 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10697 else if (strcmp (fmt_str, target_percent_c) == 0)
10698 {
10699 if (! arglist
10700 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10701 || TREE_CHAIN (arglist))
10702 return 0;
10703 arg = TREE_VALUE (arglist);
10704 arglist = build_tree_list (NULL_TREE, fp);
10705 arglist = tree_cons (NULL_TREE, arg, arglist);
10706 fn = fn_fputc;
10707 }
10708
10709 if (!fn)
10710 return 0;
10711
10712 call = build_function_call_expr (fn, arglist);
10713 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10714 }
10715
10716 /* Initialize format string characters in the target charset. */
10717
10718 static bool
10719 init_target_chars (void)
10720 {
10721 static bool init;
10722 if (!init)
10723 {
10724 target_newline = lang_hooks.to_target_charset ('\n');
10725 target_percent = lang_hooks.to_target_charset ('%');
10726 target_c = lang_hooks.to_target_charset ('c');
10727 target_s = lang_hooks.to_target_charset ('s');
10728 if (target_newline == 0 || target_percent == 0 || target_c == 0
10729 || target_s == 0)
10730 return false;
10731
10732 target_percent_c[0] = target_percent;
10733 target_percent_c[1] = target_c;
10734 target_percent_c[2] = '\0';
10735
10736 target_percent_s[0] = target_percent;
10737 target_percent_s[1] = target_s;
10738 target_percent_s[2] = '\0';
10739
10740 target_percent_s_newline[0] = target_percent;
10741 target_percent_s_newline[1] = target_s;
10742 target_percent_s_newline[2] = target_newline;
10743 target_percent_s_newline[3] = '\0';
10744
10745 init = true;
10746 }
10747 return true;
10748 }