2003-10-31 Andreas Jaeger <aj@suse.de>,
[official-gcc.git] / gcc / builtins.c
blob23b0acfb801ea6ecf18247216c7ab4cc8dae5d32
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GCC.
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.
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.
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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
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 "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
51 /* Register mappings for target machines without register windows. */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
54 #endif
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
57 #endif
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
61 #endif
63 /* Define the names of the builtin function types and codes. */
64 const char *const built_in_class_names[4]
65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
68 const char *const built_in_names[(int) END_BUILTINS] =
70 #include "builtins.def"
72 #undef DEF_BUILTIN
74 /* Setup an array of _DECL trees, make sure each element is
75 initialized to NULL_TREE. */
76 tree built_in_decls[(int) END_BUILTINS];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78 It may be NULL_TREE when this is invalid (for instance runtime is not
79 required to implement the function call in all cases. */
80 tree implicit_built_in_decls[(int) END_BUILTINS];
82 static int get_pointer_alignment (tree, unsigned int);
83 static tree c_strlen (tree, int);
84 static const char *c_getstr (tree);
85 static rtx c_readstr (const char *, enum machine_mode);
86 static int target_char_cast (tree, char *);
87 static rtx get_memory_rtx (tree);
88 static tree build_string_literal (int, const char *);
89 static int apply_args_size (void);
90 static int apply_result_size (void);
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector (int, rtx);
93 #endif
94 static rtx expand_builtin_setjmp (tree, rtx);
95 static void expand_builtin_prefetch (tree);
96 static rtx expand_builtin_apply_args (void);
97 static rtx expand_builtin_apply_args_1 (void);
98 static rtx expand_builtin_apply (rtx, rtx, rtx);
99 static void expand_builtin_return (rtx);
100 static enum type_class type_to_class (tree);
101 static rtx expand_builtin_classify_type (tree);
102 static void expand_errno_check (tree, rtx);
103 static rtx expand_builtin_mathfn (tree, rtx, rtx);
104 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
105 static rtx expand_builtin_constant_p (tree, enum machine_mode);
106 static rtx expand_builtin_args_info (tree);
107 static rtx expand_builtin_next_arg (tree);
108 static rtx expand_builtin_va_start (tree);
109 static rtx expand_builtin_va_end (tree);
110 static rtx expand_builtin_va_copy (tree);
111 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
114 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
115 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
120 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
121 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_bcopy (tree);
123 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
125 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
126 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
127 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
128 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
129 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_bzero (tree);
131 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
132 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
133 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
134 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
135 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
136 static rtx expand_builtin_alloca (tree, rtx);
137 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
138 static rtx expand_builtin_frame_address (tree, tree);
139 static rtx expand_builtin_fputs (tree, rtx, bool);
140 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
141 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
142 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
143 static tree stabilize_va_list (tree, int);
144 static rtx expand_builtin_expect (tree, rtx);
145 static tree fold_builtin_constant_p (tree);
146 static tree fold_builtin_classify_type (tree);
147 static tree fold_builtin_inf (tree, int);
148 static tree fold_builtin_nan (tree, tree, int);
149 static int validate_arglist (tree, ...);
150 static bool integer_valued_real_p (tree);
151 static tree fold_trunc_transparent_mathfn (tree);
152 static bool readonly_data_expr (tree);
153 static rtx expand_builtin_fabs (tree, rtx, rtx);
154 static rtx expand_builtin_cabs (tree, rtx);
155 static tree fold_builtin_cabs (tree, tree, tree);
156 static tree fold_builtin_trunc (tree);
157 static tree fold_builtin_floor (tree);
158 static tree fold_builtin_ceil (tree);
159 static tree fold_builtin_bitop (tree);
160 static tree fold_builtin_memcpy (tree);
161 static tree fold_builtin_mempcpy (tree);
162 static tree fold_builtin_memmove (tree);
163 static tree fold_builtin_strcpy (tree);
164 static tree fold_builtin_strncpy (tree);
165 static tree fold_builtin_memcmp (tree);
166 static tree fold_builtin_strcmp (tree);
167 static tree fold_builtin_strncmp (tree);
169 /* Return the alignment in bits of EXP, a pointer valued expression.
170 But don't return more than MAX_ALIGN no matter what.
171 The alignment returned is, by default, the alignment of the thing that
172 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
174 Otherwise, look at the expression to see if we can do better, i.e., if the
175 expression is actually pointing at an object whose alignment is tighter. */
177 static int
178 get_pointer_alignment (tree exp, unsigned int max_align)
180 unsigned int align, inner;
182 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
183 return 0;
185 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
186 align = MIN (align, max_align);
188 while (1)
190 switch (TREE_CODE (exp))
192 case NOP_EXPR:
193 case CONVERT_EXPR:
194 case NON_LVALUE_EXPR:
195 exp = TREE_OPERAND (exp, 0);
196 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
197 return align;
199 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
200 align = MIN (inner, max_align);
201 break;
203 case PLUS_EXPR:
204 /* If sum of pointer + int, restrict our maximum alignment to that
205 imposed by the integer. If not, we can't do any better than
206 ALIGN. */
207 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
208 return align;
210 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
211 & (max_align / BITS_PER_UNIT - 1))
212 != 0)
213 max_align >>= 1;
215 exp = TREE_OPERAND (exp, 0);
216 break;
218 case ADDR_EXPR:
219 /* See what we are pointing at and look at its alignment. */
220 exp = TREE_OPERAND (exp, 0);
221 if (TREE_CODE (exp) == FUNCTION_DECL)
222 align = FUNCTION_BOUNDARY;
223 else if (DECL_P (exp))
224 align = DECL_ALIGN (exp);
225 #ifdef CONSTANT_ALIGNMENT
226 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
227 align = CONSTANT_ALIGNMENT (exp, align);
228 #endif
229 return MIN (align, max_align);
231 default:
232 return align;
237 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
238 way, because it could contain a zero byte in the middle.
239 TREE_STRING_LENGTH is the size of the character array, not the string.
241 ONLY_VALUE should be nonzero if the result is not going to be emitted
242 into the instruction stream and zero if it is going to be expanded.
243 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
244 is returned, otherwise NULL, since
245 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
246 evaluate the side-effects.
248 The value returned is of type `ssizetype'.
250 Unfortunately, string_constant can't access the values of const char
251 arrays with initializers, so neither can we do so here. */
253 static tree
254 c_strlen (tree src, int only_value)
256 tree offset_node;
257 HOST_WIDE_INT offset;
258 int max;
259 const char *ptr;
261 STRIP_NOPS (src);
262 if (TREE_CODE (src) == COND_EXPR
263 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
265 tree len1, len2;
267 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
268 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
269 if (tree_int_cst_equal (len1, len2))
270 return len1;
273 if (TREE_CODE (src) == COMPOUND_EXPR
274 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
275 return c_strlen (TREE_OPERAND (src, 1), only_value);
277 src = string_constant (src, &offset_node);
278 if (src == 0)
279 return 0;
281 max = TREE_STRING_LENGTH (src) - 1;
282 ptr = TREE_STRING_POINTER (src);
284 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
286 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
287 compute the offset to the following null if we don't know where to
288 start searching for it. */
289 int i;
291 for (i = 0; i < max; i++)
292 if (ptr[i] == 0)
293 return 0;
295 /* We don't know the starting offset, but we do know that the string
296 has no internal zero bytes. We can assume that the offset falls
297 within the bounds of the string; otherwise, the programmer deserves
298 what he gets. Subtract the offset from the length of the string,
299 and return that. This would perhaps not be valid if we were dealing
300 with named arrays in addition to literal string constants. */
302 return size_diffop (size_int (max), offset_node);
305 /* We have a known offset into the string. Start searching there for
306 a null character if we can represent it as a single HOST_WIDE_INT. */
307 if (offset_node == 0)
308 offset = 0;
309 else if (! host_integerp (offset_node, 0))
310 offset = -1;
311 else
312 offset = tree_low_cst (offset_node, 0);
314 /* If the offset is known to be out of bounds, warn, and call strlen at
315 runtime. */
316 if (offset < 0 || offset > max)
318 warning ("offset outside bounds of constant string");
319 return 0;
322 /* Use strlen to search for the first zero byte. Since any strings
323 constructed with build_string will have nulls appended, we win even
324 if we get handed something like (char[4])"abcd".
326 Since OFFSET is our starting index into the string, no further
327 calculation is needed. */
328 return ssize_int (strlen (ptr + offset));
331 /* Return a char pointer for a C string if it is a string constant
332 or sum of string constant and integer constant. */
334 static const char *
335 c_getstr (tree src)
337 tree offset_node;
339 src = string_constant (src, &offset_node);
340 if (src == 0)
341 return 0;
343 if (offset_node == 0)
344 return TREE_STRING_POINTER (src);
345 else if (!host_integerp (offset_node, 1)
346 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
347 return 0;
349 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
352 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
353 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
355 static rtx
356 c_readstr (const char *str, enum machine_mode mode)
358 HOST_WIDE_INT c[2];
359 HOST_WIDE_INT ch;
360 unsigned int i, j;
362 if (GET_MODE_CLASS (mode) != MODE_INT)
363 abort ();
364 c[0] = 0;
365 c[1] = 0;
366 ch = 1;
367 for (i = 0; i < GET_MODE_SIZE (mode); i++)
369 j = i;
370 if (WORDS_BIG_ENDIAN)
371 j = GET_MODE_SIZE (mode) - i - 1;
372 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
373 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
374 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
375 j *= BITS_PER_UNIT;
376 if (j > 2 * HOST_BITS_PER_WIDE_INT)
377 abort ();
378 if (ch)
379 ch = (unsigned char) str[i];
380 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
382 return immed_double_const (c[0], c[1], mode);
385 /* Cast a target constant CST to target CHAR and if that value fits into
386 host char type, return zero and put that value into variable pointed by
387 P. */
389 static int
390 target_char_cast (tree cst, char *p)
392 unsigned HOST_WIDE_INT val, hostval;
394 if (!host_integerp (cst, 1)
395 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
396 return 1;
398 val = tree_low_cst (cst, 1);
399 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
400 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
402 hostval = val;
403 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
404 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
406 if (val != hostval)
407 return 1;
409 *p = hostval;
410 return 0;
413 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
414 times to get the address of either a higher stack frame, or a return
415 address located within it (depending on FNDECL_CODE). */
418 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
419 rtx tem)
421 int i;
423 /* Some machines need special handling before we can access
424 arbitrary frames. For example, on the sparc, we must first flush
425 all register windows to the stack. */
426 #ifdef SETUP_FRAME_ADDRESSES
427 if (count > 0)
428 SETUP_FRAME_ADDRESSES ();
429 #endif
431 /* On the sparc, the return address is not in the frame, it is in a
432 register. There is no way to access it off of the current frame
433 pointer, but it can be accessed off the previous frame pointer by
434 reading the value from the register window save area. */
435 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
436 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
437 count--;
438 #endif
440 /* Scan back COUNT frames to the specified frame. */
441 for (i = 0; i < count; i++)
443 /* Assume the dynamic chain pointer is in the word that the
444 frame address points to, unless otherwise specified. */
445 #ifdef DYNAMIC_CHAIN_ADDRESS
446 tem = DYNAMIC_CHAIN_ADDRESS (tem);
447 #endif
448 tem = memory_address (Pmode, tem);
449 tem = gen_rtx_MEM (Pmode, tem);
450 set_mem_alias_set (tem, get_frame_alias_set ());
451 tem = copy_to_reg (tem);
454 /* For __builtin_frame_address, return what we've got. */
455 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
456 return tem;
458 /* For __builtin_return_address, Get the return address from that
459 frame. */
460 #ifdef RETURN_ADDR_RTX
461 tem = RETURN_ADDR_RTX (count, tem);
462 #else
463 tem = memory_address (Pmode,
464 plus_constant (tem, GET_MODE_SIZE (Pmode)));
465 tem = gen_rtx_MEM (Pmode, tem);
466 set_mem_alias_set (tem, get_frame_alias_set ());
467 #endif
468 return tem;
471 /* Alias set used for setjmp buffer. */
472 static HOST_WIDE_INT setjmp_alias_set = -1;
474 /* Construct the leading half of a __builtin_setjmp call. Control will
475 return to RECEIVER_LABEL. This is used directly by sjlj exception
476 handling code. */
478 void
479 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
481 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
482 rtx stack_save;
483 rtx mem;
485 if (setjmp_alias_set == -1)
486 setjmp_alias_set = new_alias_set ();
488 buf_addr = convert_memory_address (Pmode, buf_addr);
490 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
492 emit_queue ();
494 /* We store the frame pointer and the address of receiver_label in
495 the buffer and use the rest of it for the stack save area, which
496 is machine-dependent. */
498 #ifndef BUILTIN_SETJMP_FRAME_VALUE
499 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
500 #endif
502 mem = gen_rtx_MEM (Pmode, buf_addr);
503 set_mem_alias_set (mem, setjmp_alias_set);
504 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
506 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
507 set_mem_alias_set (mem, setjmp_alias_set);
509 emit_move_insn (validize_mem (mem),
510 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
512 stack_save = gen_rtx_MEM (sa_mode,
513 plus_constant (buf_addr,
514 2 * GET_MODE_SIZE (Pmode)));
515 set_mem_alias_set (stack_save, setjmp_alias_set);
516 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
518 /* If there is further processing to do, do it. */
519 #ifdef HAVE_builtin_setjmp_setup
520 if (HAVE_builtin_setjmp_setup)
521 emit_insn (gen_builtin_setjmp_setup (buf_addr));
522 #endif
524 /* Tell optimize_save_area_alloca that extra work is going to
525 need to go on during alloca. */
526 current_function_calls_setjmp = 1;
528 /* Set this so all the registers get saved in our frame; we need to be
529 able to copy the saved values for any registers from frames we unwind. */
530 current_function_has_nonlocal_label = 1;
533 /* Construct the trailing part of a __builtin_setjmp call.
534 This is used directly by sjlj exception handling code. */
536 void
537 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
539 /* Clobber the FP when we get here, so we have to make sure it's
540 marked as used by this function. */
541 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
543 /* Mark the static chain as clobbered here so life information
544 doesn't get messed up for it. */
545 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
547 /* Now put in the code to restore the frame pointer, and argument
548 pointer, if needed. The code below is from expand_end_bindings
549 in stmt.c; see detailed documentation there. */
550 #ifdef HAVE_nonlocal_goto
551 if (! HAVE_nonlocal_goto)
552 #endif
553 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
555 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
556 if (fixed_regs[ARG_POINTER_REGNUM])
558 #ifdef ELIMINABLE_REGS
559 size_t i;
560 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
562 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
563 if (elim_regs[i].from == ARG_POINTER_REGNUM
564 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
565 break;
567 if (i == ARRAY_SIZE (elim_regs))
568 #endif
570 /* Now restore our arg pointer from the address at which it
571 was saved in our stack frame. */
572 emit_move_insn (virtual_incoming_args_rtx,
573 copy_to_reg (get_arg_pointer_save_area (cfun)));
576 #endif
578 #ifdef HAVE_builtin_setjmp_receiver
579 if (HAVE_builtin_setjmp_receiver)
580 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
581 else
582 #endif
583 #ifdef HAVE_nonlocal_goto_receiver
584 if (HAVE_nonlocal_goto_receiver)
585 emit_insn (gen_nonlocal_goto_receiver ());
586 else
587 #endif
588 { /* Nothing */ }
590 /* @@@ This is a kludge. Not all machine descriptions define a blockage
591 insn, but we must not allow the code we just generated to be reordered
592 by scheduling. Specifically, the update of the frame pointer must
593 happen immediately, not later. So emit an ASM_INPUT to act as blockage
594 insn. */
595 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
598 /* __builtin_setjmp is passed a pointer to an array of five words (not
599 all will be used on all machines). It operates similarly to the C
600 library function of the same name, but is more efficient. Much of
601 the code below (and for longjmp) is copied from the handling of
602 non-local gotos.
604 NOTE: This is intended for use by GNAT and the exception handling
605 scheme in the compiler and will only work in the method used by
606 them. */
608 static rtx
609 expand_builtin_setjmp (tree arglist, rtx target)
611 rtx buf_addr, next_lab, cont_lab;
613 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
614 return NULL_RTX;
616 if (target == 0 || GET_CODE (target) != REG
617 || REGNO (target) < FIRST_PSEUDO_REGISTER)
618 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
620 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
622 next_lab = gen_label_rtx ();
623 cont_lab = gen_label_rtx ();
625 expand_builtin_setjmp_setup (buf_addr, next_lab);
627 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
628 ensure that pending stack adjustments are flushed. */
629 emit_move_insn (target, const0_rtx);
630 emit_jump (cont_lab);
632 emit_label (next_lab);
634 expand_builtin_setjmp_receiver (next_lab);
636 /* Set TARGET to one. */
637 emit_move_insn (target, const1_rtx);
638 emit_label (cont_lab);
640 /* Tell flow about the strange goings on. Putting `next_lab' on
641 `nonlocal_goto_handler_labels' to indicates that function
642 calls may traverse the arc back to this label. */
644 current_function_has_nonlocal_label = 1;
645 nonlocal_goto_handler_labels
646 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
648 return target;
651 /* __builtin_longjmp is passed a pointer to an array of five words (not
652 all will be used on all machines). It operates similarly to the C
653 library function of the same name, but is more efficient. Much of
654 the code below is copied from the handling of non-local gotos.
656 NOTE: This is intended for use by GNAT and the exception handling
657 scheme in the compiler and will only work in the method used by
658 them. */
660 void
661 expand_builtin_longjmp (rtx buf_addr, rtx value)
663 rtx fp, lab, stack, insn, last;
664 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
666 if (setjmp_alias_set == -1)
667 setjmp_alias_set = new_alias_set ();
669 buf_addr = convert_memory_address (Pmode, buf_addr);
671 buf_addr = force_reg (Pmode, buf_addr);
673 /* We used to store value in static_chain_rtx, but that fails if pointers
674 are smaller than integers. We instead require that the user must pass
675 a second argument of 1, because that is what builtin_setjmp will
676 return. This also makes EH slightly more efficient, since we are no
677 longer copying around a value that we don't care about. */
678 if (value != const1_rtx)
679 abort ();
681 current_function_calls_longjmp = 1;
683 last = get_last_insn ();
684 #ifdef HAVE_builtin_longjmp
685 if (HAVE_builtin_longjmp)
686 emit_insn (gen_builtin_longjmp (buf_addr));
687 else
688 #endif
690 fp = gen_rtx_MEM (Pmode, buf_addr);
691 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
692 GET_MODE_SIZE (Pmode)));
694 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
695 2 * GET_MODE_SIZE (Pmode)));
696 set_mem_alias_set (fp, setjmp_alias_set);
697 set_mem_alias_set (lab, setjmp_alias_set);
698 set_mem_alias_set (stack, setjmp_alias_set);
700 /* Pick up FP, label, and SP from the block and jump. This code is
701 from expand_goto in stmt.c; see there for detailed comments. */
702 #if HAVE_nonlocal_goto
703 if (HAVE_nonlocal_goto)
704 /* We have to pass a value to the nonlocal_goto pattern that will
705 get copied into the static_chain pointer, but it does not matter
706 what that value is, because builtin_setjmp does not use it. */
707 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
708 else
709 #endif
711 lab = copy_to_reg (lab);
713 emit_move_insn (hard_frame_pointer_rtx, fp);
714 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
716 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
717 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
718 emit_indirect_jump (lab);
722 /* Search backwards and mark the jump insn as a non-local goto.
723 Note that this precludes the use of __builtin_longjmp to a
724 __builtin_setjmp target in the same function. However, we've
725 already cautioned the user that these functions are for
726 internal exception handling use only. */
727 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
729 if (insn == last)
730 abort ();
731 if (GET_CODE (insn) == JUMP_INSN)
733 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
734 REG_NOTES (insn));
735 break;
737 else if (GET_CODE (insn) == CALL_INSN)
738 break;
742 /* Expand a call to __builtin_prefetch. For a target that does not support
743 data prefetch, evaluate the memory address argument in case it has side
744 effects. */
746 static void
747 expand_builtin_prefetch (tree arglist)
749 tree arg0, arg1, arg2;
750 rtx op0, op1, op2;
752 if (!validate_arglist (arglist, POINTER_TYPE, 0))
753 return;
755 arg0 = TREE_VALUE (arglist);
756 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
757 zero (read) and argument 2 (locality) defaults to 3 (high degree of
758 locality). */
759 if (TREE_CHAIN (arglist))
761 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
762 if (TREE_CHAIN (TREE_CHAIN (arglist)))
763 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
764 else
765 arg2 = build_int_2 (3, 0);
767 else
769 arg1 = integer_zero_node;
770 arg2 = build_int_2 (3, 0);
773 /* Argument 0 is an address. */
774 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
776 /* Argument 1 (read/write flag) must be a compile-time constant int. */
777 if (TREE_CODE (arg1) != INTEGER_CST)
779 error ("second arg to `__builtin_prefetch' must be a constant");
780 arg1 = integer_zero_node;
782 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
783 /* Argument 1 must be either zero or one. */
784 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
786 warning ("invalid second arg to __builtin_prefetch; using zero");
787 op1 = const0_rtx;
790 /* Argument 2 (locality) must be a compile-time constant int. */
791 if (TREE_CODE (arg2) != INTEGER_CST)
793 error ("third arg to `__builtin_prefetch' must be a constant");
794 arg2 = integer_zero_node;
796 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
797 /* Argument 2 must be 0, 1, 2, or 3. */
798 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
800 warning ("invalid third arg to __builtin_prefetch; using zero");
801 op2 = const0_rtx;
804 #ifdef HAVE_prefetch
805 if (HAVE_prefetch)
807 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
808 (op0,
809 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
810 || (GET_MODE (op0) != Pmode))
812 op0 = convert_memory_address (Pmode, op0);
813 op0 = force_reg (Pmode, op0);
815 emit_insn (gen_prefetch (op0, op1, op2));
817 else
818 #endif
819 op0 = protect_from_queue (op0, 0);
820 /* Don't do anything with direct references to volatile memory, but
821 generate code to handle other side effects. */
822 if (GET_CODE (op0) != MEM && side_effects_p (op0))
823 emit_insn (op0);
826 /* Get a MEM rtx for expression EXP which is the address of an operand
827 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
829 static rtx
830 get_memory_rtx (tree exp)
832 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
833 rtx mem;
835 addr = convert_memory_address (Pmode, addr);
837 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
839 /* Get an expression we can use to find the attributes to assign to MEM.
840 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
841 we can. First remove any nops. */
842 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
843 || TREE_CODE (exp) == NON_LVALUE_EXPR)
844 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
845 exp = TREE_OPERAND (exp, 0);
847 if (TREE_CODE (exp) == ADDR_EXPR)
849 exp = TREE_OPERAND (exp, 0);
850 set_mem_attributes (mem, exp, 0);
852 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
854 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
855 /* memcpy, memset and other builtin stringops can alias with anything. */
856 set_mem_alias_set (mem, 0);
859 return mem;
862 /* Built-in functions to perform an untyped call and return. */
864 /* For each register that may be used for calling a function, this
865 gives a mode used to copy the register's value. VOIDmode indicates
866 the register is not used for calling a function. If the machine
867 has register windows, this gives only the outbound registers.
868 INCOMING_REGNO gives the corresponding inbound register. */
869 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
871 /* For each register that may be used for returning values, this gives
872 a mode used to copy the register's value. VOIDmode indicates the
873 register is not used for returning values. If the machine has
874 register windows, this gives only the outbound registers.
875 INCOMING_REGNO gives the corresponding inbound register. */
876 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
878 /* For each register that may be used for calling a function, this
879 gives the offset of that register into the block returned by
880 __builtin_apply_args. 0 indicates that the register is not
881 used for calling a function. */
882 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
884 /* Return the offset of register REGNO into the block returned by
885 __builtin_apply_args. This is not declared static, since it is
886 needed in objc-act.c. */
889 apply_args_register_offset (int regno)
891 apply_args_size ();
893 /* Arguments are always put in outgoing registers (in the argument
894 block) if such make sense. */
895 #ifdef OUTGOING_REGNO
896 regno = OUTGOING_REGNO (regno);
897 #endif
898 return apply_args_reg_offset[regno];
901 /* Return the size required for the block returned by __builtin_apply_args,
902 and initialize apply_args_mode. */
904 static int
905 apply_args_size (void)
907 static int size = -1;
908 int align;
909 unsigned int regno;
910 enum machine_mode mode;
912 /* The values computed by this function never change. */
913 if (size < 0)
915 /* The first value is the incoming arg-pointer. */
916 size = GET_MODE_SIZE (Pmode);
918 /* The second value is the structure value address unless this is
919 passed as an "invisible" first argument. */
920 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
921 size += GET_MODE_SIZE (Pmode);
923 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
924 if (FUNCTION_ARG_REGNO_P (regno))
926 /* Search for the proper mode for copying this register's
927 value. I'm not sure this is right, but it works so far. */
928 enum machine_mode best_mode = VOIDmode;
930 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
931 mode != VOIDmode;
932 mode = GET_MODE_WIDER_MODE (mode))
933 if (HARD_REGNO_MODE_OK (regno, mode)
934 && HARD_REGNO_NREGS (regno, mode) == 1)
935 best_mode = mode;
937 if (best_mode == VOIDmode)
938 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
939 mode != VOIDmode;
940 mode = GET_MODE_WIDER_MODE (mode))
941 if (HARD_REGNO_MODE_OK (regno, mode)
942 && have_insn_for (SET, mode))
943 best_mode = mode;
945 if (best_mode == VOIDmode)
946 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
947 mode != VOIDmode;
948 mode = GET_MODE_WIDER_MODE (mode))
949 if (HARD_REGNO_MODE_OK (regno, mode)
950 && have_insn_for (SET, mode))
951 best_mode = mode;
953 if (best_mode == VOIDmode)
954 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
955 mode != VOIDmode;
956 mode = GET_MODE_WIDER_MODE (mode))
957 if (HARD_REGNO_MODE_OK (regno, mode)
958 && have_insn_for (SET, mode))
959 best_mode = mode;
961 mode = best_mode;
962 if (mode == VOIDmode)
963 abort ();
965 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
966 if (size % align != 0)
967 size = CEIL (size, align) * align;
968 apply_args_reg_offset[regno] = size;
969 size += GET_MODE_SIZE (mode);
970 apply_args_mode[regno] = mode;
972 else
974 apply_args_mode[regno] = VOIDmode;
975 apply_args_reg_offset[regno] = 0;
978 return size;
981 /* Return the size required for the block returned by __builtin_apply,
982 and initialize apply_result_mode. */
984 static int
985 apply_result_size (void)
987 static int size = -1;
988 int align, regno;
989 enum machine_mode mode;
991 /* The values computed by this function never change. */
992 if (size < 0)
994 size = 0;
996 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
997 if (FUNCTION_VALUE_REGNO_P (regno))
999 /* Search for the proper mode for copying this register's
1000 value. I'm not sure this is right, but it works so far. */
1001 enum machine_mode best_mode = VOIDmode;
1003 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1004 mode != TImode;
1005 mode = GET_MODE_WIDER_MODE (mode))
1006 if (HARD_REGNO_MODE_OK (regno, mode))
1007 best_mode = mode;
1009 if (best_mode == VOIDmode)
1010 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1011 mode != VOIDmode;
1012 mode = GET_MODE_WIDER_MODE (mode))
1013 if (HARD_REGNO_MODE_OK (regno, mode)
1014 && have_insn_for (SET, mode))
1015 best_mode = mode;
1017 if (best_mode == VOIDmode)
1018 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1019 mode != VOIDmode;
1020 mode = GET_MODE_WIDER_MODE (mode))
1021 if (HARD_REGNO_MODE_OK (regno, mode)
1022 && have_insn_for (SET, mode))
1023 best_mode = mode;
1025 if (best_mode == VOIDmode)
1026 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1027 mode != VOIDmode;
1028 mode = GET_MODE_WIDER_MODE (mode))
1029 if (HARD_REGNO_MODE_OK (regno, mode)
1030 && have_insn_for (SET, mode))
1031 best_mode = mode;
1033 mode = best_mode;
1034 if (mode == VOIDmode)
1035 abort ();
1037 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1038 if (size % align != 0)
1039 size = CEIL (size, align) * align;
1040 size += GET_MODE_SIZE (mode);
1041 apply_result_mode[regno] = mode;
1043 else
1044 apply_result_mode[regno] = VOIDmode;
1046 /* Allow targets that use untyped_call and untyped_return to override
1047 the size so that machine-specific information can be stored here. */
1048 #ifdef APPLY_RESULT_SIZE
1049 size = APPLY_RESULT_SIZE;
1050 #endif
1052 return size;
1055 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1056 /* Create a vector describing the result block RESULT. If SAVEP is true,
1057 the result block is used to save the values; otherwise it is used to
1058 restore the values. */
1060 static rtx
1061 result_vector (int savep, rtx result)
1063 int regno, size, align, nelts;
1064 enum machine_mode mode;
1065 rtx reg, mem;
1066 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1068 size = nelts = 0;
1069 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1070 if ((mode = apply_result_mode[regno]) != VOIDmode)
1072 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1073 if (size % align != 0)
1074 size = CEIL (size, align) * align;
1075 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1076 mem = adjust_address (result, mode, size);
1077 savevec[nelts++] = (savep
1078 ? gen_rtx_SET (VOIDmode, mem, reg)
1079 : gen_rtx_SET (VOIDmode, reg, mem));
1080 size += GET_MODE_SIZE (mode);
1082 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1084 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1086 /* Save the state required to perform an untyped call with the same
1087 arguments as were passed to the current function. */
1089 static rtx
1090 expand_builtin_apply_args_1 (void)
1092 rtx registers;
1093 int size, align, regno;
1094 enum machine_mode mode;
1095 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1097 /* Create a block where the arg-pointer, structure value address,
1098 and argument registers can be saved. */
1099 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1101 /* Walk past the arg-pointer and structure value address. */
1102 size = GET_MODE_SIZE (Pmode);
1103 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1104 size += GET_MODE_SIZE (Pmode);
1106 /* Save each register used in calling a function to the block. */
1107 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1108 if ((mode = apply_args_mode[regno]) != VOIDmode)
1110 rtx tem;
1112 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1113 if (size % align != 0)
1114 size = CEIL (size, align) * align;
1116 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1118 emit_move_insn (adjust_address (registers, mode, size), tem);
1119 size += GET_MODE_SIZE (mode);
1122 /* Save the arg pointer to the block. */
1123 emit_move_insn (adjust_address (registers, Pmode, 0),
1124 copy_to_reg (virtual_incoming_args_rtx));
1125 size = GET_MODE_SIZE (Pmode);
1127 /* Save the structure value address unless this is passed as an
1128 "invisible" first argument. */
1129 if (struct_incoming_value)
1131 emit_move_insn (adjust_address (registers, Pmode, size),
1132 copy_to_reg (struct_incoming_value));
1133 size += GET_MODE_SIZE (Pmode);
1136 /* Return the address of the block. */
1137 return copy_addr_to_reg (XEXP (registers, 0));
1140 /* __builtin_apply_args returns block of memory allocated on
1141 the stack into which is stored the arg pointer, structure
1142 value address, static chain, and all the registers that might
1143 possibly be used in performing a function call. The code is
1144 moved to the start of the function so the incoming values are
1145 saved. */
1147 static rtx
1148 expand_builtin_apply_args (void)
1150 /* Don't do __builtin_apply_args more than once in a function.
1151 Save the result of the first call and reuse it. */
1152 if (apply_args_value != 0)
1153 return apply_args_value;
1155 /* When this function is called, it means that registers must be
1156 saved on entry to this function. So we migrate the
1157 call to the first insn of this function. */
1158 rtx temp;
1159 rtx seq;
1161 start_sequence ();
1162 temp = expand_builtin_apply_args_1 ();
1163 seq = get_insns ();
1164 end_sequence ();
1166 apply_args_value = temp;
1168 /* Put the insns after the NOTE that starts the function.
1169 If this is inside a start_sequence, make the outer-level insn
1170 chain current, so the code is placed at the start of the
1171 function. */
1172 push_topmost_sequence ();
1173 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1174 pop_topmost_sequence ();
1175 return temp;
1179 /* Perform an untyped call and save the state required to perform an
1180 untyped return of whatever value was returned by the given function. */
1182 static rtx
1183 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1185 int size, align, regno;
1186 enum machine_mode mode;
1187 rtx incoming_args, result, reg, dest, src, call_insn;
1188 rtx old_stack_level = 0;
1189 rtx call_fusage = 0;
1190 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1192 arguments = convert_memory_address (Pmode, arguments);
1194 /* Create a block where the return registers can be saved. */
1195 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1197 /* Fetch the arg pointer from the ARGUMENTS block. */
1198 incoming_args = gen_reg_rtx (Pmode);
1199 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1200 #ifndef STACK_GROWS_DOWNWARD
1201 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1202 incoming_args, 0, OPTAB_LIB_WIDEN);
1203 #endif
1205 /* Perform postincrements before actually calling the function. */
1206 emit_queue ();
1208 /* Push a new argument block and copy the arguments. Do not allow
1209 the (potential) memcpy call below to interfere with our stack
1210 manipulations. */
1211 do_pending_stack_adjust ();
1212 NO_DEFER_POP;
1214 /* Save the stack with nonlocal if available. */
1215 #ifdef HAVE_save_stack_nonlocal
1216 if (HAVE_save_stack_nonlocal)
1217 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1218 else
1219 #endif
1220 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1222 /* Push a block of memory onto the stack to store the memory arguments.
1223 Save the address in a register, and copy the memory arguments. ??? I
1224 haven't figured out how the calling convention macros effect this,
1225 but it's likely that the source and/or destination addresses in
1226 the block copy will need updating in machine specific ways. */
1227 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1228 dest = gen_rtx_MEM (BLKmode, dest);
1229 set_mem_align (dest, PARM_BOUNDARY);
1230 src = gen_rtx_MEM (BLKmode, incoming_args);
1231 set_mem_align (src, PARM_BOUNDARY);
1232 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1234 /* Refer to the argument block. */
1235 apply_args_size ();
1236 arguments = gen_rtx_MEM (BLKmode, arguments);
1237 set_mem_align (arguments, PARM_BOUNDARY);
1239 /* Walk past the arg-pointer and structure value address. */
1240 size = GET_MODE_SIZE (Pmode);
1241 if (struct_value)
1242 size += GET_MODE_SIZE (Pmode);
1244 /* Restore each of the registers previously saved. Make USE insns
1245 for each of these registers for use in making the call. */
1246 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1247 if ((mode = apply_args_mode[regno]) != VOIDmode)
1249 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1250 if (size % align != 0)
1251 size = CEIL (size, align) * align;
1252 reg = gen_rtx_REG (mode, regno);
1253 emit_move_insn (reg, adjust_address (arguments, mode, size));
1254 use_reg (&call_fusage, reg);
1255 size += GET_MODE_SIZE (mode);
1258 /* Restore the structure value address unless this is passed as an
1259 "invisible" first argument. */
1260 size = GET_MODE_SIZE (Pmode);
1261 if (struct_value)
1263 rtx value = gen_reg_rtx (Pmode);
1264 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1265 emit_move_insn (struct_value, value);
1266 if (GET_CODE (struct_value) == REG)
1267 use_reg (&call_fusage, struct_value);
1268 size += GET_MODE_SIZE (Pmode);
1271 /* All arguments and registers used for the call are set up by now! */
1272 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1274 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1275 and we don't want to load it into a register as an optimization,
1276 because prepare_call_address already did it if it should be done. */
1277 if (GET_CODE (function) != SYMBOL_REF)
1278 function = memory_address (FUNCTION_MODE, function);
1280 /* Generate the actual call instruction and save the return value. */
1281 #ifdef HAVE_untyped_call
1282 if (HAVE_untyped_call)
1283 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1284 result, result_vector (1, result)));
1285 else
1286 #endif
1287 #ifdef HAVE_call_value
1288 if (HAVE_call_value)
1290 rtx valreg = 0;
1292 /* Locate the unique return register. It is not possible to
1293 express a call that sets more than one return register using
1294 call_value; use untyped_call for that. In fact, untyped_call
1295 only needs to save the return registers in the given block. */
1296 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1297 if ((mode = apply_result_mode[regno]) != VOIDmode)
1299 if (valreg)
1300 abort (); /* HAVE_untyped_call required. */
1301 valreg = gen_rtx_REG (mode, regno);
1304 emit_call_insn (GEN_CALL_VALUE (valreg,
1305 gen_rtx_MEM (FUNCTION_MODE, function),
1306 const0_rtx, NULL_RTX, const0_rtx));
1308 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1310 else
1311 #endif
1312 abort ();
1314 /* Find the CALL insn we just emitted, and attach the register usage
1315 information. */
1316 call_insn = last_call_insn ();
1317 add_function_usage_to (call_insn, call_fusage);
1319 /* Restore the stack. */
1320 #ifdef HAVE_save_stack_nonlocal
1321 if (HAVE_save_stack_nonlocal)
1322 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1323 else
1324 #endif
1325 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1327 OK_DEFER_POP;
1329 /* Return the address of the result block. */
1330 result = copy_addr_to_reg (XEXP (result, 0));
1331 return convert_memory_address (ptr_mode, result);
1334 /* Perform an untyped return. */
1336 static void
1337 expand_builtin_return (rtx result)
1339 int size, align, regno;
1340 enum machine_mode mode;
1341 rtx reg;
1342 rtx call_fusage = 0;
1344 result = convert_memory_address (Pmode, result);
1346 apply_result_size ();
1347 result = gen_rtx_MEM (BLKmode, result);
1349 #ifdef HAVE_untyped_return
1350 if (HAVE_untyped_return)
1352 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1353 emit_barrier ();
1354 return;
1356 #endif
1358 /* Restore the return value and note that each value is used. */
1359 size = 0;
1360 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1361 if ((mode = apply_result_mode[regno]) != VOIDmode)
1363 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1364 if (size % align != 0)
1365 size = CEIL (size, align) * align;
1366 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1367 emit_move_insn (reg, adjust_address (result, mode, size));
1369 push_to_sequence (call_fusage);
1370 emit_insn (gen_rtx_USE (VOIDmode, reg));
1371 call_fusage = get_insns ();
1372 end_sequence ();
1373 size += GET_MODE_SIZE (mode);
1376 /* Put the USE insns before the return. */
1377 emit_insn (call_fusage);
1379 /* Return whatever values was restored by jumping directly to the end
1380 of the function. */
1381 expand_null_return ();
1384 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1386 static enum type_class
1387 type_to_class (tree type)
1389 switch (TREE_CODE (type))
1391 case VOID_TYPE: return void_type_class;
1392 case INTEGER_TYPE: return integer_type_class;
1393 case CHAR_TYPE: return char_type_class;
1394 case ENUMERAL_TYPE: return enumeral_type_class;
1395 case BOOLEAN_TYPE: return boolean_type_class;
1396 case POINTER_TYPE: return pointer_type_class;
1397 case REFERENCE_TYPE: return reference_type_class;
1398 case OFFSET_TYPE: return offset_type_class;
1399 case REAL_TYPE: return real_type_class;
1400 case COMPLEX_TYPE: return complex_type_class;
1401 case FUNCTION_TYPE: return function_type_class;
1402 case METHOD_TYPE: return method_type_class;
1403 case RECORD_TYPE: return record_type_class;
1404 case UNION_TYPE:
1405 case QUAL_UNION_TYPE: return union_type_class;
1406 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1407 ? string_type_class : array_type_class);
1408 case SET_TYPE: return set_type_class;
1409 case FILE_TYPE: return file_type_class;
1410 case LANG_TYPE: return lang_type_class;
1411 default: return no_type_class;
1415 /* Expand a call to __builtin_classify_type with arguments found in
1416 ARGLIST. */
1418 static rtx
1419 expand_builtin_classify_type (tree arglist)
1421 if (arglist != 0)
1422 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1423 return GEN_INT (no_type_class);
1426 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1428 static rtx
1429 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1431 rtx tmp;
1433 if (arglist == 0)
1434 return const0_rtx;
1435 arglist = TREE_VALUE (arglist);
1437 /* We have taken care of the easy cases during constant folding. This
1438 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1439 get a chance to see if it can deduce whether ARGLIST is constant.
1440 If CSE isn't going to run, of course, don't bother waiting. */
1442 if (cse_not_expected)
1443 return const0_rtx;
1445 current_function_calls_constant_p = 1;
1447 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1448 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1449 return tmp;
1452 /* This helper macro, meant to be used in mathfn_built_in below,
1453 determines which among a set of three builtin math functions is
1454 appropriate for a given type mode. The `F' and `L' cases are
1455 automatically generated from the `double' case. */
1456 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1457 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1458 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1459 fcodel = BUILT_IN_MATHFN##L ; break;
1461 /* Return mathematic function equivalent to FN but operating directly
1462 on TYPE, if available. If we can't do the conversion, return zero. */
1463 tree
1464 mathfn_built_in (tree type, enum built_in_function fn)
1466 const enum machine_mode type_mode = TYPE_MODE (type);
1467 enum built_in_function fcode, fcodef, fcodel;
1469 switch (fn)
1471 CASE_MATHFN (BUILT_IN_ACOS)
1472 CASE_MATHFN (BUILT_IN_ACOSH)
1473 CASE_MATHFN (BUILT_IN_ASIN)
1474 CASE_MATHFN (BUILT_IN_ASINH)
1475 CASE_MATHFN (BUILT_IN_ATAN)
1476 CASE_MATHFN (BUILT_IN_ATAN2)
1477 CASE_MATHFN (BUILT_IN_ATANH)
1478 CASE_MATHFN (BUILT_IN_CBRT)
1479 CASE_MATHFN (BUILT_IN_CEIL)
1480 CASE_MATHFN (BUILT_IN_COPYSIGN)
1481 CASE_MATHFN (BUILT_IN_COS)
1482 CASE_MATHFN (BUILT_IN_COSH)
1483 CASE_MATHFN (BUILT_IN_DREM)
1484 CASE_MATHFN (BUILT_IN_ERF)
1485 CASE_MATHFN (BUILT_IN_ERFC)
1486 CASE_MATHFN (BUILT_IN_EXP)
1487 CASE_MATHFN (BUILT_IN_EXP10)
1488 CASE_MATHFN (BUILT_IN_EXP2)
1489 CASE_MATHFN (BUILT_IN_EXPM1)
1490 CASE_MATHFN (BUILT_IN_FABS)
1491 CASE_MATHFN (BUILT_IN_FDIM)
1492 CASE_MATHFN (BUILT_IN_FLOOR)
1493 CASE_MATHFN (BUILT_IN_FMA)
1494 CASE_MATHFN (BUILT_IN_FMAX)
1495 CASE_MATHFN (BUILT_IN_FMIN)
1496 CASE_MATHFN (BUILT_IN_FMOD)
1497 CASE_MATHFN (BUILT_IN_FREXP)
1498 CASE_MATHFN (BUILT_IN_GAMMA)
1499 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1500 CASE_MATHFN (BUILT_IN_HYPOT)
1501 CASE_MATHFN (BUILT_IN_ILOGB)
1502 CASE_MATHFN (BUILT_IN_INF)
1503 CASE_MATHFN (BUILT_IN_J0)
1504 CASE_MATHFN (BUILT_IN_J1)
1505 CASE_MATHFN (BUILT_IN_JN)
1506 CASE_MATHFN (BUILT_IN_LDEXP)
1507 CASE_MATHFN (BUILT_IN_LGAMMA)
1508 CASE_MATHFN (BUILT_IN_LLRINT)
1509 CASE_MATHFN (BUILT_IN_LLROUND)
1510 CASE_MATHFN (BUILT_IN_LOG)
1511 CASE_MATHFN (BUILT_IN_LOG10)
1512 CASE_MATHFN (BUILT_IN_LOG1P)
1513 CASE_MATHFN (BUILT_IN_LOG2)
1514 CASE_MATHFN (BUILT_IN_LOGB)
1515 CASE_MATHFN (BUILT_IN_LRINT)
1516 CASE_MATHFN (BUILT_IN_LROUND)
1517 CASE_MATHFN (BUILT_IN_MODF)
1518 CASE_MATHFN (BUILT_IN_NAN)
1519 CASE_MATHFN (BUILT_IN_NANS)
1520 CASE_MATHFN (BUILT_IN_NEARBYINT)
1521 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1522 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1523 CASE_MATHFN (BUILT_IN_POW)
1524 CASE_MATHFN (BUILT_IN_POW10)
1525 CASE_MATHFN (BUILT_IN_REMAINDER)
1526 CASE_MATHFN (BUILT_IN_REMQUO)
1527 CASE_MATHFN (BUILT_IN_RINT)
1528 CASE_MATHFN (BUILT_IN_ROUND)
1529 CASE_MATHFN (BUILT_IN_SCALB)
1530 CASE_MATHFN (BUILT_IN_SCALBLN)
1531 CASE_MATHFN (BUILT_IN_SCALBN)
1532 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1533 CASE_MATHFN (BUILT_IN_SIN)
1534 CASE_MATHFN (BUILT_IN_SINCOS)
1535 CASE_MATHFN (BUILT_IN_SINH)
1536 CASE_MATHFN (BUILT_IN_SQRT)
1537 CASE_MATHFN (BUILT_IN_TAN)
1538 CASE_MATHFN (BUILT_IN_TANH)
1539 CASE_MATHFN (BUILT_IN_TGAMMA)
1540 CASE_MATHFN (BUILT_IN_TRUNC)
1541 CASE_MATHFN (BUILT_IN_Y0)
1542 CASE_MATHFN (BUILT_IN_Y1)
1543 CASE_MATHFN (BUILT_IN_YN)
1545 default:
1546 return 0;
1549 if (type_mode == TYPE_MODE (double_type_node))
1550 return implicit_built_in_decls[fcode];
1551 else if (type_mode == TYPE_MODE (float_type_node))
1552 return implicit_built_in_decls[fcodef];
1553 else if (type_mode == TYPE_MODE (long_double_type_node))
1554 return implicit_built_in_decls[fcodel];
1555 else
1556 return 0;
1559 /* If errno must be maintained, expand the RTL to check if the result,
1560 TARGET, of a built-in function call, EXP, is NaN, and if so set
1561 errno to EDOM. */
1563 static void
1564 expand_errno_check (tree exp, rtx target)
1566 rtx lab = gen_label_rtx ();
1568 /* Test the result; if it is NaN, set errno=EDOM because
1569 the argument was not in the domain. */
1570 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1571 0, lab);
1573 #ifdef TARGET_EDOM
1574 /* If this built-in doesn't throw an exception, set errno directly. */
1575 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1577 #ifdef GEN_ERRNO_RTX
1578 rtx errno_rtx = GEN_ERRNO_RTX;
1579 #else
1580 rtx errno_rtx
1581 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1582 #endif
1583 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1584 emit_label (lab);
1585 return;
1587 #endif
1589 /* We can't set errno=EDOM directly; let the library call do it.
1590 Pop the arguments right away in case the call gets deleted. */
1591 NO_DEFER_POP;
1592 expand_call (exp, target, 0);
1593 OK_DEFER_POP;
1594 emit_label (lab);
1598 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1599 Return 0 if a normal call should be emitted rather than expanding the
1600 function in-line. EXP is the expression that is a call to the builtin
1601 function; if convenient, the result should be placed in TARGET.
1602 SUBTARGET may be used as the target for computing one of EXP's operands. */
1604 static rtx
1605 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1607 optab builtin_optab;
1608 rtx op0, insns, before_call;
1609 tree fndecl = get_callee_fndecl (exp);
1610 tree arglist = TREE_OPERAND (exp, 1);
1611 enum machine_mode mode;
1612 bool errno_set = false;
1613 tree arg, narg;
1615 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1616 return 0;
1618 arg = TREE_VALUE (arglist);
1620 switch (DECL_FUNCTION_CODE (fndecl))
1622 case BUILT_IN_SIN:
1623 case BUILT_IN_SINF:
1624 case BUILT_IN_SINL:
1625 builtin_optab = sin_optab; break;
1626 case BUILT_IN_COS:
1627 case BUILT_IN_COSF:
1628 case BUILT_IN_COSL:
1629 builtin_optab = cos_optab; break;
1630 case BUILT_IN_SQRT:
1631 case BUILT_IN_SQRTF:
1632 case BUILT_IN_SQRTL:
1633 errno_set = ! tree_expr_nonnegative_p (arg);
1634 builtin_optab = sqrt_optab;
1635 break;
1636 case BUILT_IN_EXP:
1637 case BUILT_IN_EXPF:
1638 case BUILT_IN_EXPL:
1639 errno_set = true; builtin_optab = exp_optab; break;
1640 case BUILT_IN_LOG:
1641 case BUILT_IN_LOGF:
1642 case BUILT_IN_LOGL:
1643 errno_set = true; builtin_optab = log_optab; break;
1644 case BUILT_IN_TAN:
1645 case BUILT_IN_TANF:
1646 case BUILT_IN_TANL:
1647 builtin_optab = tan_optab; break;
1648 case BUILT_IN_ATAN:
1649 case BUILT_IN_ATANF:
1650 case BUILT_IN_ATANL:
1651 builtin_optab = atan_optab; break;
1652 case BUILT_IN_FLOOR:
1653 case BUILT_IN_FLOORF:
1654 case BUILT_IN_FLOORL:
1655 builtin_optab = floor_optab; break;
1656 case BUILT_IN_CEIL:
1657 case BUILT_IN_CEILF:
1658 case BUILT_IN_CEILL:
1659 builtin_optab = ceil_optab; break;
1660 case BUILT_IN_TRUNC:
1661 case BUILT_IN_TRUNCF:
1662 case BUILT_IN_TRUNCL:
1663 builtin_optab = btrunc_optab; break;
1664 case BUILT_IN_ROUND:
1665 case BUILT_IN_ROUNDF:
1666 case BUILT_IN_ROUNDL:
1667 builtin_optab = round_optab; break;
1668 case BUILT_IN_NEARBYINT:
1669 case BUILT_IN_NEARBYINTF:
1670 case BUILT_IN_NEARBYINTL:
1671 builtin_optab = nearbyint_optab; break;
1672 default:
1673 abort ();
1676 /* Make a suitable register to place result in. */
1677 mode = TYPE_MODE (TREE_TYPE (exp));
1679 if (! flag_errno_math || ! HONOR_NANS (mode))
1680 errno_set = false;
1682 /* Before working hard, check whether the instruction is available. */
1683 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1685 target = gen_reg_rtx (mode);
1687 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1688 need to expand the argument again. This way, we will not perform
1689 side-effects more the once. */
1690 narg = save_expr (arg);
1691 if (narg != arg)
1693 arglist = build_tree_list (NULL_TREE, arg);
1694 exp = build_function_call_expr (fndecl, arglist);
1697 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1699 emit_queue ();
1700 start_sequence ();
1702 /* Compute into TARGET.
1703 Set TARGET to wherever the result comes back. */
1704 target = expand_unop (mode, builtin_optab, op0, target, 0);
1706 if (target != 0)
1708 if (errno_set)
1709 expand_errno_check (exp, target);
1711 /* Output the entire sequence. */
1712 insns = get_insns ();
1713 end_sequence ();
1714 emit_insn (insns);
1715 return target;
1718 /* If we were unable to expand via the builtin, stop the sequence
1719 (without outputting the insns) and call to the library function
1720 with the stabilized argument list. */
1721 end_sequence ();
1724 before_call = get_last_insn ();
1726 target = expand_call (exp, target, target == const0_rtx);
1728 /* If this is a sqrt operation and we don't care about errno, try to
1729 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1730 This allows the semantics of the libcall to be visible to the RTL
1731 optimizers. */
1732 if (builtin_optab == sqrt_optab && !errno_set)
1734 /* Search backwards through the insns emitted by expand_call looking
1735 for the instruction with the REG_RETVAL note. */
1736 rtx last = get_last_insn ();
1737 while (last != before_call)
1739 if (find_reg_note (last, REG_RETVAL, NULL))
1741 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1742 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1743 two elements, i.e. symbol_ref(sqrt) and the operand. */
1744 if (note
1745 && GET_CODE (note) == EXPR_LIST
1746 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1747 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1748 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1750 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1751 /* Check operand is a register with expected mode. */
1752 if (operand
1753 && GET_CODE (operand) == REG
1754 && GET_MODE (operand) == mode)
1756 /* Replace the REG_EQUAL note with a SQRT rtx. */
1757 rtx equiv = gen_rtx_SQRT (mode, operand);
1758 set_unique_reg_note (last, REG_EQUAL, equiv);
1761 break;
1763 last = PREV_INSN (last);
1767 return target;
1770 /* Expand a call to the builtin binary math functions (pow and atan2).
1771 Return 0 if a normal call should be emitted rather than expanding the
1772 function in-line. EXP is the expression that is a call to the builtin
1773 function; if convenient, the result should be placed in TARGET.
1774 SUBTARGET may be used as the target for computing one of EXP's
1775 operands. */
1777 static rtx
1778 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1780 optab builtin_optab;
1781 rtx op0, op1, insns;
1782 tree fndecl = get_callee_fndecl (exp);
1783 tree arglist = TREE_OPERAND (exp, 1);
1784 tree arg0, arg1, temp, narg;
1785 enum machine_mode mode;
1786 bool errno_set = true;
1787 bool stable = true;
1789 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1790 return 0;
1792 arg0 = TREE_VALUE (arglist);
1793 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1795 switch (DECL_FUNCTION_CODE (fndecl))
1797 case BUILT_IN_POW:
1798 case BUILT_IN_POWF:
1799 case BUILT_IN_POWL:
1800 builtin_optab = pow_optab; break;
1801 case BUILT_IN_ATAN2:
1802 case BUILT_IN_ATAN2F:
1803 case BUILT_IN_ATAN2L:
1804 builtin_optab = atan2_optab; break;
1805 default:
1806 abort ();
1809 /* Make a suitable register to place result in. */
1810 mode = TYPE_MODE (TREE_TYPE (exp));
1812 /* Before working hard, check whether the instruction is available. */
1813 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1814 return 0;
1816 target = gen_reg_rtx (mode);
1818 if (! flag_errno_math || ! HONOR_NANS (mode))
1819 errno_set = false;
1821 /* Alway stabilize the argument list. */
1822 narg = save_expr (arg1);
1823 if (narg != arg1)
1825 temp = build_tree_list (NULL_TREE, narg);
1826 stable = false;
1828 else
1829 temp = TREE_CHAIN (arglist);
1831 narg = save_expr (arg0);
1832 if (narg != arg0)
1834 arglist = tree_cons (NULL_TREE, narg, temp);
1835 stable = false;
1837 else if (! stable)
1838 arglist = tree_cons (NULL_TREE, arg0, temp);
1840 if (! stable)
1841 exp = build_function_call_expr (fndecl, arglist);
1843 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1844 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1846 emit_queue ();
1847 start_sequence ();
1849 /* Compute into TARGET.
1850 Set TARGET to wherever the result comes back. */
1851 target = expand_binop (mode, builtin_optab, op0, op1,
1852 target, 0, OPTAB_DIRECT);
1854 /* If we were unable to expand via the builtin, stop the sequence
1855 (without outputting the insns) and call to the library function
1856 with the stabilized argument list. */
1857 if (target == 0)
1859 end_sequence ();
1860 return expand_call (exp, target, target == const0_rtx);
1863 if (errno_set)
1864 expand_errno_check (exp, target);
1866 /* Output the entire sequence. */
1867 insns = get_insns ();
1868 end_sequence ();
1869 emit_insn (insns);
1871 return target;
1874 /* To evaluate powi(x,n), the floating point value x raised to the
1875 constant integer exponent n, we use a hybrid algorithm that
1876 combines the "window method" with look-up tables. For an
1877 introduction to exponentiation algorithms and "addition chains",
1878 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1879 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1880 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1881 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1883 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1884 multiplications to inline before calling the system library's pow
1885 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1886 so this default never requires calling pow, powf or powl. */
1888 #ifndef POWI_MAX_MULTS
1889 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1890 #endif
1892 /* The size of the "optimal power tree" lookup table. All
1893 exponents less than this value are simply looked up in the
1894 powi_table below. This threshold is also used to size the
1895 cache of pseudo registers that hold intermediate results. */
1896 #define POWI_TABLE_SIZE 256
1898 /* The size, in bits of the window, used in the "window method"
1899 exponentiation algorithm. This is equivalent to a radix of
1900 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1901 #define POWI_WINDOW_SIZE 3
1903 /* The following table is an efficient representation of an
1904 "optimal power tree". For each value, i, the corresponding
1905 value, j, in the table states than an optimal evaluation
1906 sequence for calculating pow(x,i) can be found by evaluating
1907 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1908 100 integers is given in Knuth's "Seminumerical algorithms". */
1910 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1912 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1913 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1914 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1915 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1916 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1917 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1918 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1919 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1920 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1921 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1922 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1923 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1924 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1925 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1926 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1927 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1928 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1929 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1930 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1931 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1932 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1933 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1934 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1935 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1936 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1937 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1938 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1939 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1940 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1941 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1942 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1943 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1947 /* Return the number of multiplications required to calculate
1948 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
1949 subroutine of powi_cost. CACHE is an array indicating
1950 which exponents have already been calculated. */
1952 static int
1953 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1955 /* If we've already calculated this exponent, then this evaluation
1956 doesn't require any additional multiplications. */
1957 if (cache[n])
1958 return 0;
1960 cache[n] = true;
1961 return powi_lookup_cost (n - powi_table[n], cache)
1962 + powi_lookup_cost (powi_table[n], cache) + 1;
1965 /* Return the number of multiplications required to calculate
1966 powi(x,n) for an arbitrary x, given the exponent N. This
1967 function needs to be kept in sync with expand_powi below. */
1969 static int
1970 powi_cost (HOST_WIDE_INT n)
1972 bool cache[POWI_TABLE_SIZE];
1973 unsigned HOST_WIDE_INT digit;
1974 unsigned HOST_WIDE_INT val;
1975 int result;
1977 if (n == 0)
1978 return 0;
1980 /* Ignore the reciprocal when calculating the cost. */
1981 val = (n < 0) ? -n : n;
1983 /* Initialize the exponent cache. */
1984 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
1985 cache[1] = true;
1987 result = 0;
1989 while (val >= POWI_TABLE_SIZE)
1991 if (val & 1)
1993 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
1994 result += powi_lookup_cost (digit, cache)
1995 + POWI_WINDOW_SIZE + 1;
1996 val >>= POWI_WINDOW_SIZE;
1998 else
2000 val >>= 1;
2001 result++;
2005 return result + powi_lookup_cost (val, cache);
2008 /* Recursive subroutine of expand_powi. This function takes the array,
2009 CACHE, of already calculated exponents and an exponent N and returns
2010 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2012 static rtx
2013 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2015 unsigned HOST_WIDE_INT digit;
2016 rtx target, result;
2017 rtx op0, op1;
2019 if (n < POWI_TABLE_SIZE)
2021 if (cache[n])
2022 return cache[n];
2024 target = gen_reg_rtx (mode);
2025 cache[n] = target;
2027 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2028 op1 = expand_powi_1 (mode, powi_table[n], cache);
2030 else if (n & 1)
2032 target = gen_reg_rtx (mode);
2033 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2034 op0 = expand_powi_1 (mode, n - digit, cache);
2035 op1 = expand_powi_1 (mode, digit, cache);
2037 else
2039 target = gen_reg_rtx (mode);
2040 op0 = expand_powi_1 (mode, n >> 1, cache);
2041 op1 = op0;
2044 result = expand_mult (mode, op0, op1, target, 0);
2045 if (result != target)
2046 emit_move_insn (target, result);
2047 return target;
2050 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2051 floating point operand in mode MODE, and N is the exponent. This
2052 function needs to be kept in sync with powi_cost above. */
2054 static rtx
2055 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2057 unsigned HOST_WIDE_INT val;
2058 rtx cache[POWI_TABLE_SIZE];
2059 rtx result;
2061 if (n == 0)
2062 return CONST1_RTX (mode);
2064 val = (n < 0) ? -n : n;
2066 memset (cache, 0, sizeof (cache));
2067 cache[1] = x;
2069 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2071 /* If the original exponent was negative, reciprocate the result. */
2072 if (n < 0)
2073 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2074 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2076 return result;
2079 /* Expand a call to the pow built-in mathematical function. Return 0 if
2080 a normal call should be emitted rather than expanding the function
2081 in-line. EXP is the expression that is a call to the builtin
2082 function; if convenient, the result should be placed in TARGET. */
2084 static rtx
2085 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2087 tree arglist = TREE_OPERAND (exp, 1);
2088 tree arg0, arg1;
2090 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2091 return 0;
2093 arg0 = TREE_VALUE (arglist);
2094 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2096 if (TREE_CODE (arg1) == REAL_CST
2097 && ! TREE_CONSTANT_OVERFLOW (arg1))
2099 REAL_VALUE_TYPE cint;
2100 REAL_VALUE_TYPE c;
2101 HOST_WIDE_INT n;
2103 c = TREE_REAL_CST (arg1);
2104 n = real_to_integer (&c);
2105 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2106 if (real_identical (&c, &cint))
2108 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2109 Otherwise, check the number of multiplications required.
2110 Note that pow never sets errno for an integer exponent. */
2111 if ((n >= -1 && n <= 2)
2112 || (flag_unsafe_math_optimizations
2113 && ! optimize_size
2114 && powi_cost (n) <= POWI_MAX_MULTS))
2116 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2117 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2118 op = force_reg (mode, op);
2119 return expand_powi (op, mode, n);
2123 return expand_builtin_mathfn_2 (exp, target, NULL_RTX);
2126 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2127 if we failed the caller should emit a normal call, otherwise
2128 try to get the result in TARGET, if convenient. */
2130 static rtx
2131 expand_builtin_strlen (tree arglist, rtx target,
2132 enum machine_mode target_mode)
2134 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2135 return 0;
2136 else
2138 rtx pat;
2139 tree len, src = TREE_VALUE (arglist);
2140 rtx result, src_reg, char_rtx, before_strlen;
2141 enum machine_mode insn_mode = target_mode, char_mode;
2142 enum insn_code icode = CODE_FOR_nothing;
2143 int align;
2145 /* If the length can be computed at compile-time, return it. */
2146 len = c_strlen (src, 0);
2147 if (len)
2148 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2150 /* If the length can be computed at compile-time and is constant
2151 integer, but there are side-effects in src, evaluate
2152 src for side-effects, then return len.
2153 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2154 can be optimized into: i++; x = 3; */
2155 len = c_strlen (src, 1);
2156 if (len && TREE_CODE (len) == INTEGER_CST)
2158 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2159 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2162 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2164 /* If SRC is not a pointer type, don't do this operation inline. */
2165 if (align == 0)
2166 return 0;
2168 /* Bail out if we can't compute strlen in the right mode. */
2169 while (insn_mode != VOIDmode)
2171 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2172 if (icode != CODE_FOR_nothing)
2173 break;
2175 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2177 if (insn_mode == VOIDmode)
2178 return 0;
2180 /* Make a place to write the result of the instruction. */
2181 result = target;
2182 if (! (result != 0
2183 && GET_CODE (result) == REG
2184 && GET_MODE (result) == insn_mode
2185 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2186 result = gen_reg_rtx (insn_mode);
2188 /* Make a place to hold the source address. We will not expand
2189 the actual source until we are sure that the expansion will
2190 not fail -- there are trees that cannot be expanded twice. */
2191 src_reg = gen_reg_rtx (Pmode);
2193 /* Mark the beginning of the strlen sequence so we can emit the
2194 source operand later. */
2195 before_strlen = get_last_insn ();
2197 char_rtx = const0_rtx;
2198 char_mode = insn_data[(int) icode].operand[2].mode;
2199 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2200 char_mode))
2201 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2203 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2204 char_rtx, GEN_INT (align));
2205 if (! pat)
2206 return 0;
2207 emit_insn (pat);
2209 /* Now that we are assured of success, expand the source. */
2210 start_sequence ();
2211 pat = memory_address (BLKmode,
2212 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2213 if (pat != src_reg)
2214 emit_move_insn (src_reg, pat);
2215 pat = get_insns ();
2216 end_sequence ();
2218 if (before_strlen)
2219 emit_insn_after (pat, before_strlen);
2220 else
2221 emit_insn_before (pat, get_insns ());
2223 /* Return the value in the proper mode for this function. */
2224 if (GET_MODE (result) == target_mode)
2225 target = result;
2226 else if (target != 0)
2227 convert_move (target, result, 0);
2228 else
2229 target = convert_to_mode (target_mode, result, 0);
2231 return target;
2235 /* Expand a call to the strstr builtin. Return 0 if we failed the
2236 caller should emit a normal call, otherwise try to get the result
2237 in TARGET, if convenient (and in mode MODE if that's convenient). */
2239 static rtx
2240 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2242 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2243 return 0;
2244 else
2246 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2247 tree fn;
2248 const char *p1, *p2;
2250 p2 = c_getstr (s2);
2251 if (p2 == NULL)
2252 return 0;
2254 p1 = c_getstr (s1);
2255 if (p1 != NULL)
2257 const char *r = strstr (p1, p2);
2259 if (r == NULL)
2260 return const0_rtx;
2262 /* Return an offset into the constant string argument. */
2263 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2264 s1, ssize_int (r - p1))),
2265 target, mode, EXPAND_NORMAL);
2268 if (p2[0] == '\0')
2269 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2271 if (p2[1] != '\0')
2272 return 0;
2274 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2275 if (!fn)
2276 return 0;
2278 /* New argument list transforming strstr(s1, s2) to
2279 strchr(s1, s2[0]). */
2280 arglist =
2281 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2282 arglist = tree_cons (NULL_TREE, s1, arglist);
2283 return expand_expr (build_function_call_expr (fn, arglist),
2284 target, mode, EXPAND_NORMAL);
2288 /* Expand a call to the strchr builtin. Return 0 if we failed the
2289 caller should emit a normal call, otherwise try to get the result
2290 in TARGET, if convenient (and in mode MODE if that's convenient). */
2292 static rtx
2293 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2295 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2296 return 0;
2297 else
2299 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2300 const char *p1;
2302 if (TREE_CODE (s2) != INTEGER_CST)
2303 return 0;
2305 p1 = c_getstr (s1);
2306 if (p1 != NULL)
2308 char c;
2309 const char *r;
2311 if (target_char_cast (s2, &c))
2312 return 0;
2314 r = strchr (p1, c);
2316 if (r == NULL)
2317 return const0_rtx;
2319 /* Return an offset into the constant string argument. */
2320 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2321 s1, ssize_int (r - p1))),
2322 target, mode, EXPAND_NORMAL);
2325 /* FIXME: Should use here strchrM optab so that ports can optimize
2326 this. */
2327 return 0;
2331 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2332 caller should emit a normal call, otherwise try to get the result
2333 in TARGET, if convenient (and in mode MODE if that's convenient). */
2335 static rtx
2336 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2338 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2339 return 0;
2340 else
2342 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2343 tree fn;
2344 const char *p1;
2346 if (TREE_CODE (s2) != INTEGER_CST)
2347 return 0;
2349 p1 = c_getstr (s1);
2350 if (p1 != NULL)
2352 char c;
2353 const char *r;
2355 if (target_char_cast (s2, &c))
2356 return 0;
2358 r = strrchr (p1, c);
2360 if (r == NULL)
2361 return const0_rtx;
2363 /* Return an offset into the constant string argument. */
2364 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2365 s1, ssize_int (r - p1))),
2366 target, mode, EXPAND_NORMAL);
2369 if (! integer_zerop (s2))
2370 return 0;
2372 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2373 if (!fn)
2374 return 0;
2376 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2377 return expand_expr (build_function_call_expr (fn, arglist),
2378 target, mode, EXPAND_NORMAL);
2382 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2383 caller should emit a normal call, otherwise try to get the result
2384 in TARGET, if convenient (and in mode MODE if that's convenient). */
2386 static rtx
2387 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2389 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2390 return 0;
2391 else
2393 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2394 tree fn;
2395 const char *p1, *p2;
2397 p2 = c_getstr (s2);
2398 if (p2 == NULL)
2399 return 0;
2401 p1 = c_getstr (s1);
2402 if (p1 != NULL)
2404 const char *r = strpbrk (p1, p2);
2406 if (r == NULL)
2407 return const0_rtx;
2409 /* Return an offset into the constant string argument. */
2410 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2411 s1, ssize_int (r - p1))),
2412 target, mode, EXPAND_NORMAL);
2415 if (p2[0] == '\0')
2417 /* strpbrk(x, "") == NULL.
2418 Evaluate and ignore the arguments in case they had
2419 side-effects. */
2420 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2421 return const0_rtx;
2424 if (p2[1] != '\0')
2425 return 0; /* Really call strpbrk. */
2427 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2428 if (!fn)
2429 return 0;
2431 /* New argument list transforming strpbrk(s1, s2) to
2432 strchr(s1, s2[0]). */
2433 arglist =
2434 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2435 arglist = tree_cons (NULL_TREE, s1, arglist);
2436 return expand_expr (build_function_call_expr (fn, arglist),
2437 target, mode, EXPAND_NORMAL);
2441 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2442 bytes from constant string DATA + OFFSET and return it as target
2443 constant. */
2445 static rtx
2446 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2447 enum machine_mode mode)
2449 const char *str = (const char *) data;
2451 if (offset < 0
2452 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2453 > strlen (str) + 1))
2454 abort (); /* Attempt to read past the end of constant string. */
2456 return c_readstr (str + offset, mode);
2459 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2460 Return 0 if we failed, the caller should emit a normal call,
2461 otherwise try to get the result in TARGET, if convenient (and in
2462 mode MODE if that's convenient). */
2463 static rtx
2464 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2466 if (!validate_arglist (arglist,
2467 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2468 return 0;
2469 else
2471 tree dest = TREE_VALUE (arglist);
2472 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2473 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2474 const char *src_str;
2475 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2476 unsigned int dest_align
2477 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2478 rtx dest_mem, src_mem, dest_addr, len_rtx;
2480 /* If DEST is not a pointer type, call the normal function. */
2481 if (dest_align == 0)
2482 return 0;
2484 /* If the LEN parameter is zero, return DEST. */
2485 if (integer_zerop (len))
2487 /* Evaluate and ignore SRC in case it has side-effects. */
2488 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2489 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2492 /* If SRC and DEST are the same (and not volatile), return DEST. */
2493 if (operand_equal_p (src, dest, 0))
2495 /* Evaluate and ignore LEN in case it has side-effects. */
2496 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2497 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2500 /* If either SRC is not a pointer type, don't do this
2501 operation in-line. */
2502 if (src_align == 0)
2503 return 0;
2505 dest_mem = get_memory_rtx (dest);
2506 set_mem_align (dest_mem, dest_align);
2507 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2508 src_str = c_getstr (src);
2510 /* If SRC is a string constant and block move would be done
2511 by pieces, we can avoid loading the string from memory
2512 and only stored the computed constants. */
2513 if (src_str
2514 && GET_CODE (len_rtx) == CONST_INT
2515 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2516 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2517 (void *) src_str, dest_align))
2519 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2520 builtin_memcpy_read_str,
2521 (void *) src_str, dest_align, 0);
2522 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2523 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2524 return dest_mem;
2527 src_mem = get_memory_rtx (src);
2528 set_mem_align (src_mem, src_align);
2530 /* Copy word part most expediently. */
2531 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2532 BLOCK_OP_NORMAL);
2534 if (dest_addr == 0)
2536 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2537 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2539 return dest_addr;
2543 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2544 Return 0 if we failed the caller should emit a normal call,
2545 otherwise try to get the result in TARGET, if convenient (and in
2546 mode MODE if that's convenient). If ENDP is 0 return the
2547 destination pointer, if ENDP is 1 return the end pointer ala
2548 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2549 stpcpy. */
2551 static rtx
2552 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2553 int endp)
2555 if (!validate_arglist (arglist,
2556 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2557 return 0;
2558 /* If return value is ignored, transform mempcpy into memcpy. */
2559 else if (target == const0_rtx)
2561 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2563 if (!fn)
2564 return 0;
2566 return expand_expr (build_function_call_expr (fn, arglist),
2567 target, mode, EXPAND_NORMAL);
2569 else
2571 tree dest = TREE_VALUE (arglist);
2572 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2573 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2574 const char *src_str;
2575 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2576 unsigned int dest_align
2577 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2578 rtx dest_mem, src_mem, len_rtx;
2580 /* If DEST is not a pointer type, call the normal function. */
2581 if (dest_align == 0)
2582 return 0;
2584 /* If SRC and DEST are the same (and not volatile), do nothing. */
2585 if (operand_equal_p (src, dest, 0))
2587 tree expr;
2589 if (endp == 0)
2591 /* Evaluate and ignore LEN in case it has side-effects. */
2592 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2593 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2596 if (endp == 2)
2597 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2598 integer_one_node));
2599 len = convert (TREE_TYPE (dest), len);
2600 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2601 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2604 /* If LEN is not constant, call the normal function. */
2605 if (! host_integerp (len, 1))
2606 return 0;
2608 /* If the LEN parameter is zero, return DEST. */
2609 if (tree_low_cst (len, 1) == 0)
2611 /* Evaluate and ignore SRC in case it has side-effects. */
2612 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2613 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2616 /* If either SRC is not a pointer type, don't do this
2617 operation in-line. */
2618 if (src_align == 0)
2619 return 0;
2621 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2622 src_str = c_getstr (src);
2624 /* If SRC is a string constant and block move would be done
2625 by pieces, we can avoid loading the string from memory
2626 and only stored the computed constants. */
2627 if (src_str
2628 && GET_CODE (len_rtx) == CONST_INT
2629 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2630 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2631 (void *) src_str, dest_align))
2633 dest_mem = get_memory_rtx (dest);
2634 set_mem_align (dest_mem, dest_align);
2635 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2636 builtin_memcpy_read_str,
2637 (void *) src_str, dest_align, endp);
2638 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2639 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2640 return dest_mem;
2643 if (GET_CODE (len_rtx) == CONST_INT
2644 && can_move_by_pieces (INTVAL (len_rtx),
2645 MIN (dest_align, src_align)))
2647 dest_mem = get_memory_rtx (dest);
2648 set_mem_align (dest_mem, dest_align);
2649 src_mem = get_memory_rtx (src);
2650 set_mem_align (src_mem, src_align);
2651 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2652 MIN (dest_align, src_align), endp);
2653 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2654 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2655 return dest_mem;
2658 return 0;
2662 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2663 if we failed the caller should emit a normal call. */
2665 static rtx
2666 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2668 if (!validate_arglist (arglist,
2669 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2670 return 0;
2671 else
2673 tree dest = TREE_VALUE (arglist);
2674 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2675 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2677 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2678 unsigned int dest_align
2679 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2681 /* If DEST is not a pointer type, call the normal function. */
2682 if (dest_align == 0)
2683 return 0;
2685 /* If the LEN parameter is zero, return DEST. */
2686 if (integer_zerop (len))
2688 /* Evaluate and ignore SRC in case it has side-effects. */
2689 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2690 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2693 /* If SRC and DEST are the same (and not volatile), return DEST. */
2694 if (operand_equal_p (src, dest, 0))
2696 /* Evaluate and ignore LEN in case it has side-effects. */
2697 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2698 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2701 /* If either SRC is not a pointer type, don't do this
2702 operation in-line. */
2703 if (src_align == 0)
2704 return 0;
2706 /* If src is categorized for a readonly section we can use
2707 normal memcpy. */
2708 if (readonly_data_expr (src))
2710 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2711 if (!fn)
2712 return 0;
2713 return expand_expr (build_function_call_expr (fn, arglist),
2714 target, mode, EXPAND_NORMAL);
2717 /* Otherwise, call the normal function. */
2718 return 0;
2722 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2723 if we failed the caller should emit a normal call. */
2725 static rtx
2726 expand_builtin_bcopy (tree arglist)
2728 tree src, dest, size, newarglist;
2730 if (!validate_arglist (arglist,
2731 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2732 return NULL_RTX;
2734 src = TREE_VALUE (arglist);
2735 dest = TREE_VALUE (TREE_CHAIN (arglist));
2736 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2738 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2739 memmove(ptr y, ptr x, size_t z). This is done this way
2740 so that if it isn't expanded inline, we fallback to
2741 calling bcopy instead of memmove. */
2743 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2744 newarglist = tree_cons (NULL_TREE, src, newarglist);
2745 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2747 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2750 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2751 if we failed the caller should emit a normal call, otherwise try to get
2752 the result in TARGET, if convenient (and in mode MODE if that's
2753 convenient). */
2755 static rtx
2756 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2758 tree fn, len, src, dst;
2760 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2761 return 0;
2763 src = TREE_VALUE (TREE_CHAIN (arglist));
2764 dst = TREE_VALUE (arglist);
2766 /* If SRC and DST are equal (and not volatile), return DST. */
2767 if (operand_equal_p (src, dst, 0))
2768 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2770 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2771 if (!fn)
2772 return 0;
2774 len = c_strlen (src, 1);
2775 if (len == 0 || TREE_SIDE_EFFECTS (len))
2776 return 0;
2778 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2779 arglist = build_tree_list (NULL_TREE, len);
2780 arglist = tree_cons (NULL_TREE, src, arglist);
2781 arglist = tree_cons (NULL_TREE, dst, arglist);
2782 return expand_expr (build_function_call_expr (fn, arglist),
2783 target, mode, EXPAND_NORMAL);
2786 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2787 Return 0 if we failed the caller should emit a normal call,
2788 otherwise try to get the result in TARGET, if convenient (and in
2789 mode MODE if that's convenient). */
2791 static rtx
2792 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2794 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2795 return 0;
2796 else
2798 tree dst, src, len;
2800 /* If return value is ignored, transform stpcpy into strcpy. */
2801 if (target == const0_rtx)
2803 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2804 if (!fn)
2805 return 0;
2807 return expand_expr (build_function_call_expr (fn, arglist),
2808 target, mode, EXPAND_NORMAL);
2811 /* Ensure we get an actual string whose length can be evaluated at
2812 compile-time, not an expression containing a string. This is
2813 because the latter will potentially produce pessimized code
2814 when used to produce the return value. */
2815 src = TREE_VALUE (TREE_CHAIN (arglist));
2816 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2817 return 0;
2819 dst = TREE_VALUE (arglist);
2820 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2821 arglist = build_tree_list (NULL_TREE, len);
2822 arglist = tree_cons (NULL_TREE, src, arglist);
2823 arglist = tree_cons (NULL_TREE, dst, arglist);
2824 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2828 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2829 bytes from constant string DATA + OFFSET and return it as target
2830 constant. */
2832 static rtx
2833 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2834 enum machine_mode mode)
2836 const char *str = (const char *) data;
2838 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2839 return const0_rtx;
2841 return c_readstr (str + offset, mode);
2844 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2845 if we failed the caller should emit a normal call. */
2847 static rtx
2848 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2850 if (!validate_arglist (arglist,
2851 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2852 return 0;
2853 else
2855 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2856 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2857 tree fn;
2859 /* We must be passed a constant len parameter. */
2860 if (TREE_CODE (len) != INTEGER_CST)
2861 return 0;
2863 /* If the len parameter is zero, return the dst parameter. */
2864 if (integer_zerop (len))
2866 /* Evaluate and ignore the src argument in case it has
2867 side-effects. */
2868 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2869 VOIDmode, EXPAND_NORMAL);
2870 /* Return the dst parameter. */
2871 return expand_expr (TREE_VALUE (arglist), target, mode,
2872 EXPAND_NORMAL);
2875 /* Now, we must be passed a constant src ptr parameter. */
2876 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2877 return 0;
2879 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2881 /* We're required to pad with trailing zeros if the requested
2882 len is greater than strlen(s2)+1. In that case try to
2883 use store_by_pieces, if it fails, punt. */
2884 if (tree_int_cst_lt (slen, len))
2886 tree dest = TREE_VALUE (arglist);
2887 unsigned int dest_align
2888 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2889 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2890 rtx dest_mem;
2892 if (!p || dest_align == 0 || !host_integerp (len, 1)
2893 || !can_store_by_pieces (tree_low_cst (len, 1),
2894 builtin_strncpy_read_str,
2895 (void *) p, dest_align))
2896 return 0;
2898 dest_mem = get_memory_rtx (dest);
2899 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2900 builtin_strncpy_read_str,
2901 (void *) p, dest_align, 0);
2902 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2903 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2904 return dest_mem;
2907 /* OK transform into builtin memcpy. */
2908 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2909 if (!fn)
2910 return 0;
2911 return expand_expr (build_function_call_expr (fn, arglist),
2912 target, mode, EXPAND_NORMAL);
2916 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2917 bytes from constant string DATA + OFFSET and return it as target
2918 constant. */
2920 static rtx
2921 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2922 enum machine_mode mode)
2924 const char *c = (const char *) data;
2925 char *p = alloca (GET_MODE_SIZE (mode));
2927 memset (p, *c, GET_MODE_SIZE (mode));
2929 return c_readstr (p, mode);
2932 /* Callback routine for store_by_pieces. Return the RTL of a register
2933 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2934 char value given in the RTL register data. For example, if mode is
2935 4 bytes wide, return the RTL for 0x01010101*data. */
2937 static rtx
2938 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2939 enum machine_mode mode)
2941 rtx target, coeff;
2942 size_t size;
2943 char *p;
2945 size = GET_MODE_SIZE (mode);
2946 if (size == 1)
2947 return (rtx) data;
2949 p = alloca (size);
2950 memset (p, 1, size);
2951 coeff = c_readstr (p, mode);
2953 target = convert_to_mode (mode, (rtx) data, 1);
2954 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2955 return force_reg (mode, target);
2958 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2959 if we failed the caller should emit a normal call, otherwise try to get
2960 the result in TARGET, if convenient (and in mode MODE if that's
2961 convenient). */
2963 static rtx
2964 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2966 if (!validate_arglist (arglist,
2967 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2968 return 0;
2969 else
2971 tree dest = TREE_VALUE (arglist);
2972 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2973 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2974 char c;
2976 unsigned int dest_align
2977 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2978 rtx dest_mem, dest_addr, len_rtx;
2980 /* If DEST is not a pointer type, don't do this
2981 operation in-line. */
2982 if (dest_align == 0)
2983 return 0;
2985 /* If the LEN parameter is zero, return DEST. */
2986 if (integer_zerop (len))
2988 /* Evaluate and ignore VAL in case it has side-effects. */
2989 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2990 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2993 if (TREE_CODE (val) != INTEGER_CST)
2995 rtx val_rtx;
2997 if (!host_integerp (len, 1))
2998 return 0;
3000 if (optimize_size && tree_low_cst (len, 1) > 1)
3001 return 0;
3003 /* Assume that we can memset by pieces if we can store the
3004 * the coefficients by pieces (in the required modes).
3005 * We can't pass builtin_memset_gen_str as that emits RTL. */
3006 c = 1;
3007 if (!can_store_by_pieces (tree_low_cst (len, 1),
3008 builtin_memset_read_str,
3009 &c, dest_align))
3010 return 0;
3012 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3013 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3014 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3015 val_rtx);
3016 dest_mem = get_memory_rtx (dest);
3017 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3018 builtin_memset_gen_str,
3019 val_rtx, dest_align, 0);
3020 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3021 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3022 return dest_mem;
3025 if (target_char_cast (val, &c))
3026 return 0;
3028 if (c)
3030 if (!host_integerp (len, 1))
3031 return 0;
3032 if (!can_store_by_pieces (tree_low_cst (len, 1),
3033 builtin_memset_read_str, &c,
3034 dest_align))
3035 return 0;
3037 dest_mem = get_memory_rtx (dest);
3038 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3039 builtin_memset_read_str,
3040 &c, dest_align, 0);
3041 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3042 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3043 return dest_mem;
3046 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3048 dest_mem = get_memory_rtx (dest);
3049 set_mem_align (dest_mem, dest_align);
3050 dest_addr = clear_storage (dest_mem, len_rtx);
3052 if (dest_addr == 0)
3054 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3055 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3058 return dest_addr;
3062 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3063 if we failed the caller should emit a normal call. */
3065 static rtx
3066 expand_builtin_bzero (tree arglist)
3068 tree dest, size, newarglist;
3070 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3071 return NULL_RTX;
3073 dest = TREE_VALUE (arglist);
3074 size = TREE_VALUE (TREE_CHAIN (arglist));
3076 /* New argument list transforming bzero(ptr x, int y) to
3077 memset(ptr x, int 0, size_t y). This is done this way
3078 so that if it isn't expanded inline, we fallback to
3079 calling bzero instead of memset. */
3081 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3082 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3083 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3085 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3088 /* Expand expression EXP, which is a call to the memcmp built-in function.
3089 ARGLIST is the argument list for this call. Return 0 if we failed and the
3090 caller should emit a normal call, otherwise try to get the result in
3091 TARGET, if convenient (and in mode MODE, if that's convenient). */
3093 static rtx
3094 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3095 enum machine_mode mode)
3097 tree arg1, arg2, len;
3098 const char *p1, *p2;
3100 if (!validate_arglist (arglist,
3101 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3102 return 0;
3104 arg1 = TREE_VALUE (arglist);
3105 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3106 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3108 /* If the len parameter is zero, return zero. */
3109 if (integer_zerop (len))
3111 /* Evaluate and ignore arg1 and arg2 in case they have
3112 side-effects. */
3113 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3114 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3115 return const0_rtx;
3118 /* If both arguments are equal (and not volatile), return zero. */
3119 if (operand_equal_p (arg1, arg2, 0))
3121 /* Evaluate and ignore len in case it has side-effects. */
3122 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3123 return const0_rtx;
3126 p1 = c_getstr (arg1);
3127 p2 = c_getstr (arg2);
3129 /* If all arguments are constant, and the value of len is not greater
3130 than the lengths of arg1 and arg2, evaluate at compile-time. */
3131 if (host_integerp (len, 1) && p1 && p2
3132 && compare_tree_int (len, strlen (p1) + 1) <= 0
3133 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3135 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3137 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3140 /* If len parameter is one, return an expression corresponding to
3141 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3142 if (integer_onep (len))
3144 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3145 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3146 tree ind1 =
3147 fold (build1 (CONVERT_EXPR, integer_type_node,
3148 build1 (INDIRECT_REF, cst_uchar_node,
3149 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3150 tree ind2 =
3151 fold (build1 (CONVERT_EXPR, integer_type_node,
3152 build1 (INDIRECT_REF, cst_uchar_node,
3153 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3154 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3155 return expand_expr (result, target, mode, EXPAND_NORMAL);
3158 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3160 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3161 rtx result;
3162 rtx insn;
3164 int arg1_align
3165 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3166 int arg2_align
3167 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3168 enum machine_mode insn_mode;
3170 #ifdef HAVE_cmpmemsi
3171 if (HAVE_cmpmemsi)
3172 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3173 else
3174 #endif
3175 #ifdef HAVE_cmpstrsi
3176 if (HAVE_cmpstrsi)
3177 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3178 else
3179 #endif
3180 return 0;
3182 /* If we don't have POINTER_TYPE, call the function. */
3183 if (arg1_align == 0 || arg2_align == 0)
3184 return 0;
3186 /* Make a place to write the result of the instruction. */
3187 result = target;
3188 if (! (result != 0
3189 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3190 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3191 result = gen_reg_rtx (insn_mode);
3193 arg1_rtx = get_memory_rtx (arg1);
3194 arg2_rtx = get_memory_rtx (arg2);
3195 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3196 #ifdef HAVE_cmpmemsi
3197 if (HAVE_cmpmemsi)
3198 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3199 GEN_INT (MIN (arg1_align, arg2_align)));
3200 else
3201 #endif
3202 #ifdef HAVE_cmpstrsi
3203 if (HAVE_cmpstrsi)
3204 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3205 GEN_INT (MIN (arg1_align, arg2_align)));
3206 else
3207 #endif
3208 abort ();
3210 if (insn)
3211 emit_insn (insn);
3212 else
3213 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3214 TYPE_MODE (integer_type_node), 3,
3215 XEXP (arg1_rtx, 0), Pmode,
3216 XEXP (arg2_rtx, 0), Pmode,
3217 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3218 TREE_UNSIGNED (sizetype)),
3219 TYPE_MODE (sizetype));
3221 /* Return the value in the proper mode for this function. */
3222 mode = TYPE_MODE (TREE_TYPE (exp));
3223 if (GET_MODE (result) == mode)
3224 return result;
3225 else if (target != 0)
3227 convert_move (target, result, 0);
3228 return target;
3230 else
3231 return convert_to_mode (mode, result, 0);
3233 #endif
3235 return 0;
3238 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3239 if we failed the caller should emit a normal call, otherwise try to get
3240 the result in TARGET, if convenient. */
3242 static rtx
3243 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3245 tree arglist = TREE_OPERAND (exp, 1);
3246 tree arg1, arg2;
3247 const char *p1, *p2;
3249 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3250 return 0;
3252 arg1 = TREE_VALUE (arglist);
3253 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3255 /* If both arguments are equal (and not volatile), return zero. */
3256 if (operand_equal_p (arg1, arg2, 0))
3257 return const0_rtx;
3259 p1 = c_getstr (arg1);
3260 p2 = c_getstr (arg2);
3262 if (p1 && p2)
3264 const int i = strcmp (p1, p2);
3265 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3268 /* If either arg is "", return an expression corresponding to
3269 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3270 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3272 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3273 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3274 tree ind1 =
3275 fold (build1 (CONVERT_EXPR, integer_type_node,
3276 build1 (INDIRECT_REF, cst_uchar_node,
3277 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3278 tree ind2 =
3279 fold (build1 (CONVERT_EXPR, integer_type_node,
3280 build1 (INDIRECT_REF, cst_uchar_node,
3281 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3282 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3283 return expand_expr (result, target, mode, EXPAND_NORMAL);
3286 #ifdef HAVE_cmpstrsi
3287 if (HAVE_cmpstrsi)
3289 tree len, len1, len2;
3290 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3291 rtx result, insn;
3292 tree fndecl;
3294 int arg1_align
3295 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3296 int arg2_align
3297 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3298 enum machine_mode insn_mode
3299 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3301 len1 = c_strlen (arg1, 1);
3302 len2 = c_strlen (arg2, 1);
3304 if (len1)
3305 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3306 if (len2)
3307 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3309 /* If we don't have a constant length for the first, use the length
3310 of the second, if we know it. We don't require a constant for
3311 this case; some cost analysis could be done if both are available
3312 but neither is constant. For now, assume they're equally cheap,
3313 unless one has side effects. If both strings have constant lengths,
3314 use the smaller. */
3316 if (!len1)
3317 len = len2;
3318 else if (!len2)
3319 len = len1;
3320 else if (TREE_SIDE_EFFECTS (len1))
3321 len = len2;
3322 else if (TREE_SIDE_EFFECTS (len2))
3323 len = len1;
3324 else if (TREE_CODE (len1) != INTEGER_CST)
3325 len = len2;
3326 else if (TREE_CODE (len2) != INTEGER_CST)
3327 len = len1;
3328 else if (tree_int_cst_lt (len1, len2))
3329 len = len1;
3330 else
3331 len = len2;
3333 /* If both arguments have side effects, we cannot optimize. */
3334 if (!len || TREE_SIDE_EFFECTS (len))
3335 return 0;
3337 /* If we don't have POINTER_TYPE, call the function. */
3338 if (arg1_align == 0 || arg2_align == 0)
3339 return 0;
3341 /* Make a place to write the result of the instruction. */
3342 result = target;
3343 if (! (result != 0
3344 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3345 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3346 result = gen_reg_rtx (insn_mode);
3348 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3349 arg1 = save_expr (arg1);
3350 arg2 = save_expr (arg2);
3352 arg1_rtx = get_memory_rtx (arg1);
3353 arg2_rtx = get_memory_rtx (arg2);
3354 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3355 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3356 GEN_INT (MIN (arg1_align, arg2_align)));
3357 if (insn)
3359 emit_insn (insn);
3361 /* Return the value in the proper mode for this function. */
3362 mode = TYPE_MODE (TREE_TYPE (exp));
3363 if (GET_MODE (result) == mode)
3364 return result;
3365 if (target == 0)
3366 return convert_to_mode (mode, result, 0);
3367 convert_move (target, result, 0);
3368 return target;
3371 /* Expand the library call ourselves using a stabilized argument
3372 list to avoid re-evaluating the function's arguments twice. */
3373 arglist = build_tree_list (NULL_TREE, arg2);
3374 arglist = tree_cons (NULL_TREE, arg1, arglist);
3375 fndecl = get_callee_fndecl (exp);
3376 exp = build_function_call_expr (fndecl, arglist);
3377 return expand_call (exp, target, target == const0_rtx);
3379 #endif
3380 return 0;
3383 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3384 if we failed the caller should emit a normal call, otherwise try to get
3385 the result in TARGET, if convenient. */
3387 static rtx
3388 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3390 tree arglist = TREE_OPERAND (exp, 1);
3391 tree arg1, arg2, arg3;
3392 const char *p1, *p2;
3394 if (!validate_arglist (arglist,
3395 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3396 return 0;
3398 arg1 = TREE_VALUE (arglist);
3399 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3400 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3402 /* If the len parameter is zero, return zero. */
3403 if (integer_zerop (arg3))
3405 /* Evaluate and ignore arg1 and arg2 in case they have
3406 side-effects. */
3407 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3408 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3409 return const0_rtx;
3412 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3413 if (operand_equal_p (arg1, arg2, 0))
3415 /* Evaluate and ignore arg3 in case it has side-effects. */
3416 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3417 return const0_rtx;
3420 p1 = c_getstr (arg1);
3421 p2 = c_getstr (arg2);
3423 /* If all arguments are constant, evaluate at compile-time. */
3424 if (host_integerp (arg3, 1) && p1 && p2)
3426 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3427 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3430 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3431 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3432 if (host_integerp (arg3, 1)
3433 && (tree_low_cst (arg3, 1) == 1
3434 || (tree_low_cst (arg3, 1) > 1
3435 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3437 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3438 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3439 tree ind1 =
3440 fold (build1 (CONVERT_EXPR, integer_type_node,
3441 build1 (INDIRECT_REF, cst_uchar_node,
3442 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3443 tree ind2 =
3444 fold (build1 (CONVERT_EXPR, integer_type_node,
3445 build1 (INDIRECT_REF, cst_uchar_node,
3446 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3447 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3448 return expand_expr (result, target, mode, EXPAND_NORMAL);
3451 /* If c_strlen can determine an expression for one of the string
3452 lengths, and it doesn't have side effects, then emit cmpstrsi
3453 using length MIN(strlen(string)+1, arg3). */
3454 #ifdef HAVE_cmpstrsi
3455 if (HAVE_cmpstrsi)
3457 tree len, len1, len2;
3458 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3459 rtx result, insn;
3460 tree fndecl;
3462 int arg1_align
3463 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3464 int arg2_align
3465 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3466 enum machine_mode insn_mode
3467 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3469 len1 = c_strlen (arg1, 1);
3470 len2 = c_strlen (arg2, 1);
3472 if (len1)
3473 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3474 if (len2)
3475 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3477 /* If we don't have a constant length for the first, use the length
3478 of the second, if we know it. We don't require a constant for
3479 this case; some cost analysis could be done if both are available
3480 but neither is constant. For now, assume they're equally cheap,
3481 unless one has side effects. If both strings have constant lengths,
3482 use the smaller. */
3484 if (!len1)
3485 len = len2;
3486 else if (!len2)
3487 len = len1;
3488 else if (TREE_SIDE_EFFECTS (len1))
3489 len = len2;
3490 else if (TREE_SIDE_EFFECTS (len2))
3491 len = len1;
3492 else if (TREE_CODE (len1) != INTEGER_CST)
3493 len = len2;
3494 else if (TREE_CODE (len2) != INTEGER_CST)
3495 len = len1;
3496 else if (tree_int_cst_lt (len1, len2))
3497 len = len1;
3498 else
3499 len = len2;
3501 /* If both arguments have side effects, we cannot optimize. */
3502 if (!len || TREE_SIDE_EFFECTS (len))
3503 return 0;
3505 /* The actual new length parameter is MIN(len,arg3). */
3506 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3508 /* If we don't have POINTER_TYPE, call the function. */
3509 if (arg1_align == 0 || arg2_align == 0)
3510 return 0;
3512 /* Make a place to write the result of the instruction. */
3513 result = target;
3514 if (! (result != 0
3515 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3516 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3517 result = gen_reg_rtx (insn_mode);
3519 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3520 arg1 = save_expr (arg1);
3521 arg2 = save_expr (arg2);
3522 len = save_expr (len);
3524 arg1_rtx = get_memory_rtx (arg1);
3525 arg2_rtx = get_memory_rtx (arg2);
3526 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3527 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3528 GEN_INT (MIN (arg1_align, arg2_align)));
3529 if (insn)
3531 emit_insn (insn);
3533 /* Return the value in the proper mode for this function. */
3534 mode = TYPE_MODE (TREE_TYPE (exp));
3535 if (GET_MODE (result) == mode)
3536 return result;
3537 if (target == 0)
3538 return convert_to_mode (mode, result, 0);
3539 convert_move (target, result, 0);
3540 return target;
3543 /* Expand the library call ourselves using a stabilized argument
3544 list to avoid re-evaluating the function's arguments twice. */
3545 arglist = build_tree_list (NULL_TREE, len);
3546 arglist = tree_cons (NULL_TREE, arg2, arglist);
3547 arglist = tree_cons (NULL_TREE, arg1, arglist);
3548 fndecl = get_callee_fndecl (exp);
3549 exp = build_function_call_expr (fndecl, arglist);
3550 return expand_call (exp, target, target == const0_rtx);
3552 #endif
3553 return 0;
3556 /* Expand expression EXP, which is a call to the strcat builtin.
3557 Return 0 if we failed the caller should emit a normal call,
3558 otherwise try to get the result in TARGET, if convenient. */
3560 static rtx
3561 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3563 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3564 return 0;
3565 else
3567 tree dst = TREE_VALUE (arglist),
3568 src = TREE_VALUE (TREE_CHAIN (arglist));
3569 const char *p = c_getstr (src);
3571 if (p)
3573 /* If the string length is zero, return the dst parameter. */
3574 if (*p == '\0')
3575 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3576 else if (!optimize_size)
3578 /* Otherwise if !optimize_size, see if we can store by
3579 pieces into (dst + strlen(dst)). */
3580 tree newdst, arglist,
3581 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3583 /* This is the length argument. */
3584 arglist = build_tree_list (NULL_TREE,
3585 fold (size_binop (PLUS_EXPR,
3586 c_strlen (src, 0),
3587 ssize_int (1))));
3588 /* Prepend src argument. */
3589 arglist = tree_cons (NULL_TREE, src, arglist);
3591 /* We're going to use dst more than once. */
3592 dst = save_expr (dst);
3594 /* Create strlen (dst). */
3595 newdst =
3596 fold (build_function_call_expr (strlen_fn,
3597 build_tree_list (NULL_TREE,
3598 dst)));
3599 /* Create (dst + strlen (dst)). */
3600 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3602 /* Prepend the new dst argument. */
3603 arglist = tree_cons (NULL_TREE, newdst, arglist);
3605 /* We don't want to get turned into a memcpy if the
3606 target is const0_rtx, i.e. when the return value
3607 isn't used. That would produce pessimized code so
3608 pass in a target of zero, it should never actually be
3609 used. If this was successful return the original
3610 dst, not the result of mempcpy. */
3611 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3612 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3613 else
3614 return 0;
3618 return 0;
3622 /* Expand expression EXP, which is a call to the strncat builtin.
3623 Return 0 if we failed the caller should emit a normal call,
3624 otherwise try to get the result in TARGET, if convenient. */
3626 static rtx
3627 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3629 if (!validate_arglist (arglist,
3630 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3631 return 0;
3632 else
3634 tree dst = TREE_VALUE (arglist),
3635 src = TREE_VALUE (TREE_CHAIN (arglist)),
3636 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3637 const char *p = c_getstr (src);
3639 /* If the requested length is zero, or the src parameter string
3640 length is zero, return the dst parameter. */
3641 if (integer_zerop (len) || (p && *p == '\0'))
3643 /* Evaluate and ignore the src and len parameters in case
3644 they have side-effects. */
3645 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3646 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3647 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3650 /* If the requested len is greater than or equal to the string
3651 length, call strcat. */
3652 if (TREE_CODE (len) == INTEGER_CST && p
3653 && compare_tree_int (len, strlen (p)) >= 0)
3655 tree newarglist
3656 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3657 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3659 /* If the replacement _DECL isn't initialized, don't do the
3660 transformation. */
3661 if (!fn)
3662 return 0;
3664 return expand_expr (build_function_call_expr (fn, newarglist),
3665 target, mode, EXPAND_NORMAL);
3667 return 0;
3671 /* Expand expression EXP, which is a call to the strspn builtin.
3672 Return 0 if we failed the caller should emit a normal call,
3673 otherwise try to get the result in TARGET, if convenient. */
3675 static rtx
3676 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3678 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3679 return 0;
3680 else
3682 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3683 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3685 /* If both arguments are constants, evaluate at compile-time. */
3686 if (p1 && p2)
3688 const size_t r = strspn (p1, p2);
3689 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3692 /* If either argument is "", return 0. */
3693 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3695 /* Evaluate and ignore both arguments in case either one has
3696 side-effects. */
3697 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3698 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3699 return const0_rtx;
3701 return 0;
3705 /* Expand expression EXP, which is a call to the strcspn builtin.
3706 Return 0 if we failed the caller should emit a normal call,
3707 otherwise try to get the result in TARGET, if convenient. */
3709 static rtx
3710 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3712 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3713 return 0;
3714 else
3716 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3717 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3719 /* If both arguments are constants, evaluate at compile-time. */
3720 if (p1 && p2)
3722 const size_t r = strcspn (p1, p2);
3723 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3726 /* If the first argument is "", return 0. */
3727 if (p1 && *p1 == '\0')
3729 /* Evaluate and ignore argument s2 in case it has
3730 side-effects. */
3731 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3732 return const0_rtx;
3735 /* If the second argument is "", return __builtin_strlen(s1). */
3736 if (p2 && *p2 == '\0')
3738 tree newarglist = build_tree_list (NULL_TREE, s1),
3739 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3741 /* If the replacement _DECL isn't initialized, don't do the
3742 transformation. */
3743 if (!fn)
3744 return 0;
3746 return expand_expr (build_function_call_expr (fn, newarglist),
3747 target, mode, EXPAND_NORMAL);
3749 return 0;
3753 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3754 if that's convenient. */
3757 expand_builtin_saveregs (void)
3759 rtx val, seq;
3761 /* Don't do __builtin_saveregs more than once in a function.
3762 Save the result of the first call and reuse it. */
3763 if (saveregs_value != 0)
3764 return saveregs_value;
3766 /* When this function is called, it means that registers must be
3767 saved on entry to this function. So we migrate the call to the
3768 first insn of this function. */
3770 start_sequence ();
3772 /* Do whatever the machine needs done in this case. */
3773 val = targetm.calls.expand_builtin_saveregs ();
3775 seq = get_insns ();
3776 end_sequence ();
3778 saveregs_value = val;
3780 /* Put the insns after the NOTE that starts the function. If this
3781 is inside a start_sequence, make the outer-level insn chain current, so
3782 the code is placed at the start of the function. */
3783 push_topmost_sequence ();
3784 emit_insn_after (seq, get_insns ());
3785 pop_topmost_sequence ();
3787 return val;
3790 /* __builtin_args_info (N) returns word N of the arg space info
3791 for the current function. The number and meanings of words
3792 is controlled by the definition of CUMULATIVE_ARGS. */
3794 static rtx
3795 expand_builtin_args_info (tree arglist)
3797 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3798 int *word_ptr = (int *) &current_function_args_info;
3800 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3801 abort ();
3803 if (arglist != 0)
3805 if (!host_integerp (TREE_VALUE (arglist), 0))
3806 error ("argument of `__builtin_args_info' must be constant");
3807 else
3809 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3811 if (wordnum < 0 || wordnum >= nwords)
3812 error ("argument of `__builtin_args_info' out of range");
3813 else
3814 return GEN_INT (word_ptr[wordnum]);
3817 else
3818 error ("missing argument in `__builtin_args_info'");
3820 return const0_rtx;
3823 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3825 static rtx
3826 expand_builtin_next_arg (tree arglist)
3828 tree fntype = TREE_TYPE (current_function_decl);
3830 if (TYPE_ARG_TYPES (fntype) == 0
3831 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3832 == void_type_node))
3834 error ("`va_start' used in function with fixed args");
3835 return const0_rtx;
3838 if (arglist)
3840 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3841 tree arg = TREE_VALUE (arglist);
3843 /* Strip off all nops for the sake of the comparison. This
3844 is not quite the same as STRIP_NOPS. It does more.
3845 We must also strip off INDIRECT_EXPR for C++ reference
3846 parameters. */
3847 while (TREE_CODE (arg) == NOP_EXPR
3848 || TREE_CODE (arg) == CONVERT_EXPR
3849 || TREE_CODE (arg) == NON_LVALUE_EXPR
3850 || TREE_CODE (arg) == INDIRECT_REF)
3851 arg = TREE_OPERAND (arg, 0);
3852 if (arg != last_parm)
3853 warning ("second parameter of `va_start' not last named argument");
3855 else
3856 /* Evidently an out of date version of <stdarg.h>; can't validate
3857 va_start's second argument, but can still work as intended. */
3858 warning ("`__builtin_next_arg' called without an argument");
3860 return expand_binop (Pmode, add_optab,
3861 current_function_internal_arg_pointer,
3862 current_function_arg_offset_rtx,
3863 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3866 /* Make it easier for the backends by protecting the valist argument
3867 from multiple evaluations. */
3869 static tree
3870 stabilize_va_list (tree valist, int needs_lvalue)
3872 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3874 if (TREE_SIDE_EFFECTS (valist))
3875 valist = save_expr (valist);
3877 /* For this case, the backends will be expecting a pointer to
3878 TREE_TYPE (va_list_type_node), but it's possible we've
3879 actually been given an array (an actual va_list_type_node).
3880 So fix it. */
3881 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3883 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3884 tree p2 = build_pointer_type (va_list_type_node);
3886 valist = build1 (ADDR_EXPR, p2, valist);
3887 valist = fold (build1 (NOP_EXPR, p1, valist));
3890 else
3892 tree pt;
3894 if (! needs_lvalue)
3896 if (! TREE_SIDE_EFFECTS (valist))
3897 return valist;
3899 pt = build_pointer_type (va_list_type_node);
3900 valist = fold (build1 (ADDR_EXPR, pt, valist));
3901 TREE_SIDE_EFFECTS (valist) = 1;
3904 if (TREE_SIDE_EFFECTS (valist))
3905 valist = save_expr (valist);
3906 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3907 valist));
3910 return valist;
3913 /* The "standard" definition of va_list is void*. */
3915 tree
3916 std_build_builtin_va_list (void)
3918 return ptr_type_node;
3921 /* The "standard" implementation of va_start: just assign `nextarg' to
3922 the variable. */
3924 void
3925 std_expand_builtin_va_start (tree valist, rtx nextarg)
3927 tree t;
3929 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3930 make_tree (ptr_type_node, nextarg));
3931 TREE_SIDE_EFFECTS (t) = 1;
3933 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3936 /* Expand ARGLIST, from a call to __builtin_va_start. */
3938 static rtx
3939 expand_builtin_va_start (tree arglist)
3941 rtx nextarg;
3942 tree chain, valist;
3944 chain = TREE_CHAIN (arglist);
3946 if (TREE_CHAIN (chain))
3947 error ("too many arguments to function `va_start'");
3949 nextarg = expand_builtin_next_arg (chain);
3950 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3952 #ifdef EXPAND_BUILTIN_VA_START
3953 EXPAND_BUILTIN_VA_START (valist, nextarg);
3954 #else
3955 std_expand_builtin_va_start (valist, nextarg);
3956 #endif
3958 return const0_rtx;
3961 /* The "standard" implementation of va_arg: read the value from the
3962 current (padded) address and increment by the (padded) size. */
3965 std_expand_builtin_va_arg (tree valist, tree type)
3967 tree addr_tree, t, type_size = NULL;
3968 tree align, alignm1;
3969 tree rounded_size;
3970 rtx addr;
3972 /* Compute the rounded size of the type. */
3973 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3974 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3975 if (type == error_mark_node
3976 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3977 || TREE_OVERFLOW (type_size))
3978 rounded_size = size_zero_node;
3979 else
3980 rounded_size = fold (build (MULT_EXPR, sizetype,
3981 fold (build (TRUNC_DIV_EXPR, sizetype,
3982 fold (build (PLUS_EXPR, sizetype,
3983 type_size, alignm1)),
3984 align)),
3985 align));
3987 /* Get AP. */
3988 addr_tree = valist;
3989 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3991 /* Small args are padded downward. */
3992 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3993 fold (build (COND_EXPR, sizetype,
3994 fold (build (GT_EXPR, sizetype,
3995 rounded_size,
3996 align)),
3997 size_zero_node,
3998 fold (build (MINUS_EXPR, sizetype,
3999 rounded_size,
4000 type_size))))));
4003 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4004 addr = copy_to_reg (addr);
4006 /* Compute new value for AP. */
4007 if (! integer_zerop (rounded_size))
4009 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4010 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4011 rounded_size));
4012 TREE_SIDE_EFFECTS (t) = 1;
4013 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4016 return addr;
4019 /* Expand __builtin_va_arg, which is not really a builtin function, but
4020 a very special sort of operator. */
4023 expand_builtin_va_arg (tree valist, tree type)
4025 rtx addr, result;
4026 tree promoted_type, want_va_type, have_va_type;
4028 /* Verify that valist is of the proper type. */
4030 want_va_type = va_list_type_node;
4031 have_va_type = TREE_TYPE (valist);
4032 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4034 /* If va_list is an array type, the argument may have decayed
4035 to a pointer type, e.g. by being passed to another function.
4036 In that case, unwrap both types so that we can compare the
4037 underlying records. */
4038 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4039 || TREE_CODE (have_va_type) == POINTER_TYPE)
4041 want_va_type = TREE_TYPE (want_va_type);
4042 have_va_type = TREE_TYPE (have_va_type);
4045 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4047 error ("first argument to `va_arg' not of type `va_list'");
4048 addr = const0_rtx;
4051 /* Generate a diagnostic for requesting data of a type that cannot
4052 be passed through `...' due to type promotion at the call site. */
4053 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4054 != type)
4056 const char *name = "<anonymous type>", *pname = 0;
4057 static bool gave_help;
4059 if (TYPE_NAME (type))
4061 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4062 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4063 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4064 && DECL_NAME (TYPE_NAME (type)))
4065 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4067 if (TYPE_NAME (promoted_type))
4069 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4070 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4071 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4072 && DECL_NAME (TYPE_NAME (promoted_type)))
4073 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4076 /* Unfortunately, this is merely undefined, rather than a constraint
4077 violation, so we cannot make this an error. If this call is never
4078 executed, the program is still strictly conforming. */
4079 warning ("`%s' is promoted to `%s' when passed through `...'",
4080 name, pname);
4081 if (! gave_help)
4083 gave_help = true;
4084 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4085 pname, name);
4088 /* We can, however, treat "undefined" any way we please.
4089 Call abort to encourage the user to fix the program. */
4090 expand_builtin_trap ();
4092 /* This is dead code, but go ahead and finish so that the
4093 mode of the result comes out right. */
4094 addr = const0_rtx;
4096 else
4098 /* Make it easier for the backends by protecting the valist argument
4099 from multiple evaluations. */
4100 valist = stabilize_va_list (valist, 0);
4102 #ifdef EXPAND_BUILTIN_VA_ARG
4103 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4104 #else
4105 addr = std_expand_builtin_va_arg (valist, type);
4106 #endif
4109 addr = convert_memory_address (Pmode, addr);
4111 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4112 set_mem_alias_set (result, get_varargs_alias_set ());
4114 return result;
4117 /* Expand ARGLIST, from a call to __builtin_va_end. */
4119 static rtx
4120 expand_builtin_va_end (tree arglist)
4122 tree valist = TREE_VALUE (arglist);
4124 #ifdef EXPAND_BUILTIN_VA_END
4125 valist = stabilize_va_list (valist, 0);
4126 EXPAND_BUILTIN_VA_END (arglist);
4127 #else
4128 /* Evaluate for side effects, if needed. I hate macros that don't
4129 do that. */
4130 if (TREE_SIDE_EFFECTS (valist))
4131 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4132 #endif
4134 return const0_rtx;
4137 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4138 builtin rather than just as an assignment in stdarg.h because of the
4139 nastiness of array-type va_list types. */
4141 static rtx
4142 expand_builtin_va_copy (tree arglist)
4144 tree dst, src, t;
4146 dst = TREE_VALUE (arglist);
4147 src = TREE_VALUE (TREE_CHAIN (arglist));
4149 dst = stabilize_va_list (dst, 1);
4150 src = stabilize_va_list (src, 0);
4152 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4154 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4155 TREE_SIDE_EFFECTS (t) = 1;
4156 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4158 else
4160 rtx dstb, srcb, size;
4162 /* Evaluate to pointers. */
4163 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4164 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4165 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4166 VOIDmode, EXPAND_NORMAL);
4168 dstb = convert_memory_address (Pmode, dstb);
4169 srcb = convert_memory_address (Pmode, srcb);
4171 /* "Dereference" to BLKmode memories. */
4172 dstb = gen_rtx_MEM (BLKmode, dstb);
4173 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4174 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4175 srcb = gen_rtx_MEM (BLKmode, srcb);
4176 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4177 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4179 /* Copy. */
4180 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4183 return const0_rtx;
4186 /* Expand a call to one of the builtin functions __builtin_frame_address or
4187 __builtin_return_address. */
4189 static rtx
4190 expand_builtin_frame_address (tree fndecl, tree arglist)
4192 /* The argument must be a nonnegative integer constant.
4193 It counts the number of frames to scan up the stack.
4194 The value is the return address saved in that frame. */
4195 if (arglist == 0)
4196 /* Warning about missing arg was already issued. */
4197 return const0_rtx;
4198 else if (! host_integerp (TREE_VALUE (arglist), 1))
4200 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4201 error ("invalid arg to `__builtin_frame_address'");
4202 else
4203 error ("invalid arg to `__builtin_return_address'");
4204 return const0_rtx;
4206 else
4208 rtx tem
4209 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4210 tree_low_cst (TREE_VALUE (arglist), 1),
4211 hard_frame_pointer_rtx);
4213 /* Some ports cannot access arbitrary stack frames. */
4214 if (tem == NULL)
4216 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4217 warning ("unsupported arg to `__builtin_frame_address'");
4218 else
4219 warning ("unsupported arg to `__builtin_return_address'");
4220 return const0_rtx;
4223 /* For __builtin_frame_address, return what we've got. */
4224 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4225 return tem;
4227 if (GET_CODE (tem) != REG
4228 && ! CONSTANT_P (tem))
4229 tem = copy_to_mode_reg (Pmode, tem);
4230 return tem;
4234 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4235 we failed and the caller should emit a normal call, otherwise try to get
4236 the result in TARGET, if convenient. */
4238 static rtx
4239 expand_builtin_alloca (tree arglist, rtx target)
4241 rtx op0;
4242 rtx result;
4244 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4245 return 0;
4247 /* Compute the argument. */
4248 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4250 /* Allocate the desired space. */
4251 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4252 result = convert_memory_address (ptr_mode, result);
4254 return result;
4257 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4258 Return 0 if a normal call should be emitted rather than expanding the
4259 function in-line. If convenient, the result should be placed in TARGET.
4260 SUBTARGET may be used as the target for computing one of EXP's operands. */
4262 static rtx
4263 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4264 rtx subtarget, optab op_optab)
4266 rtx op0;
4267 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4268 return 0;
4270 /* Compute the argument. */
4271 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4272 /* Compute op, into TARGET if possible.
4273 Set TARGET to wherever the result comes back. */
4274 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4275 op_optab, op0, target, 1);
4276 if (target == 0)
4277 abort ();
4279 return convert_to_mode (target_mode, target, 0);
4282 /* If the string passed to fputs is a constant and is one character
4283 long, we attempt to transform this call into __builtin_fputc(). */
4285 static rtx
4286 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4288 tree len, fn;
4289 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4290 : implicit_built_in_decls[BUILT_IN_FPUTC];
4291 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4292 : implicit_built_in_decls[BUILT_IN_FWRITE];
4294 /* If the return value is used, or the replacement _DECL isn't
4295 initialized, don't do the transformation. */
4296 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4297 return 0;
4299 /* Verify the arguments in the original call. */
4300 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4301 return 0;
4303 /* Get the length of the string passed to fputs. If the length
4304 can't be determined, punt. */
4305 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4306 || TREE_CODE (len) != INTEGER_CST)
4307 return 0;
4309 switch (compare_tree_int (len, 1))
4311 case -1: /* length is 0, delete the call entirely . */
4313 /* Evaluate and ignore the argument in case it has
4314 side-effects. */
4315 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4316 VOIDmode, EXPAND_NORMAL);
4317 return const0_rtx;
4319 case 0: /* length is 1, call fputc. */
4321 const char *p = c_getstr (TREE_VALUE (arglist));
4323 if (p != NULL)
4325 /* New argument list transforming fputs(string, stream) to
4326 fputc(string[0], stream). */
4327 arglist =
4328 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4329 arglist =
4330 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4331 fn = fn_fputc;
4332 break;
4335 /* FALLTHROUGH */
4336 case 1: /* length is greater than 1, call fwrite. */
4338 tree string_arg;
4340 /* If optimizing for size keep fputs. */
4341 if (optimize_size)
4342 return 0;
4343 string_arg = TREE_VALUE (arglist);
4344 /* New argument list transforming fputs(string, stream) to
4345 fwrite(string, 1, len, stream). */
4346 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4347 arglist = tree_cons (NULL_TREE, len, arglist);
4348 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4349 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4350 fn = fn_fwrite;
4351 break;
4353 default:
4354 abort ();
4357 return expand_expr (build_function_call_expr (fn, arglist),
4358 const0_rtx, VOIDmode, EXPAND_NORMAL);
4361 /* Expand a call to __builtin_expect. We return our argument and emit a
4362 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4363 a non-jump context. */
4365 static rtx
4366 expand_builtin_expect (tree arglist, rtx target)
4368 tree exp, c;
4369 rtx note, rtx_c;
4371 if (arglist == NULL_TREE
4372 || TREE_CHAIN (arglist) == NULL_TREE)
4373 return const0_rtx;
4374 exp = TREE_VALUE (arglist);
4375 c = TREE_VALUE (TREE_CHAIN (arglist));
4377 if (TREE_CODE (c) != INTEGER_CST)
4379 error ("second arg to `__builtin_expect' must be a constant");
4380 c = integer_zero_node;
4383 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4385 /* Don't bother with expected value notes for integral constants. */
4386 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4388 /* We do need to force this into a register so that we can be
4389 moderately sure to be able to correctly interpret the branch
4390 condition later. */
4391 target = force_reg (GET_MODE (target), target);
4393 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4395 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4396 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4399 return target;
4402 /* Like expand_builtin_expect, except do this in a jump context. This is
4403 called from do_jump if the conditional is a __builtin_expect. Return either
4404 a list of insns to emit the jump or NULL if we cannot optimize
4405 __builtin_expect. We need to optimize this at jump time so that machines
4406 like the PowerPC don't turn the test into a SCC operation, and then jump
4407 based on the test being 0/1. */
4410 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4412 tree arglist = TREE_OPERAND (exp, 1);
4413 tree arg0 = TREE_VALUE (arglist);
4414 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4415 rtx ret = NULL_RTX;
4417 /* Only handle __builtin_expect (test, 0) and
4418 __builtin_expect (test, 1). */
4419 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4420 && (integer_zerop (arg1) || integer_onep (arg1)))
4422 int num_jumps = 0;
4423 int save_pending_stack_adjust = pending_stack_adjust;
4424 rtx insn;
4426 /* If we fail to locate an appropriate conditional jump, we'll
4427 fall back to normal evaluation. Ensure that the expression
4428 can be re-evaluated. */
4429 switch (unsafe_for_reeval (arg0))
4431 case 0: /* Safe. */
4432 break;
4434 case 1: /* Mildly unsafe. */
4435 arg0 = unsave_expr (arg0);
4436 break;
4438 case 2: /* Wildly unsafe. */
4439 return NULL_RTX;
4442 /* Expand the jump insns. */
4443 start_sequence ();
4444 do_jump (arg0, if_false_label, if_true_label);
4445 ret = get_insns ();
4446 end_sequence ();
4448 /* Now that the __builtin_expect has been validated, go through and add
4449 the expect's to each of the conditional jumps. If we run into an
4450 error, just give up and generate the 'safe' code of doing a SCC
4451 operation and then doing a branch on that. */
4452 insn = ret;
4453 while (insn != NULL_RTX)
4455 rtx next = NEXT_INSN (insn);
4457 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4459 rtx ifelse = SET_SRC (pc_set (insn));
4460 rtx label;
4461 int taken;
4463 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4465 taken = 1;
4466 label = XEXP (XEXP (ifelse, 1), 0);
4468 /* An inverted jump reverses the probabilities. */
4469 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4471 taken = 0;
4472 label = XEXP (XEXP (ifelse, 2), 0);
4474 /* We shouldn't have to worry about conditional returns during
4475 the expansion stage, but handle it gracefully anyway. */
4476 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4478 taken = 1;
4479 label = NULL_RTX;
4481 /* An inverted return reverses the probabilities. */
4482 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4484 taken = 0;
4485 label = NULL_RTX;
4487 else
4488 goto do_next_insn;
4490 /* If the test is expected to fail, reverse the
4491 probabilities. */
4492 if (integer_zerop (arg1))
4493 taken = 1 - taken;
4495 /* If we are jumping to the false label, reverse the
4496 probabilities. */
4497 if (label == NULL_RTX)
4498 ; /* conditional return */
4499 else if (label == if_false_label)
4500 taken = 1 - taken;
4501 else if (label != if_true_label)
4502 goto do_next_insn;
4504 num_jumps++;
4505 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4508 do_next_insn:
4509 insn = next;
4512 /* If no jumps were modified, fail and do __builtin_expect the normal
4513 way. */
4514 if (num_jumps == 0)
4516 ret = NULL_RTX;
4517 pending_stack_adjust = save_pending_stack_adjust;
4521 return ret;
4524 void
4525 expand_builtin_trap (void)
4527 #ifdef HAVE_trap
4528 if (HAVE_trap)
4529 emit_insn (gen_trap ());
4530 else
4531 #endif
4532 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4533 emit_barrier ();
4536 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4537 Return 0 if a normal call should be emitted rather than expanding
4538 the function inline. If convenient, the result should be placed
4539 in TARGET. SUBTARGET may be used as the target for computing
4540 the operand. */
4542 static rtx
4543 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4545 enum machine_mode mode;
4546 tree arg;
4547 rtx op0;
4549 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4550 return 0;
4552 arg = TREE_VALUE (arglist);
4553 mode = TYPE_MODE (TREE_TYPE (arg));
4554 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4555 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4558 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4559 Return 0 if a normal call should be emitted rather than expanding
4560 the function inline. If convenient, the result should be placed
4561 in target. */
4563 static rtx
4564 expand_builtin_cabs (tree arglist, rtx target)
4566 enum machine_mode mode;
4567 tree arg;
4568 rtx op0;
4570 if (arglist == 0 || TREE_CHAIN (arglist))
4571 return 0;
4572 arg = TREE_VALUE (arglist);
4573 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4574 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4575 return 0;
4577 mode = TYPE_MODE (TREE_TYPE (arg));
4578 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4579 return expand_complex_abs (mode, op0, target, 0);
4582 /* Create a new constant string literal and return a char* pointer to it.
4583 The STRING_CST value is the LEN characters at STR. */
4584 static tree
4585 build_string_literal (int len, const char *str)
4587 tree t, elem, index, type;
4589 t = build_string (len, str);
4590 elem = build_type_variant (char_type_node, 1, 0);
4591 index = build_index_type (build_int_2 (len - 1, 0));
4592 type = build_array_type (elem, index);
4593 TREE_TYPE (t) = type;
4594 TREE_CONSTANT (t) = 1;
4595 TREE_READONLY (t) = 1;
4596 TREE_STATIC (t) = 1;
4598 type = build_pointer_type (type);
4599 t = build1 (ADDR_EXPR, type, t);
4601 type = build_pointer_type (elem);
4602 t = build1 (NOP_EXPR, type, t);
4603 return t;
4606 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4607 Return 0 if a normal call should be emitted rather than transforming
4608 the function inline. If convenient, the result should be placed in
4609 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4610 call. */
4611 static rtx
4612 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4613 bool unlocked)
4615 tree fn_putchar = unlocked
4616 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4617 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4618 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4619 : implicit_built_in_decls[BUILT_IN_PUTS];
4620 const char *fmt_str;
4621 tree fn, fmt, arg;
4623 /* If the return value is used, don't do the transformation. */
4624 if (target != const0_rtx)
4625 return 0;
4627 /* Verify the required arguments in the original call. */
4628 if (! arglist)
4629 return 0;
4630 fmt = TREE_VALUE (arglist);
4631 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4632 return 0;
4633 arglist = TREE_CHAIN (arglist);
4635 /* Check whether the format is a literal string constant. */
4636 fmt_str = c_getstr (fmt);
4637 if (fmt_str == NULL)
4638 return 0;
4640 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4641 if (strcmp (fmt_str, "%s\n") == 0)
4643 if (! arglist
4644 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4645 || TREE_CHAIN (arglist))
4646 return 0;
4647 fn = fn_puts;
4649 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4650 else if (strcmp (fmt_str, "%c") == 0)
4652 if (! arglist
4653 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4654 || TREE_CHAIN (arglist))
4655 return 0;
4656 fn = fn_putchar;
4658 else
4660 /* We can't handle anything else with % args or %% ... yet. */
4661 if (strchr (fmt_str, '%'))
4662 return 0;
4664 if (arglist)
4665 return 0;
4667 /* If the format specifier was "", printf does nothing. */
4668 if (fmt_str[0] == '\0')
4669 return const0_rtx;
4670 /* If the format specifier has length of 1, call putchar. */
4671 if (fmt_str[1] == '\0')
4673 /* Given printf("c"), (where c is any one character,)
4674 convert "c"[0] to an int and pass that to the replacement
4675 function. */
4676 arg = build_int_2 (fmt_str[0], 0);
4677 arglist = build_tree_list (NULL_TREE, arg);
4678 fn = fn_putchar;
4680 else
4682 /* If the format specifier was "string\n", call puts("string"). */
4683 size_t len = strlen (fmt_str);
4684 if (fmt_str[len - 1] == '\n')
4686 /* Create a NUL-terminated string that's one char shorter
4687 than the original, stripping off the trailing '\n'. */
4688 char *newstr = (char *) alloca (len);
4689 memcpy (newstr, fmt_str, len - 1);
4690 newstr[len - 1] = 0;
4692 arg = build_string_literal (len, newstr);
4693 arglist = build_tree_list (NULL_TREE, arg);
4694 fn = fn_puts;
4696 else
4697 /* We'd like to arrange to call fputs(string,stdout) here,
4698 but we need stdout and don't have a way to get it yet. */
4699 return 0;
4703 if (!fn)
4704 return 0;
4705 return expand_expr (build_function_call_expr (fn, arglist),
4706 target, mode, EXPAND_NORMAL);
4709 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4710 Return 0 if a normal call should be emitted rather than transforming
4711 the function inline. If convenient, the result should be placed in
4712 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4713 call. */
4714 static rtx
4715 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4716 bool unlocked)
4718 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4719 : implicit_built_in_decls[BUILT_IN_FPUTC];
4720 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4721 : implicit_built_in_decls[BUILT_IN_FPUTS];
4722 const char *fmt_str;
4723 tree fn, fmt, fp, arg;
4725 /* If the return value is used, don't do the transformation. */
4726 if (target != const0_rtx)
4727 return 0;
4729 /* Verify the required arguments in the original call. */
4730 if (! arglist)
4731 return 0;
4732 fp = TREE_VALUE (arglist);
4733 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4734 return 0;
4735 arglist = TREE_CHAIN (arglist);
4736 if (! arglist)
4737 return 0;
4738 fmt = TREE_VALUE (arglist);
4739 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4740 return 0;
4741 arglist = TREE_CHAIN (arglist);
4743 /* Check whether the format is a literal string constant. */
4744 fmt_str = c_getstr (fmt);
4745 if (fmt_str == NULL)
4746 return 0;
4748 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4749 if (strcmp (fmt_str, "%s") == 0)
4751 if (! arglist
4752 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4753 || TREE_CHAIN (arglist))
4754 return 0;
4755 arg = TREE_VALUE (arglist);
4756 arglist = build_tree_list (NULL_TREE, fp);
4757 arglist = tree_cons (NULL_TREE, arg, arglist);
4758 fn = fn_fputs;
4760 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4761 else if (strcmp (fmt_str, "%c") == 0)
4763 if (! arglist
4764 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4765 || TREE_CHAIN (arglist))
4766 return 0;
4767 arg = TREE_VALUE (arglist);
4768 arglist = build_tree_list (NULL_TREE, fp);
4769 arglist = tree_cons (NULL_TREE, arg, arglist);
4770 fn = fn_fputc;
4772 else
4774 /* We can't handle anything else with % args or %% ... yet. */
4775 if (strchr (fmt_str, '%'))
4776 return 0;
4778 if (arglist)
4779 return 0;
4781 /* If the format specifier was "", fprintf does nothing. */
4782 if (fmt_str[0] == '\0')
4784 /* Evaluate and ignore FILE* argument for side-effects. */
4785 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4786 return const0_rtx;
4789 /* When "string" doesn't contain %, replace all cases of
4790 fprintf(stream,string) with fputs(string,stream). The fputs
4791 builtin will take care of special cases like length == 1. */
4792 arglist = build_tree_list (NULL_TREE, fp);
4793 arglist = tree_cons (NULL_TREE, fmt, arglist);
4794 fn = fn_fputs;
4797 if (!fn)
4798 return 0;
4799 return expand_expr (build_function_call_expr (fn, arglist),
4800 target, mode, EXPAND_NORMAL);
4803 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4804 a normal call should be emitted rather than expanding the function
4805 inline. If convenient, the result should be placed in TARGET with
4806 mode MODE. */
4808 static rtx
4809 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4811 tree orig_arglist, dest, fmt;
4812 const char *fmt_str;
4814 orig_arglist = arglist;
4816 /* Verify the required arguments in the original call. */
4817 if (! arglist)
4818 return 0;
4819 dest = TREE_VALUE (arglist);
4820 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4821 return 0;
4822 arglist = TREE_CHAIN (arglist);
4823 if (! arglist)
4824 return 0;
4825 fmt = TREE_VALUE (arglist);
4826 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4827 return 0;
4828 arglist = TREE_CHAIN (arglist);
4830 /* Check whether the format is a literal string constant. */
4831 fmt_str = c_getstr (fmt);
4832 if (fmt_str == NULL)
4833 return 0;
4835 /* If the format doesn't contain % args or %%, use strcpy. */
4836 if (strchr (fmt_str, '%') == 0)
4838 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4839 tree exp;
4841 if (arglist || ! fn)
4842 return 0;
4843 expand_expr (build_function_call_expr (fn, orig_arglist),
4844 const0_rtx, VOIDmode, EXPAND_NORMAL);
4845 if (target == const0_rtx)
4846 return const0_rtx;
4847 exp = build_int_2 (strlen (fmt_str), 0);
4848 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4849 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4851 /* If the format is "%s", use strcpy if the result isn't used. */
4852 else if (strcmp (fmt_str, "%s") == 0)
4854 tree fn, arg, len;
4855 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4857 if (! fn)
4858 return 0;
4860 if (! arglist || TREE_CHAIN (arglist))
4861 return 0;
4862 arg = TREE_VALUE (arglist);
4863 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4864 return 0;
4866 if (target != const0_rtx)
4868 len = c_strlen (arg, 1);
4869 if (! len || TREE_CODE (len) != INTEGER_CST)
4870 return 0;
4872 else
4873 len = NULL_TREE;
4875 arglist = build_tree_list (NULL_TREE, arg);
4876 arglist = tree_cons (NULL_TREE, dest, arglist);
4877 expand_expr (build_function_call_expr (fn, arglist),
4878 const0_rtx, VOIDmode, EXPAND_NORMAL);
4880 if (target == const0_rtx)
4881 return const0_rtx;
4882 return expand_expr (len, target, mode, EXPAND_NORMAL);
4885 return 0;
4888 /* Expand an expression EXP that calls a built-in function,
4889 with result going to TARGET if that's convenient
4890 (and in mode MODE if that's convenient).
4891 SUBTARGET may be used as the target for computing one of EXP's operands.
4892 IGNORE is nonzero if the value is to be ignored. */
4895 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4896 int ignore)
4898 tree fndecl = get_callee_fndecl (exp);
4899 tree arglist = TREE_OPERAND (exp, 1);
4900 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4901 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4903 /* Perform postincrements before expanding builtin functions. */
4904 emit_queue ();
4906 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4907 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4909 /* When not optimizing, generate calls to library functions for a certain
4910 set of builtins. */
4911 if (!optimize
4912 && !CALLED_AS_BUILT_IN (fndecl)
4913 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
4914 && fcode != BUILT_IN_ALLOCA)
4915 return expand_call (exp, target, ignore);
4917 /* The built-in function expanders test for target == const0_rtx
4918 to determine whether the function's result will be ignored. */
4919 if (ignore)
4920 target = const0_rtx;
4922 /* If the result of a pure or const built-in function is ignored, and
4923 none of its arguments are volatile, we can avoid expanding the
4924 built-in call and just evaluate the arguments for side-effects. */
4925 if (target == const0_rtx
4926 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4928 bool volatilep = false;
4929 tree arg;
4931 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4932 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4934 volatilep = true;
4935 break;
4938 if (! volatilep)
4940 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4941 expand_expr (TREE_VALUE (arg), const0_rtx,
4942 VOIDmode, EXPAND_NORMAL);
4943 return const0_rtx;
4947 switch (fcode)
4949 case BUILT_IN_ABS:
4950 case BUILT_IN_LABS:
4951 case BUILT_IN_LLABS:
4952 case BUILT_IN_IMAXABS:
4953 /* build_function_call changes these into ABS_EXPR. */
4954 abort ();
4956 case BUILT_IN_FABS:
4957 case BUILT_IN_FABSF:
4958 case BUILT_IN_FABSL:
4959 target = expand_builtin_fabs (arglist, target, subtarget);
4960 if (target)
4961 return target;
4962 break;
4964 case BUILT_IN_CABS:
4965 case BUILT_IN_CABSF:
4966 case BUILT_IN_CABSL:
4967 if (flag_unsafe_math_optimizations)
4969 target = expand_builtin_cabs (arglist, target);
4970 if (target)
4971 return target;
4973 break;
4975 case BUILT_IN_CONJ:
4976 case BUILT_IN_CONJF:
4977 case BUILT_IN_CONJL:
4978 case BUILT_IN_CREAL:
4979 case BUILT_IN_CREALF:
4980 case BUILT_IN_CREALL:
4981 case BUILT_IN_CIMAG:
4982 case BUILT_IN_CIMAGF:
4983 case BUILT_IN_CIMAGL:
4984 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4985 and IMAGPART_EXPR. */
4986 abort ();
4988 case BUILT_IN_SIN:
4989 case BUILT_IN_SINF:
4990 case BUILT_IN_SINL:
4991 case BUILT_IN_COS:
4992 case BUILT_IN_COSF:
4993 case BUILT_IN_COSL:
4994 case BUILT_IN_EXP:
4995 case BUILT_IN_EXPF:
4996 case BUILT_IN_EXPL:
4997 case BUILT_IN_LOG:
4998 case BUILT_IN_LOGF:
4999 case BUILT_IN_LOGL:
5000 case BUILT_IN_TAN:
5001 case BUILT_IN_TANF:
5002 case BUILT_IN_TANL:
5003 case BUILT_IN_ATAN:
5004 case BUILT_IN_ATANF:
5005 case BUILT_IN_ATANL:
5006 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5007 because of possible accuracy problems. */
5008 if (! flag_unsafe_math_optimizations)
5009 break;
5010 case BUILT_IN_SQRT:
5011 case BUILT_IN_SQRTF:
5012 case BUILT_IN_SQRTL:
5013 case BUILT_IN_FLOOR:
5014 case BUILT_IN_FLOORF:
5015 case BUILT_IN_FLOORL:
5016 case BUILT_IN_CEIL:
5017 case BUILT_IN_CEILF:
5018 case BUILT_IN_CEILL:
5019 case BUILT_IN_TRUNC:
5020 case BUILT_IN_TRUNCF:
5021 case BUILT_IN_TRUNCL:
5022 case BUILT_IN_ROUND:
5023 case BUILT_IN_ROUNDF:
5024 case BUILT_IN_ROUNDL:
5025 case BUILT_IN_NEARBYINT:
5026 case BUILT_IN_NEARBYINTF:
5027 case BUILT_IN_NEARBYINTL:
5028 target = expand_builtin_mathfn (exp, target, subtarget);
5029 if (target)
5030 return target;
5031 break;
5033 case BUILT_IN_POW:
5034 case BUILT_IN_POWF:
5035 case BUILT_IN_POWL:
5036 if (! flag_unsafe_math_optimizations)
5037 break;
5038 target = expand_builtin_pow (exp, target, subtarget);
5039 if (target)
5040 return target;
5041 break;
5043 case BUILT_IN_ATAN2:
5044 case BUILT_IN_ATAN2F:
5045 case BUILT_IN_ATAN2L:
5046 if (! flag_unsafe_math_optimizations)
5047 break;
5048 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5049 if (target)
5050 return target;
5051 break;
5053 case BUILT_IN_APPLY_ARGS:
5054 return expand_builtin_apply_args ();
5056 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5057 FUNCTION with a copy of the parameters described by
5058 ARGUMENTS, and ARGSIZE. It returns a block of memory
5059 allocated on the stack into which is stored all the registers
5060 that might possibly be used for returning the result of a
5061 function. ARGUMENTS is the value returned by
5062 __builtin_apply_args. ARGSIZE is the number of bytes of
5063 arguments that must be copied. ??? How should this value be
5064 computed? We'll also need a safe worst case value for varargs
5065 functions. */
5066 case BUILT_IN_APPLY:
5067 if (!validate_arglist (arglist, POINTER_TYPE,
5068 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5069 && !validate_arglist (arglist, REFERENCE_TYPE,
5070 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5071 return const0_rtx;
5072 else
5074 int i;
5075 tree t;
5076 rtx ops[3];
5078 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5079 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5081 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5084 /* __builtin_return (RESULT) causes the function to return the
5085 value described by RESULT. RESULT is address of the block of
5086 memory returned by __builtin_apply. */
5087 case BUILT_IN_RETURN:
5088 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5089 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5090 NULL_RTX, VOIDmode, 0));
5091 return const0_rtx;
5093 case BUILT_IN_SAVEREGS:
5094 return expand_builtin_saveregs ();
5096 case BUILT_IN_ARGS_INFO:
5097 return expand_builtin_args_info (arglist);
5099 /* Return the address of the first anonymous stack arg. */
5100 case BUILT_IN_NEXT_ARG:
5101 return expand_builtin_next_arg (arglist);
5103 case BUILT_IN_CLASSIFY_TYPE:
5104 return expand_builtin_classify_type (arglist);
5106 case BUILT_IN_CONSTANT_P:
5107 return expand_builtin_constant_p (arglist, target_mode);
5109 case BUILT_IN_FRAME_ADDRESS:
5110 case BUILT_IN_RETURN_ADDRESS:
5111 return expand_builtin_frame_address (fndecl, arglist);
5113 /* Returns the address of the area where the structure is returned.
5114 0 otherwise. */
5115 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5116 if (arglist != 0
5117 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5118 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5119 return const0_rtx;
5120 else
5121 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5123 case BUILT_IN_ALLOCA:
5124 target = expand_builtin_alloca (arglist, target);
5125 if (target)
5126 return target;
5127 break;
5129 case BUILT_IN_FFS:
5130 case BUILT_IN_FFSL:
5131 case BUILT_IN_FFSLL:
5132 target = expand_builtin_unop (target_mode, arglist, target,
5133 subtarget, ffs_optab);
5134 if (target)
5135 return target;
5136 break;
5138 case BUILT_IN_CLZ:
5139 case BUILT_IN_CLZL:
5140 case BUILT_IN_CLZLL:
5141 target = expand_builtin_unop (target_mode, arglist, target,
5142 subtarget, clz_optab);
5143 if (target)
5144 return target;
5145 break;
5147 case BUILT_IN_CTZ:
5148 case BUILT_IN_CTZL:
5149 case BUILT_IN_CTZLL:
5150 target = expand_builtin_unop (target_mode, arglist, target,
5151 subtarget, ctz_optab);
5152 if (target)
5153 return target;
5154 break;
5156 case BUILT_IN_POPCOUNT:
5157 case BUILT_IN_POPCOUNTL:
5158 case BUILT_IN_POPCOUNTLL:
5159 target = expand_builtin_unop (target_mode, arglist, target,
5160 subtarget, popcount_optab);
5161 if (target)
5162 return target;
5163 break;
5165 case BUILT_IN_PARITY:
5166 case BUILT_IN_PARITYL:
5167 case BUILT_IN_PARITYLL:
5168 target = expand_builtin_unop (target_mode, arglist, target,
5169 subtarget, parity_optab);
5170 if (target)
5171 return target;
5172 break;
5174 case BUILT_IN_STRLEN:
5175 target = expand_builtin_strlen (arglist, target, target_mode);
5176 if (target)
5177 return target;
5178 break;
5180 case BUILT_IN_STRCPY:
5181 target = expand_builtin_strcpy (arglist, target, mode);
5182 if (target)
5183 return target;
5184 break;
5186 case BUILT_IN_STRNCPY:
5187 target = expand_builtin_strncpy (arglist, target, mode);
5188 if (target)
5189 return target;
5190 break;
5192 case BUILT_IN_STPCPY:
5193 target = expand_builtin_stpcpy (arglist, target, mode);
5194 if (target)
5195 return target;
5196 break;
5198 case BUILT_IN_STRCAT:
5199 target = expand_builtin_strcat (arglist, target, mode);
5200 if (target)
5201 return target;
5202 break;
5204 case BUILT_IN_STRNCAT:
5205 target = expand_builtin_strncat (arglist, target, mode);
5206 if (target)
5207 return target;
5208 break;
5210 case BUILT_IN_STRSPN:
5211 target = expand_builtin_strspn (arglist, target, mode);
5212 if (target)
5213 return target;
5214 break;
5216 case BUILT_IN_STRCSPN:
5217 target = expand_builtin_strcspn (arglist, target, mode);
5218 if (target)
5219 return target;
5220 break;
5222 case BUILT_IN_STRSTR:
5223 target = expand_builtin_strstr (arglist, target, mode);
5224 if (target)
5225 return target;
5226 break;
5228 case BUILT_IN_STRPBRK:
5229 target = expand_builtin_strpbrk (arglist, target, mode);
5230 if (target)
5231 return target;
5232 break;
5234 case BUILT_IN_INDEX:
5235 case BUILT_IN_STRCHR:
5236 target = expand_builtin_strchr (arglist, target, mode);
5237 if (target)
5238 return target;
5239 break;
5241 case BUILT_IN_RINDEX:
5242 case BUILT_IN_STRRCHR:
5243 target = expand_builtin_strrchr (arglist, target, mode);
5244 if (target)
5245 return target;
5246 break;
5248 case BUILT_IN_MEMCPY:
5249 target = expand_builtin_memcpy (arglist, target, mode);
5250 if (target)
5251 return target;
5252 break;
5254 case BUILT_IN_MEMPCPY:
5255 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5256 if (target)
5257 return target;
5258 break;
5260 case BUILT_IN_MEMMOVE:
5261 target = expand_builtin_memmove (arglist, target, mode);
5262 if (target)
5263 return target;
5264 break;
5266 case BUILT_IN_BCOPY:
5267 target = expand_builtin_bcopy (arglist);
5268 if (target)
5269 return target;
5270 break;
5272 case BUILT_IN_MEMSET:
5273 target = expand_builtin_memset (arglist, target, mode);
5274 if (target)
5275 return target;
5276 break;
5278 case BUILT_IN_BZERO:
5279 target = expand_builtin_bzero (arglist);
5280 if (target)
5281 return target;
5282 break;
5284 case BUILT_IN_STRCMP:
5285 target = expand_builtin_strcmp (exp, target, mode);
5286 if (target)
5287 return target;
5288 break;
5290 case BUILT_IN_STRNCMP:
5291 target = expand_builtin_strncmp (exp, target, mode);
5292 if (target)
5293 return target;
5294 break;
5296 case BUILT_IN_BCMP:
5297 case BUILT_IN_MEMCMP:
5298 target = expand_builtin_memcmp (exp, arglist, target, mode);
5299 if (target)
5300 return target;
5301 break;
5303 case BUILT_IN_SETJMP:
5304 target = expand_builtin_setjmp (arglist, target);
5305 if (target)
5306 return target;
5307 break;
5309 /* __builtin_longjmp is passed a pointer to an array of five words.
5310 It's similar to the C library longjmp function but works with
5311 __builtin_setjmp above. */
5312 case BUILT_IN_LONGJMP:
5313 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5314 break;
5315 else
5317 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5318 VOIDmode, 0);
5319 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5320 NULL_RTX, VOIDmode, 0);
5322 if (value != const1_rtx)
5324 error ("__builtin_longjmp second argument must be 1");
5325 return const0_rtx;
5328 expand_builtin_longjmp (buf_addr, value);
5329 return const0_rtx;
5332 case BUILT_IN_TRAP:
5333 expand_builtin_trap ();
5334 return const0_rtx;
5336 case BUILT_IN_PRINTF:
5337 target = expand_builtin_printf (arglist, target, mode, false);
5338 if (target)
5339 return target;
5340 break;
5342 case BUILT_IN_PRINTF_UNLOCKED:
5343 target = expand_builtin_printf (arglist, target, mode, true);
5344 if (target)
5345 return target;
5346 break;
5348 case BUILT_IN_FPUTS:
5349 target = expand_builtin_fputs (arglist, target, false);
5350 if (target)
5351 return target;
5352 break;
5354 case BUILT_IN_FPUTS_UNLOCKED:
5355 target = expand_builtin_fputs (arglist, target, true);
5356 if (target)
5357 return target;
5358 break;
5360 case BUILT_IN_FPRINTF:
5361 target = expand_builtin_fprintf (arglist, target, mode, false);
5362 if (target)
5363 return target;
5364 break;
5366 case BUILT_IN_FPRINTF_UNLOCKED:
5367 target = expand_builtin_fprintf (arglist, target, mode, true);
5368 if (target)
5369 return target;
5370 break;
5372 case BUILT_IN_SPRINTF:
5373 target = expand_builtin_sprintf (arglist, target, mode);
5374 if (target)
5375 return target;
5376 break;
5378 /* Various hooks for the DWARF 2 __throw routine. */
5379 case BUILT_IN_UNWIND_INIT:
5380 expand_builtin_unwind_init ();
5381 return const0_rtx;
5382 case BUILT_IN_DWARF_CFA:
5383 return virtual_cfa_rtx;
5384 #ifdef DWARF2_UNWIND_INFO
5385 case BUILT_IN_DWARF_SP_COLUMN:
5386 return expand_builtin_dwarf_sp_column ();
5387 case BUILT_IN_INIT_DWARF_REG_SIZES:
5388 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5389 return const0_rtx;
5390 #endif
5391 case BUILT_IN_FROB_RETURN_ADDR:
5392 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5393 case BUILT_IN_EXTRACT_RETURN_ADDR:
5394 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5395 case BUILT_IN_EH_RETURN:
5396 expand_builtin_eh_return (TREE_VALUE (arglist),
5397 TREE_VALUE (TREE_CHAIN (arglist)));
5398 return const0_rtx;
5399 #ifdef EH_RETURN_DATA_REGNO
5400 case BUILT_IN_EH_RETURN_DATA_REGNO:
5401 return expand_builtin_eh_return_data_regno (arglist);
5402 #endif
5403 case BUILT_IN_VA_START:
5404 case BUILT_IN_STDARG_START:
5405 return expand_builtin_va_start (arglist);
5406 case BUILT_IN_VA_END:
5407 return expand_builtin_va_end (arglist);
5408 case BUILT_IN_VA_COPY:
5409 return expand_builtin_va_copy (arglist);
5410 case BUILT_IN_EXPECT:
5411 return expand_builtin_expect (arglist, target);
5412 case BUILT_IN_PREFETCH:
5413 expand_builtin_prefetch (arglist);
5414 return const0_rtx;
5417 default: /* just do library call, if unknown builtin */
5418 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5419 error ("built-in function `%s' not currently supported",
5420 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5423 /* The switch statement above can drop through to cause the function
5424 to be called normally. */
5425 return expand_call (exp, target, ignore);
5428 /* Determine whether a tree node represents a call to a built-in
5429 function. If the tree T is a call to a built-in function with
5430 the right number of arguments of the appropriate types, return
5431 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5432 Otherwise the return value is END_BUILTINS. */
5434 enum built_in_function
5435 builtin_mathfn_code (tree t)
5437 tree fndecl, arglist, parmlist;
5438 tree argtype, parmtype;
5440 if (TREE_CODE (t) != CALL_EXPR
5441 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5442 return END_BUILTINS;
5444 fndecl = get_callee_fndecl (t);
5445 if (fndecl == NULL_TREE
5446 || TREE_CODE (fndecl) != FUNCTION_DECL
5447 || ! DECL_BUILT_IN (fndecl)
5448 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5449 return END_BUILTINS;
5451 arglist = TREE_OPERAND (t, 1);
5452 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5453 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5455 /* If a function doesn't take a variable number of arguments,
5456 the last element in the list will have type `void'. */
5457 parmtype = TREE_VALUE (parmlist);
5458 if (VOID_TYPE_P (parmtype))
5460 if (arglist)
5461 return END_BUILTINS;
5462 return DECL_FUNCTION_CODE (fndecl);
5465 if (! arglist)
5466 return END_BUILTINS;
5468 argtype = TREE_TYPE (TREE_VALUE (arglist));
5470 if (SCALAR_FLOAT_TYPE_P (parmtype))
5472 if (! SCALAR_FLOAT_TYPE_P (argtype))
5473 return END_BUILTINS;
5475 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5477 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5478 return END_BUILTINS;
5480 else if (POINTER_TYPE_P (parmtype))
5482 if (! POINTER_TYPE_P (argtype))
5483 return END_BUILTINS;
5485 else if (INTEGRAL_TYPE_P (parmtype))
5487 if (! INTEGRAL_TYPE_P (argtype))
5488 return END_BUILTINS;
5490 else
5491 return END_BUILTINS;
5493 arglist = TREE_CHAIN (arglist);
5496 /* Variable-length argument list. */
5497 return DECL_FUNCTION_CODE (fndecl);
5500 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5501 constant. ARGLIST is the argument list of the call. */
5503 static tree
5504 fold_builtin_constant_p (tree arglist)
5506 if (arglist == 0)
5507 return 0;
5509 arglist = TREE_VALUE (arglist);
5511 /* We return 1 for a numeric type that's known to be a constant
5512 value at compile-time or for an aggregate type that's a
5513 literal constant. */
5514 STRIP_NOPS (arglist);
5516 /* If we know this is a constant, emit the constant of one. */
5517 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5518 || (TREE_CODE (arglist) == CONSTRUCTOR
5519 && TREE_CONSTANT (arglist))
5520 || (TREE_CODE (arglist) == ADDR_EXPR
5521 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5522 return integer_one_node;
5524 /* If this expression has side effects, show we don't know it to be a
5525 constant. Likewise if it's a pointer or aggregate type since in
5526 those case we only want literals, since those are only optimized
5527 when generating RTL, not later.
5528 And finally, if we are compiling an initializer, not code, we
5529 need to return a definite result now; there's not going to be any
5530 more optimization done. */
5531 if (TREE_SIDE_EFFECTS (arglist)
5532 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5533 || POINTER_TYPE_P (TREE_TYPE (arglist))
5534 || cfun == 0)
5535 return integer_zero_node;
5537 return 0;
5540 /* Fold a call to __builtin_classify_type. */
5542 static tree
5543 fold_builtin_classify_type (tree arglist)
5545 if (arglist == 0)
5546 return build_int_2 (no_type_class, 0);
5548 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5551 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5553 static tree
5554 fold_builtin_inf (tree type, int warn)
5556 REAL_VALUE_TYPE real;
5558 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5559 warning ("target format does not support infinity");
5561 real_inf (&real);
5562 return build_real (type, real);
5565 /* Fold a call to __builtin_nan or __builtin_nans. */
5567 static tree
5568 fold_builtin_nan (tree arglist, tree type, int quiet)
5570 REAL_VALUE_TYPE real;
5571 const char *str;
5573 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5574 return 0;
5575 str = c_getstr (TREE_VALUE (arglist));
5576 if (!str)
5577 return 0;
5579 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5580 return 0;
5582 return build_real (type, real);
5585 /* Return true if the floating point expression T has an integer value.
5586 We also allow +Inf, -Inf and NaN to be considered integer values. */
5588 static bool
5589 integer_valued_real_p (tree t)
5591 switch (TREE_CODE (t))
5593 case FLOAT_EXPR:
5594 return true;
5596 case ABS_EXPR:
5597 case SAVE_EXPR:
5598 case NON_LVALUE_EXPR:
5599 return integer_valued_real_p (TREE_OPERAND (t, 0));
5601 case COMPOUND_EXPR:
5602 case MODIFY_EXPR:
5603 case BIND_EXPR:
5604 return integer_valued_real_p (TREE_OPERAND (t, 1));
5606 case PLUS_EXPR:
5607 case MINUS_EXPR:
5608 case MULT_EXPR:
5609 case MIN_EXPR:
5610 case MAX_EXPR:
5611 return integer_valued_real_p (TREE_OPERAND (t, 0))
5612 && integer_valued_real_p (TREE_OPERAND (t, 1));
5614 case COND_EXPR:
5615 return integer_valued_real_p (TREE_OPERAND (t, 1))
5616 && integer_valued_real_p (TREE_OPERAND (t, 2));
5618 case REAL_CST:
5619 if (! TREE_CONSTANT_OVERFLOW (t))
5621 REAL_VALUE_TYPE c, cint;
5623 c = TREE_REAL_CST (t);
5624 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5625 return real_identical (&c, &cint);
5628 case NOP_EXPR:
5630 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5631 if (TREE_CODE (type) == INTEGER_TYPE)
5632 return true;
5633 if (TREE_CODE (type) == REAL_TYPE)
5634 return integer_valued_real_p (TREE_OPERAND (t, 0));
5635 break;
5638 case CALL_EXPR:
5639 switch (builtin_mathfn_code (t))
5641 case BUILT_IN_CEIL:
5642 case BUILT_IN_CEILF:
5643 case BUILT_IN_CEILL:
5644 case BUILT_IN_FLOOR:
5645 case BUILT_IN_FLOORF:
5646 case BUILT_IN_FLOORL:
5647 case BUILT_IN_NEARBYINT:
5648 case BUILT_IN_NEARBYINTF:
5649 case BUILT_IN_NEARBYINTL:
5650 case BUILT_IN_ROUND:
5651 case BUILT_IN_ROUNDF:
5652 case BUILT_IN_ROUNDL:
5653 case BUILT_IN_TRUNC:
5654 case BUILT_IN_TRUNCF:
5655 case BUILT_IN_TRUNCL:
5656 return true;
5658 default:
5659 break;
5661 break;
5663 default:
5664 break;
5666 return false;
5669 /* EXP is assumed to be builtin call where truncation can be propagated
5670 across (for instance floor((double)f) == (double)floorf (f).
5671 Do the transformation. */
5673 static tree
5674 fold_trunc_transparent_mathfn (tree exp)
5676 tree fndecl = get_callee_fndecl (exp);
5677 tree arglist = TREE_OPERAND (exp, 1);
5678 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5679 tree arg;
5681 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5682 return 0;
5684 arg = TREE_VALUE (arglist);
5685 /* Integer rounding functions are idempotent. */
5686 if (fcode == builtin_mathfn_code (arg))
5687 return arg;
5689 /* If argument is already integer valued, and we don't need to worry
5690 about setting errno, there's no need to perform rounding. */
5691 if (! flag_errno_math && integer_valued_real_p (arg))
5692 return arg;
5694 if (optimize)
5696 tree arg0 = strip_float_extensions (arg);
5697 tree ftype = TREE_TYPE (exp);
5698 tree newtype = TREE_TYPE (arg0);
5699 tree decl;
5701 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5702 && (decl = mathfn_built_in (newtype, fcode)))
5704 arglist =
5705 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5706 return convert (ftype,
5707 build_function_call_expr (decl, arglist));
5710 return 0;
5713 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5714 function's DECL, ARGLIST is the argument list and TYPE is the return
5715 type. Return NULL_TREE if no simplification can be made. */
5717 static tree
5718 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5720 tree arg;
5722 if (!arglist || TREE_CHAIN (arglist))
5723 return NULL_TREE;
5725 arg = TREE_VALUE (arglist);
5726 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5727 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5728 return NULL_TREE;
5730 /* Evaluate cabs of a constant at compile-time. */
5731 if (flag_unsafe_math_optimizations
5732 && TREE_CODE (arg) == COMPLEX_CST
5733 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5734 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5735 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5736 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5738 REAL_VALUE_TYPE r, i;
5740 r = TREE_REAL_CST (TREE_REALPART (arg));
5741 i = TREE_REAL_CST (TREE_IMAGPART (arg));
5743 real_arithmetic (&r, MULT_EXPR, &r, &r);
5744 real_arithmetic (&i, MULT_EXPR, &i, &i);
5745 real_arithmetic (&r, PLUS_EXPR, &r, &i);
5746 if (real_sqrt (&r, TYPE_MODE (type), &r)
5747 || ! flag_trapping_math)
5748 return build_real (type, r);
5751 /* If either part is zero, cabs is fabs of the other. */
5752 if (TREE_CODE (arg) == COMPLEX_EXPR
5753 && real_zerop (TREE_OPERAND (arg, 0)))
5754 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5755 if (TREE_CODE (arg) == COMPLEX_EXPR
5756 && real_zerop (TREE_OPERAND (arg, 1)))
5757 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5759 if (flag_unsafe_math_optimizations)
5761 enum built_in_function fcode;
5762 tree sqrtfn;
5764 fcode = DECL_FUNCTION_CODE (fndecl);
5765 if (fcode == BUILT_IN_CABS)
5766 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5767 else if (fcode == BUILT_IN_CABSF)
5768 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5769 else if (fcode == BUILT_IN_CABSL)
5770 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5771 else
5772 sqrtfn = NULL_TREE;
5774 if (sqrtfn != NULL_TREE)
5776 tree rpart, ipart, result, arglist;
5778 arg = save_expr (arg);
5780 rpart = fold (build1 (REALPART_EXPR, type, arg));
5781 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5783 rpart = save_expr (rpart);
5784 ipart = save_expr (ipart);
5786 result = fold (build (PLUS_EXPR, type,
5787 fold (build (MULT_EXPR, type,
5788 rpart, rpart)),
5789 fold (build (MULT_EXPR, type,
5790 ipart, ipart))));
5792 arglist = build_tree_list (NULL_TREE, result);
5793 return build_function_call_expr (sqrtfn, arglist);
5797 return NULL_TREE;
5800 /* Fold function call to builtin trunc, truncf or truncl. Return
5801 NULL_TREE if no simplification can be made. */
5803 static tree
5804 fold_builtin_trunc (tree exp)
5806 tree arglist = TREE_OPERAND (exp, 1);
5807 tree arg;
5809 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5810 return 0;
5812 /* Optimize trunc of constant value. */
5813 arg = TREE_VALUE (arglist);
5814 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5816 REAL_VALUE_TYPE r, x;
5817 tree type = TREE_TYPE (exp);
5819 x = TREE_REAL_CST (arg);
5820 real_trunc (&r, TYPE_MODE (type), &x);
5821 return build_real (type, r);
5824 return fold_trunc_transparent_mathfn (exp);
5827 /* Fold function call to builtin floor, floorf or floorl. Return
5828 NULL_TREE if no simplification can be made. */
5830 static tree
5831 fold_builtin_floor (tree exp)
5833 tree arglist = TREE_OPERAND (exp, 1);
5834 tree arg;
5836 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5837 return 0;
5839 /* Optimize floor of constant value. */
5840 arg = TREE_VALUE (arglist);
5841 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5843 REAL_VALUE_TYPE x;
5845 x = TREE_REAL_CST (arg);
5846 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5848 tree type = TREE_TYPE (exp);
5849 REAL_VALUE_TYPE r;
5851 real_floor (&r, TYPE_MODE (type), &x);
5852 return build_real (type, r);
5856 return fold_trunc_transparent_mathfn (exp);
5859 /* Fold function call to builtin ceil, ceilf or ceill. Return
5860 NULL_TREE if no simplification can be made. */
5862 static tree
5863 fold_builtin_ceil (tree exp)
5865 tree arglist = TREE_OPERAND (exp, 1);
5866 tree arg;
5868 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5869 return 0;
5871 /* Optimize ceil of constant value. */
5872 arg = TREE_VALUE (arglist);
5873 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5875 REAL_VALUE_TYPE x;
5877 x = TREE_REAL_CST (arg);
5878 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5880 tree type = TREE_TYPE (exp);
5881 REAL_VALUE_TYPE r;
5883 real_ceil (&r, TYPE_MODE (type), &x);
5884 return build_real (type, r);
5888 return fold_trunc_transparent_mathfn (exp);
5891 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
5892 and their long and long long variants (i.e. ffsl and ffsll).
5893 Return NULL_TREE if no simplification can be made. */
5895 static tree
5896 fold_builtin_bitop (tree exp)
5898 tree fndecl = get_callee_fndecl (exp);
5899 tree arglist = TREE_OPERAND (exp, 1);
5900 tree arg;
5902 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
5903 return NULL_TREE;
5905 /* Optimize for constant argument. */
5906 arg = TREE_VALUE (arglist);
5907 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5909 HOST_WIDE_INT hi, width, result;
5910 unsigned HOST_WIDE_INT lo;
5911 tree type, t;
5913 type = TREE_TYPE (arg);
5914 width = TYPE_PRECISION (type);
5915 lo = TREE_INT_CST_LOW (arg);
5917 /* Clear all the bits that are beyond the type's precision. */
5918 if (width > HOST_BITS_PER_WIDE_INT)
5920 hi = TREE_INT_CST_HIGH (arg);
5921 if (width < 2 * HOST_BITS_PER_WIDE_INT)
5922 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
5924 else
5926 hi = 0;
5927 if (width < HOST_BITS_PER_WIDE_INT)
5928 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
5931 switch (DECL_FUNCTION_CODE (fndecl))
5933 case BUILT_IN_FFS:
5934 case BUILT_IN_FFSL:
5935 case BUILT_IN_FFSLL:
5936 if (lo != 0)
5937 result = exact_log2 (lo & -lo) + 1;
5938 else if (hi != 0)
5939 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
5940 else
5941 result = 0;
5942 break;
5944 case BUILT_IN_CLZ:
5945 case BUILT_IN_CLZL:
5946 case BUILT_IN_CLZLL:
5947 if (hi != 0)
5948 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
5949 else if (lo != 0)
5950 result = width - floor_log2 (lo) - 1;
5951 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5952 result = width;
5953 break;
5955 case BUILT_IN_CTZ:
5956 case BUILT_IN_CTZL:
5957 case BUILT_IN_CTZLL:
5958 if (lo != 0)
5959 result = exact_log2 (lo & -lo);
5960 else if (hi != 0)
5961 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
5962 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5963 result = width;
5964 break;
5966 case BUILT_IN_POPCOUNT:
5967 case BUILT_IN_POPCOUNTL:
5968 case BUILT_IN_POPCOUNTLL:
5969 result = 0;
5970 while (lo)
5971 result++, lo &= lo - 1;
5972 while (hi)
5973 result++, hi &= hi - 1;
5974 break;
5976 case BUILT_IN_PARITY:
5977 case BUILT_IN_PARITYL:
5978 case BUILT_IN_PARITYLL:
5979 result = 0;
5980 while (lo)
5981 result++, lo &= lo - 1;
5982 while (hi)
5983 result++, hi &= hi - 1;
5984 result &= 1;
5985 break;
5987 default:
5988 abort();
5991 t = build_int_2 (result, 0);
5992 TREE_TYPE (t) = TREE_TYPE (exp);
5993 return t;
5996 return NULL_TREE;
5999 /* Return true if EXPR is the real constant contained in VALUE. */
6001 static bool
6002 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6004 STRIP_NOPS (expr);
6006 return ((TREE_CODE (expr) == REAL_CST
6007 && ! TREE_CONSTANT_OVERFLOW (expr)
6008 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6009 || (TREE_CODE (expr) == COMPLEX_CST
6010 && real_dconstp (TREE_REALPART (expr), value)
6011 && real_zerop (TREE_IMAGPART (expr))));
6014 /* A subroutine of fold_builtin to fold the various logarithmic
6015 functions. EXP is the CALL_EXPR of a call to a builtin log*
6016 function. VALUE is the base of the log* function. */
6018 static tree
6019 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6021 tree arglist = TREE_OPERAND (exp, 1);
6023 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6025 tree fndecl = get_callee_fndecl (exp);
6026 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6027 tree arg = TREE_VALUE (arglist);
6028 const enum built_in_function fcode = builtin_mathfn_code (arg);
6030 /* Optimize log*(1.0) = 0.0. */
6031 if (real_onep (arg))
6032 return build_real (type, dconst0);
6034 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6035 exactly, then only do this if flag_unsafe_math_optimizations. */
6036 if (exact_real_truncate (TYPE_MODE (type), value)
6037 || flag_unsafe_math_optimizations)
6039 const REAL_VALUE_TYPE value_truncate =
6040 real_value_truncate (TYPE_MODE (type), *value);
6041 if (real_dconstp (arg, &value_truncate))
6042 return build_real (type, dconst1);
6045 /* Special case, optimize logN(expN(x)) = x. */
6046 if (flag_unsafe_math_optimizations
6047 && ((value == &dconste
6048 && (fcode == BUILT_IN_EXP
6049 || fcode == BUILT_IN_EXPF
6050 || fcode == BUILT_IN_EXPL))
6051 || (value == &dconst2
6052 && (fcode == BUILT_IN_EXP2
6053 || fcode == BUILT_IN_EXP2F
6054 || fcode == BUILT_IN_EXP2L))
6055 || (value == &dconst10
6056 && (fcode == BUILT_IN_EXP10
6057 || fcode == BUILT_IN_EXP10F
6058 || fcode == BUILT_IN_EXP10L))))
6059 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6061 /* Optimize log*(func()) for various exponential functions. We
6062 want to determine the value "x" and the power "exponent" in
6063 order to transform logN(x**exponent) into exponent*logN(x). */
6064 if (flag_unsafe_math_optimizations)
6066 tree exponent = 0, x = 0;
6068 switch (fcode)
6070 case BUILT_IN_EXP:
6071 case BUILT_IN_EXPF:
6072 case BUILT_IN_EXPL:
6073 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6074 x = build_real (type,
6075 real_value_truncate (TYPE_MODE (type), dconste));
6076 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6077 break;
6078 case BUILT_IN_EXP2:
6079 case BUILT_IN_EXP2F:
6080 case BUILT_IN_EXP2L:
6081 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6082 x = build_real (type, dconst2);
6083 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6084 break;
6085 case BUILT_IN_EXP10:
6086 case BUILT_IN_EXP10F:
6087 case BUILT_IN_EXP10L:
6088 case BUILT_IN_POW10:
6089 case BUILT_IN_POW10F:
6090 case BUILT_IN_POW10L:
6091 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6092 x = build_real (type, dconst10);
6093 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6094 break;
6095 case BUILT_IN_SQRT:
6096 case BUILT_IN_SQRTF:
6097 case BUILT_IN_SQRTL:
6098 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6099 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6100 exponent = build_real (type, dconsthalf);
6101 break;
6102 case BUILT_IN_CBRT:
6103 case BUILT_IN_CBRTF:
6104 case BUILT_IN_CBRTL:
6105 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6106 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6107 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6108 dconstthird));
6109 break;
6110 case BUILT_IN_POW:
6111 case BUILT_IN_POWF:
6112 case BUILT_IN_POWL:
6113 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6114 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6115 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6116 break;
6117 default:
6118 break;
6121 /* Now perform the optimization. */
6122 if (x && exponent)
6124 tree logfn;
6125 arglist = build_tree_list (NULL_TREE, x);
6126 logfn = build_function_call_expr (fndecl, arglist);
6127 return fold (build (MULT_EXPR, type, exponent, logfn));
6132 return 0;
6135 /* A subroutine of fold_builtin to fold the various exponent
6136 functions. EXP is the CALL_EXPR of a call to a builtin function.
6137 VALUE is the value which will be raised to a power. */
6139 static tree
6140 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6142 tree arglist = TREE_OPERAND (exp, 1);
6144 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6146 tree fndecl = get_callee_fndecl (exp);
6147 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6148 tree arg = TREE_VALUE (arglist);
6150 /* Optimize exp*(0.0) = 1.0. */
6151 if (real_zerop (arg))
6152 return build_real (type, dconst1);
6154 /* Optimize expN(1.0) = N. */
6155 if (real_onep (arg))
6157 REAL_VALUE_TYPE cst;
6159 real_convert (&cst, TYPE_MODE (type), value);
6160 return build_real (type, cst);
6163 /* Attempt to evaluate expN(integer) at compile-time. */
6164 if (flag_unsafe_math_optimizations
6165 && TREE_CODE (arg) == REAL_CST
6166 && ! TREE_CONSTANT_OVERFLOW (arg))
6168 REAL_VALUE_TYPE cint;
6169 REAL_VALUE_TYPE c;
6170 HOST_WIDE_INT n;
6172 c = TREE_REAL_CST (arg);
6173 n = real_to_integer (&c);
6174 real_from_integer (&cint, VOIDmode, n,
6175 n < 0 ? -1 : 0, 0);
6176 if (real_identical (&c, &cint))
6178 REAL_VALUE_TYPE x;
6180 real_powi (&x, TYPE_MODE (type), value, n);
6181 return build_real (type, x);
6185 /* Optimize expN(logN(x)) = x. */
6186 if (flag_unsafe_math_optimizations)
6188 const enum built_in_function fcode = builtin_mathfn_code (arg);
6190 if ((value == &dconste
6191 && (fcode == BUILT_IN_LOG
6192 || fcode == BUILT_IN_LOGF
6193 || fcode == BUILT_IN_LOGL))
6194 || (value == &dconst2
6195 && (fcode == BUILT_IN_LOG2
6196 || fcode == BUILT_IN_LOG2F
6197 || fcode == BUILT_IN_LOG2L))
6198 || (value == &dconst10
6199 && (fcode == BUILT_IN_LOG10
6200 || fcode == BUILT_IN_LOG10F
6201 || fcode == BUILT_IN_LOG10L)))
6202 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6206 return 0;
6209 /* Fold function call to builtin memcpy. Return
6210 NULL_TREE if no simplification can be made. */
6212 static tree
6213 fold_builtin_memcpy (tree exp)
6215 tree arglist = TREE_OPERAND (exp, 1);
6216 tree dest, src, len;
6218 if (!validate_arglist (arglist,
6219 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6220 return 0;
6222 dest = TREE_VALUE (arglist);
6223 src = TREE_VALUE (TREE_CHAIN (arglist));
6224 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6226 /* If the LEN parameter is zero, return DEST. */
6227 if (integer_zerop (len))
6228 return omit_one_operand (TREE_TYPE (exp), dest, src);
6230 /* If SRC and DEST are the same (and not volatile), return DEST. */
6231 if (operand_equal_p (src, dest, 0))
6232 return omit_one_operand (TREE_TYPE (exp), dest, len);
6234 return 0;
6237 /* Fold function call to builtin mempcpy. Return
6238 NULL_TREE if no simplification can be made. */
6240 static tree
6241 fold_builtin_mempcpy (tree exp)
6243 tree arglist = TREE_OPERAND (exp, 1);
6244 tree dest, src, len;
6246 if (!validate_arglist (arglist,
6247 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6248 return 0;
6250 dest = TREE_VALUE (arglist);
6251 src = TREE_VALUE (TREE_CHAIN (arglist));
6252 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6254 /* If the LEN parameter is zero, return DEST. */
6255 if (integer_zerop (len))
6256 return omit_one_operand (TREE_TYPE (exp), dest, src);
6258 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6259 if (operand_equal_p (src, dest, 0))
6261 tree temp = convert (TREE_TYPE (dest), len);
6262 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6263 return convert (TREE_TYPE (exp), temp);
6266 return 0;
6269 /* Fold function call to builtin memmove. Return
6270 NULL_TREE if no simplification can be made. */
6272 static tree
6273 fold_builtin_memmove (tree exp)
6275 tree arglist = TREE_OPERAND (exp, 1);
6276 tree dest, src, len;
6278 if (!validate_arglist (arglist,
6279 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6280 return 0;
6282 dest = TREE_VALUE (arglist);
6283 src = TREE_VALUE (TREE_CHAIN (arglist));
6284 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6286 /* If the LEN parameter is zero, return DEST. */
6287 if (integer_zerop (len))
6288 return omit_one_operand (TREE_TYPE (exp), dest, src);
6290 /* If SRC and DEST are the same (and not volatile), return DEST. */
6291 if (operand_equal_p (src, dest, 0))
6292 return omit_one_operand (TREE_TYPE (exp), dest, len);
6294 return 0;
6297 /* Fold function call to builtin strcpy. Return
6298 NULL_TREE if no simplification can be made. */
6300 static tree
6301 fold_builtin_strcpy (tree exp)
6303 tree arglist = TREE_OPERAND (exp, 1);
6304 tree dest, src;
6306 if (!validate_arglist (arglist,
6307 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6308 return 0;
6310 dest = TREE_VALUE (arglist);
6311 src = TREE_VALUE (TREE_CHAIN (arglist));
6313 /* If SRC and DEST are the same (and not volatile), return DEST. */
6314 if (operand_equal_p (src, dest, 0))
6315 return convert (TREE_TYPE (exp), dest);
6317 return 0;
6320 /* Fold function call to builtin strncpy. Return
6321 NULL_TREE if no simplification can be made. */
6323 static tree
6324 fold_builtin_strncpy (tree exp)
6326 tree arglist = TREE_OPERAND (exp, 1);
6327 tree dest, src, len;
6329 if (!validate_arglist (arglist,
6330 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6331 return 0;
6333 dest = TREE_VALUE (arglist);
6334 src = TREE_VALUE (TREE_CHAIN (arglist));
6335 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6337 /* If the LEN parameter is zero, return DEST. */
6338 if (integer_zerop (len))
6339 return omit_one_operand (TREE_TYPE (exp), dest, src);
6341 return 0;
6344 /* Fold function call to builtin memcmp. Return
6345 NULL_TREE if no simplification can be made. */
6347 static tree
6348 fold_builtin_memcmp (tree exp)
6350 tree arglist = TREE_OPERAND (exp, 1);
6351 tree arg1, arg2, len;
6353 if (!validate_arglist (arglist,
6354 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6355 return 0;
6357 arg1 = TREE_VALUE (arglist);
6358 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6359 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6361 /* If the LEN parameter is zero, return zero. */
6362 if (integer_zerop (len))
6364 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6365 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6368 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6369 if (operand_equal_p (arg1, arg2, 0))
6370 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6372 return 0;
6375 /* Fold function call to builtin strcmp. Return
6376 NULL_TREE if no simplification can be made. */
6378 static tree
6379 fold_builtin_strcmp (tree exp)
6381 tree arglist = TREE_OPERAND (exp, 1);
6382 tree arg1, arg2;
6383 const char *p1, *p2;
6385 if (!validate_arglist (arglist,
6386 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6387 return 0;
6389 arg1 = TREE_VALUE (arglist);
6390 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6392 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6393 if (operand_equal_p (arg1, arg2, 0))
6394 return convert (TREE_TYPE (exp), integer_zero_node);
6396 p1 = c_getstr (arg1);
6397 p2 = c_getstr (arg2);
6399 if (p1 && p2)
6401 tree temp;
6402 const int i = strcmp (p1, p2);
6403 if (i < 0)
6404 temp = integer_minus_one_node;
6405 else if (i > 0)
6406 temp = integer_one_node;
6407 else
6408 temp = integer_zero_node;
6409 return convert (TREE_TYPE (exp), temp);
6412 return 0;
6415 /* Fold function call to builtin strncmp. Return
6416 NULL_TREE if no simplification can be made. */
6418 static tree
6419 fold_builtin_strncmp (tree exp)
6421 tree arglist = TREE_OPERAND (exp, 1);
6422 tree arg1, arg2, len;
6423 const char *p1, *p2;
6425 if (!validate_arglist (arglist,
6426 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6427 return 0;
6429 arg1 = TREE_VALUE (arglist);
6430 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6431 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6433 /* If the LEN parameter is zero, return zero. */
6434 if (integer_zerop (len))
6436 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6437 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6440 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6441 if (operand_equal_p (arg1, arg2, 0))
6442 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6444 p1 = c_getstr (arg1);
6445 p2 = c_getstr (arg2);
6447 if (host_integerp (len, 1) && p1 && p2)
6449 tree temp;
6450 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6451 if (i < 0)
6452 temp = integer_minus_one_node;
6453 else if (i > 0)
6454 temp = integer_one_node;
6455 else
6456 temp = integer_zero_node;
6457 return convert (TREE_TYPE (exp), temp);
6460 return 0;
6463 /* Used by constant folding to eliminate some builtin calls early. EXP is
6464 the CALL_EXPR of a call to a builtin function. */
6466 tree
6467 fold_builtin (tree exp)
6469 tree fndecl = get_callee_fndecl (exp);
6470 tree arglist = TREE_OPERAND (exp, 1);
6471 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6473 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6474 return 0;
6476 switch (DECL_FUNCTION_CODE (fndecl))
6478 case BUILT_IN_CONSTANT_P:
6479 return fold_builtin_constant_p (arglist);
6481 case BUILT_IN_CLASSIFY_TYPE:
6482 return fold_builtin_classify_type (arglist);
6484 case BUILT_IN_STRLEN:
6485 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6487 tree len = c_strlen (TREE_VALUE (arglist), 0);
6488 if (len)
6490 /* Convert from the internal "sizetype" type to "size_t". */
6491 if (size_type_node)
6492 len = convert (size_type_node, len);
6493 return len;
6496 break;
6498 case BUILT_IN_FABS:
6499 case BUILT_IN_FABSF:
6500 case BUILT_IN_FABSL:
6501 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6502 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6503 break;
6505 case BUILT_IN_CABS:
6506 case BUILT_IN_CABSF:
6507 case BUILT_IN_CABSL:
6508 return fold_builtin_cabs (fndecl, arglist, type);
6510 case BUILT_IN_SQRT:
6511 case BUILT_IN_SQRTF:
6512 case BUILT_IN_SQRTL:
6513 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6515 enum built_in_function fcode;
6516 tree arg = TREE_VALUE (arglist);
6518 /* Optimize sqrt of constant value. */
6519 if (TREE_CODE (arg) == REAL_CST
6520 && ! TREE_CONSTANT_OVERFLOW (arg))
6522 REAL_VALUE_TYPE r, x;
6524 x = TREE_REAL_CST (arg);
6525 if (real_sqrt (&r, TYPE_MODE (type), &x)
6526 || (!flag_trapping_math && !flag_errno_math))
6527 return build_real (type, r);
6530 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
6531 fcode = builtin_mathfn_code (arg);
6532 if (flag_unsafe_math_optimizations
6533 && (fcode == BUILT_IN_EXP
6534 || fcode == BUILT_IN_EXPF
6535 || fcode == BUILT_IN_EXPL))
6537 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6538 arg = fold (build (MULT_EXPR, type,
6539 TREE_VALUE (TREE_OPERAND (arg, 1)),
6540 build_real (type, dconsthalf)));
6541 arglist = build_tree_list (NULL_TREE, arg);
6542 return build_function_call_expr (expfn, arglist);
6545 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6546 if (flag_unsafe_math_optimizations
6547 && (fcode == BUILT_IN_POW
6548 || fcode == BUILT_IN_POWF
6549 || fcode == BUILT_IN_POWL))
6551 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6552 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6553 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6554 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6555 build_real (type, dconsthalf)));
6556 arglist = tree_cons (NULL_TREE, arg0,
6557 build_tree_list (NULL_TREE, narg1));
6558 return build_function_call_expr (powfn, arglist);
6561 break;
6563 case BUILT_IN_SIN:
6564 case BUILT_IN_SINF:
6565 case BUILT_IN_SINL:
6566 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6568 tree arg = TREE_VALUE (arglist);
6570 /* Optimize sin(0.0) = 0.0. */
6571 if (real_zerop (arg))
6572 return arg;
6574 break;
6576 case BUILT_IN_COS:
6577 case BUILT_IN_COSF:
6578 case BUILT_IN_COSL:
6579 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6581 tree arg = TREE_VALUE (arglist);
6583 /* Optimize cos(0.0) = 1.0. */
6584 if (real_zerop (arg))
6585 return build_real (type, dconst1);
6587 /* Optimize cos(-x) into cos(x). */
6588 if (TREE_CODE (arg) == NEGATE_EXPR)
6590 tree arglist = build_tree_list (NULL_TREE,
6591 TREE_OPERAND (arg, 0));
6592 return build_function_call_expr (fndecl, arglist);
6595 break;
6597 case BUILT_IN_EXP:
6598 case BUILT_IN_EXPF:
6599 case BUILT_IN_EXPL:
6600 return fold_builtin_exponent (exp, &dconste);
6601 case BUILT_IN_EXP2:
6602 case BUILT_IN_EXP2F:
6603 case BUILT_IN_EXP2L:
6604 return fold_builtin_exponent (exp, &dconst2);
6605 case BUILT_IN_EXP10:
6606 case BUILT_IN_EXP10F:
6607 case BUILT_IN_EXP10L:
6608 case BUILT_IN_POW10:
6609 case BUILT_IN_POW10F:
6610 case BUILT_IN_POW10L:
6611 return fold_builtin_exponent (exp, &dconst10);
6612 case BUILT_IN_LOG:
6613 case BUILT_IN_LOGF:
6614 case BUILT_IN_LOGL:
6615 return fold_builtin_logarithm (exp, &dconste);
6616 break;
6617 case BUILT_IN_LOG2:
6618 case BUILT_IN_LOG2F:
6619 case BUILT_IN_LOG2L:
6620 return fold_builtin_logarithm (exp, &dconst2);
6621 break;
6622 case BUILT_IN_LOG10:
6623 case BUILT_IN_LOG10F:
6624 case BUILT_IN_LOG10L:
6625 return fold_builtin_logarithm (exp, &dconst10);
6626 break;
6628 case BUILT_IN_TAN:
6629 case BUILT_IN_TANF:
6630 case BUILT_IN_TANL:
6631 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6633 enum built_in_function fcode;
6634 tree arg = TREE_VALUE (arglist);
6636 /* Optimize tan(0.0) = 0.0. */
6637 if (real_zerop (arg))
6638 return arg;
6640 /* Optimize tan(atan(x)) = x. */
6641 fcode = builtin_mathfn_code (arg);
6642 if (flag_unsafe_math_optimizations
6643 && (fcode == BUILT_IN_ATAN
6644 || fcode == BUILT_IN_ATANF
6645 || fcode == BUILT_IN_ATANL))
6646 return TREE_VALUE (TREE_OPERAND (arg, 1));
6648 break;
6650 case BUILT_IN_ATAN:
6651 case BUILT_IN_ATANF:
6652 case BUILT_IN_ATANL:
6653 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6655 tree arg = TREE_VALUE (arglist);
6657 /* Optimize atan(0.0) = 0.0. */
6658 if (real_zerop (arg))
6659 return arg;
6661 /* Optimize atan(1.0) = pi/4. */
6662 if (real_onep (arg))
6664 REAL_VALUE_TYPE cst;
6666 real_convert (&cst, TYPE_MODE (type), &dconstpi);
6667 cst.exp -= 2;
6668 return build_real (type, cst);
6671 break;
6673 case BUILT_IN_POW:
6674 case BUILT_IN_POWF:
6675 case BUILT_IN_POWL:
6676 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6678 enum built_in_function fcode;
6679 tree arg0 = TREE_VALUE (arglist);
6680 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6682 /* Optimize pow(1.0,y) = 1.0. */
6683 if (real_onep (arg0))
6684 return omit_one_operand (type, build_real (type, dconst1), arg1);
6686 if (TREE_CODE (arg1) == REAL_CST
6687 && ! TREE_CONSTANT_OVERFLOW (arg1))
6689 REAL_VALUE_TYPE c;
6690 c = TREE_REAL_CST (arg1);
6692 /* Optimize pow(x,0.0) = 1.0. */
6693 if (REAL_VALUES_EQUAL (c, dconst0))
6694 return omit_one_operand (type, build_real (type, dconst1),
6695 arg0);
6697 /* Optimize pow(x,1.0) = x. */
6698 if (REAL_VALUES_EQUAL (c, dconst1))
6699 return arg0;
6701 /* Optimize pow(x,-1.0) = 1.0/x. */
6702 if (REAL_VALUES_EQUAL (c, dconstm1))
6703 return fold (build (RDIV_EXPR, type,
6704 build_real (type, dconst1),
6705 arg0));
6707 /* Optimize pow(x,0.5) = sqrt(x). */
6708 if (flag_unsafe_math_optimizations
6709 && REAL_VALUES_EQUAL (c, dconsthalf))
6711 tree sqrtfn;
6713 fcode = DECL_FUNCTION_CODE (fndecl);
6714 if (fcode == BUILT_IN_POW)
6715 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6716 else if (fcode == BUILT_IN_POWF)
6717 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6718 else if (fcode == BUILT_IN_POWL)
6719 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6720 else
6721 sqrtfn = NULL_TREE;
6723 if (sqrtfn != NULL_TREE)
6725 tree arglist = build_tree_list (NULL_TREE, arg0);
6726 return build_function_call_expr (sqrtfn, arglist);
6730 /* Attempt to evaluate pow at compile-time. */
6731 if (TREE_CODE (arg0) == REAL_CST
6732 && ! TREE_CONSTANT_OVERFLOW (arg0))
6734 REAL_VALUE_TYPE cint;
6735 HOST_WIDE_INT n;
6737 n = real_to_integer (&c);
6738 real_from_integer (&cint, VOIDmode, n,
6739 n < 0 ? -1 : 0, 0);
6740 if (real_identical (&c, &cint))
6742 REAL_VALUE_TYPE x;
6743 bool inexact;
6745 x = TREE_REAL_CST (arg0);
6746 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6747 if (flag_unsafe_math_optimizations || !inexact)
6748 return build_real (type, x);
6753 /* Optimize pow(exp(x),y) = exp(x*y). */
6754 fcode = builtin_mathfn_code (arg0);
6755 if (flag_unsafe_math_optimizations
6756 && (fcode == BUILT_IN_EXP
6757 || fcode == BUILT_IN_EXPF
6758 || fcode == BUILT_IN_EXPL))
6760 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6761 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6762 arg = fold (build (MULT_EXPR, type, arg, arg1));
6763 arglist = build_tree_list (NULL_TREE, arg);
6764 return build_function_call_expr (expfn, arglist);
6767 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
6768 if (flag_unsafe_math_optimizations
6769 && (fcode == BUILT_IN_SQRT
6770 || fcode == BUILT_IN_SQRTF
6771 || fcode == BUILT_IN_SQRTL))
6773 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6774 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6775 build_real (type, dconsthalf)));
6777 arglist = tree_cons (NULL_TREE, narg0,
6778 build_tree_list (NULL_TREE, narg1));
6779 return build_function_call_expr (fndecl, arglist);
6782 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
6783 if (flag_unsafe_math_optimizations
6784 && (fcode == BUILT_IN_POW
6785 || fcode == BUILT_IN_POWF
6786 || fcode == BUILT_IN_POWL))
6788 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6789 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6790 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6791 arglist = tree_cons (NULL_TREE, arg00,
6792 build_tree_list (NULL_TREE, narg1));
6793 return build_function_call_expr (fndecl, arglist);
6796 break;
6798 case BUILT_IN_INF:
6799 case BUILT_IN_INFF:
6800 case BUILT_IN_INFL:
6801 return fold_builtin_inf (type, true);
6803 case BUILT_IN_HUGE_VAL:
6804 case BUILT_IN_HUGE_VALF:
6805 case BUILT_IN_HUGE_VALL:
6806 return fold_builtin_inf (type, false);
6808 case BUILT_IN_NAN:
6809 case BUILT_IN_NANF:
6810 case BUILT_IN_NANL:
6811 return fold_builtin_nan (arglist, type, true);
6813 case BUILT_IN_NANS:
6814 case BUILT_IN_NANSF:
6815 case BUILT_IN_NANSL:
6816 return fold_builtin_nan (arglist, type, false);
6818 case BUILT_IN_FLOOR:
6819 case BUILT_IN_FLOORF:
6820 case BUILT_IN_FLOORL:
6821 return fold_builtin_floor (exp);
6823 case BUILT_IN_CEIL:
6824 case BUILT_IN_CEILF:
6825 case BUILT_IN_CEILL:
6826 return fold_builtin_ceil (exp);
6828 case BUILT_IN_TRUNC:
6829 case BUILT_IN_TRUNCF:
6830 case BUILT_IN_TRUNCL:
6831 return fold_builtin_trunc (exp);
6833 case BUILT_IN_ROUND:
6834 case BUILT_IN_ROUNDF:
6835 case BUILT_IN_ROUNDL:
6836 case BUILT_IN_NEARBYINT:
6837 case BUILT_IN_NEARBYINTF:
6838 case BUILT_IN_NEARBYINTL:
6839 return fold_trunc_transparent_mathfn (exp);
6841 case BUILT_IN_FFS:
6842 case BUILT_IN_FFSL:
6843 case BUILT_IN_FFSLL:
6844 case BUILT_IN_CLZ:
6845 case BUILT_IN_CLZL:
6846 case BUILT_IN_CLZLL:
6847 case BUILT_IN_CTZ:
6848 case BUILT_IN_CTZL:
6849 case BUILT_IN_CTZLL:
6850 case BUILT_IN_POPCOUNT:
6851 case BUILT_IN_POPCOUNTL:
6852 case BUILT_IN_POPCOUNTLL:
6853 case BUILT_IN_PARITY:
6854 case BUILT_IN_PARITYL:
6855 case BUILT_IN_PARITYLL:
6856 return fold_builtin_bitop (exp);
6858 case BUILT_IN_MEMCPY:
6859 return fold_builtin_memcpy (exp);
6861 case BUILT_IN_MEMPCPY:
6862 return fold_builtin_mempcpy (exp);
6864 case BUILT_IN_MEMMOVE:
6865 return fold_builtin_memmove (exp);
6867 case BUILT_IN_STRCPY:
6868 return fold_builtin_strcpy (exp);
6870 case BUILT_IN_STRNCPY:
6871 return fold_builtin_strncpy (exp);
6873 case BUILT_IN_MEMCMP:
6874 return fold_builtin_memcmp (exp);
6876 case BUILT_IN_STRCMP:
6877 return fold_builtin_strcmp (exp);
6879 case BUILT_IN_STRNCMP:
6880 return fold_builtin_strncmp (exp);
6882 default:
6883 break;
6886 return 0;
6889 /* Conveniently construct a function call expression. */
6891 tree
6892 build_function_call_expr (tree fn, tree arglist)
6894 tree call_expr;
6896 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
6897 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
6898 call_expr, arglist);
6899 return fold (call_expr);
6902 /* This function validates the types of a function call argument list
6903 represented as a tree chain of parameters against a specified list
6904 of tree_codes. If the last specifier is a 0, that represents an
6905 ellipses, otherwise the last specifier must be a VOID_TYPE. */
6907 static int
6908 validate_arglist (tree arglist, ...)
6910 enum tree_code code;
6911 int res = 0;
6912 va_list ap;
6914 va_start (ap, arglist);
6918 code = va_arg (ap, enum tree_code);
6919 switch (code)
6921 case 0:
6922 /* This signifies an ellipses, any further arguments are all ok. */
6923 res = 1;
6924 goto end;
6925 case VOID_TYPE:
6926 /* This signifies an endlink, if no arguments remain, return
6927 true, otherwise return false. */
6928 res = arglist == 0;
6929 goto end;
6930 default:
6931 /* If no parameters remain or the parameter's code does not
6932 match the specified code, return false. Otherwise continue
6933 checking any remaining arguments. */
6934 if (arglist == 0
6935 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
6936 goto end;
6937 break;
6939 arglist = TREE_CHAIN (arglist);
6941 while (1);
6943 /* We need gotos here since we can only have one VA_CLOSE in a
6944 function. */
6945 end: ;
6946 va_end (ap);
6948 return res;
6951 /* Default target-specific builtin expander that does nothing. */
6954 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6955 rtx target ATTRIBUTE_UNUSED,
6956 rtx subtarget ATTRIBUTE_UNUSED,
6957 enum machine_mode mode ATTRIBUTE_UNUSED,
6958 int ignore ATTRIBUTE_UNUSED)
6960 return NULL_RTX;
6963 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
6965 void
6966 purge_builtin_constant_p (void)
6968 rtx insn, set, arg, new, note;
6970 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6971 if (INSN_P (insn)
6972 && (set = single_set (insn)) != NULL_RTX
6973 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6974 || (GET_CODE (arg) == SUBREG
6975 && (GET_CODE (arg = SUBREG_REG (arg))
6976 == CONSTANT_P_RTX))))
6978 arg = XEXP (arg, 0);
6979 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6980 validate_change (insn, &SET_SRC (set), new, 0);
6982 /* Remove the REG_EQUAL note from the insn. */
6983 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6984 remove_note (insn, note);
6988 /* Returns true is EXP represents data that would potentially reside
6989 in a readonly section. */
6991 static bool
6992 readonly_data_expr (tree exp)
6994 STRIP_NOPS (exp);
6996 if (TREE_CODE (exp) == ADDR_EXPR)
6997 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
6998 else
6999 return false;