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