2004-02-11 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / builtins.c
bloba5520a3b97c4dd0a9062487fd4c22f5849d961be
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 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 rtx expand_builtin_signbit (tree, rtx);
156 static tree fold_builtin_cabs (tree, tree, tree);
157 static tree fold_builtin_trunc (tree);
158 static tree fold_builtin_floor (tree);
159 static tree fold_builtin_ceil (tree);
160 static tree fold_builtin_round (tree);
161 static tree fold_builtin_bitop (tree);
162 static tree fold_builtin_memcpy (tree);
163 static tree fold_builtin_mempcpy (tree);
164 static tree fold_builtin_memmove (tree);
165 static tree fold_builtin_strcpy (tree);
166 static tree fold_builtin_strncpy (tree);
167 static tree fold_builtin_memcmp (tree);
168 static tree fold_builtin_strcmp (tree);
169 static tree fold_builtin_strncmp (tree);
170 static tree fold_builtin_signbit (tree);
172 /* Return the alignment in bits of EXP, a pointer valued expression.
173 But don't return more than MAX_ALIGN no matter what.
174 The alignment returned is, by default, the alignment of the thing that
175 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
177 Otherwise, look at the expression to see if we can do better, i.e., if the
178 expression is actually pointing at an object whose alignment is tighter. */
180 static int
181 get_pointer_alignment (tree exp, unsigned int max_align)
183 unsigned int align, inner;
185 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
186 return 0;
188 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
189 align = MIN (align, max_align);
191 while (1)
193 switch (TREE_CODE (exp))
195 case NOP_EXPR:
196 case CONVERT_EXPR:
197 case NON_LVALUE_EXPR:
198 exp = TREE_OPERAND (exp, 0);
199 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
200 return align;
202 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
203 align = MIN (inner, max_align);
204 break;
206 case PLUS_EXPR:
207 /* If sum of pointer + int, restrict our maximum alignment to that
208 imposed by the integer. If not, we can't do any better than
209 ALIGN. */
210 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
211 return align;
213 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
214 & (max_align / BITS_PER_UNIT - 1))
215 != 0)
216 max_align >>= 1;
218 exp = TREE_OPERAND (exp, 0);
219 break;
221 case ADDR_EXPR:
222 /* See what we are pointing at and look at its alignment. */
223 exp = TREE_OPERAND (exp, 0);
224 if (TREE_CODE (exp) == FUNCTION_DECL)
225 align = FUNCTION_BOUNDARY;
226 else if (DECL_P (exp))
227 align = DECL_ALIGN (exp);
228 #ifdef CONSTANT_ALIGNMENT
229 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
230 align = CONSTANT_ALIGNMENT (exp, align);
231 #endif
232 return MIN (align, max_align);
234 default:
235 return align;
240 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
241 way, because it could contain a zero byte in the middle.
242 TREE_STRING_LENGTH is the size of the character array, not the string.
244 ONLY_VALUE should be nonzero if the result is not going to be emitted
245 into the instruction stream and zero if it is going to be expanded.
246 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
247 is returned, otherwise NULL, since
248 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
249 evaluate the side-effects.
251 The value returned is of type `ssizetype'.
253 Unfortunately, string_constant can't access the values of const char
254 arrays with initializers, so neither can we do so here. */
256 static tree
257 c_strlen (tree src, int only_value)
259 tree offset_node;
260 HOST_WIDE_INT offset;
261 int max;
262 const char *ptr;
264 STRIP_NOPS (src);
265 if (TREE_CODE (src) == COND_EXPR
266 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
268 tree len1, len2;
270 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
271 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
272 if (tree_int_cst_equal (len1, len2))
273 return len1;
276 if (TREE_CODE (src) == COMPOUND_EXPR
277 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
278 return c_strlen (TREE_OPERAND (src, 1), only_value);
280 src = string_constant (src, &offset_node);
281 if (src == 0)
282 return 0;
284 max = TREE_STRING_LENGTH (src) - 1;
285 ptr = TREE_STRING_POINTER (src);
287 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
289 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
290 compute the offset to the following null if we don't know where to
291 start searching for it. */
292 int i;
294 for (i = 0; i < max; i++)
295 if (ptr[i] == 0)
296 return 0;
298 /* We don't know the starting offset, but we do know that the string
299 has no internal zero bytes. We can assume that the offset falls
300 within the bounds of the string; otherwise, the programmer deserves
301 what he gets. Subtract the offset from the length of the string,
302 and return that. This would perhaps not be valid if we were dealing
303 with named arrays in addition to literal string constants. */
305 return size_diffop (size_int (max), offset_node);
308 /* We have a known offset into the string. Start searching there for
309 a null character if we can represent it as a single HOST_WIDE_INT. */
310 if (offset_node == 0)
311 offset = 0;
312 else if (! host_integerp (offset_node, 0))
313 offset = -1;
314 else
315 offset = tree_low_cst (offset_node, 0);
317 /* If the offset is known to be out of bounds, warn, and call strlen at
318 runtime. */
319 if (offset < 0 || offset > max)
321 warning ("offset outside bounds of constant string");
322 return 0;
325 /* Use strlen to search for the first zero byte. Since any strings
326 constructed with build_string will have nulls appended, we win even
327 if we get handed something like (char[4])"abcd".
329 Since OFFSET is our starting index into the string, no further
330 calculation is needed. */
331 return ssize_int (strlen (ptr + offset));
334 /* Return a char pointer for a C string if it is a string constant
335 or sum of string constant and integer constant. */
337 static const char *
338 c_getstr (tree src)
340 tree offset_node;
342 src = string_constant (src, &offset_node);
343 if (src == 0)
344 return 0;
346 if (offset_node == 0)
347 return TREE_STRING_POINTER (src);
348 else if (!host_integerp (offset_node, 1)
349 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
350 return 0;
352 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
355 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
356 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
358 static rtx
359 c_readstr (const char *str, enum machine_mode mode)
361 HOST_WIDE_INT c[2];
362 HOST_WIDE_INT ch;
363 unsigned int i, j;
365 if (GET_MODE_CLASS (mode) != MODE_INT)
366 abort ();
367 c[0] = 0;
368 c[1] = 0;
369 ch = 1;
370 for (i = 0; i < GET_MODE_SIZE (mode); i++)
372 j = i;
373 if (WORDS_BIG_ENDIAN)
374 j = GET_MODE_SIZE (mode) - i - 1;
375 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
376 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
377 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
378 j *= BITS_PER_UNIT;
379 if (j > 2 * HOST_BITS_PER_WIDE_INT)
380 abort ();
381 if (ch)
382 ch = (unsigned char) str[i];
383 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
385 return immed_double_const (c[0], c[1], mode);
388 /* Cast a target constant CST to target CHAR and if that value fits into
389 host char type, return zero and put that value into variable pointed by
390 P. */
392 static int
393 target_char_cast (tree cst, char *p)
395 unsigned HOST_WIDE_INT val, hostval;
397 if (!host_integerp (cst, 1)
398 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
399 return 1;
401 val = tree_low_cst (cst, 1);
402 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
403 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
405 hostval = val;
406 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
407 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
409 if (val != hostval)
410 return 1;
412 *p = hostval;
413 return 0;
416 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
417 times to get the address of either a higher stack frame, or a return
418 address located within it (depending on FNDECL_CODE). */
421 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
422 rtx tem)
424 int i;
426 /* Some machines need special handling before we can access
427 arbitrary frames. For example, on the sparc, we must first flush
428 all register windows to the stack. */
429 #ifdef SETUP_FRAME_ADDRESSES
430 if (count > 0)
431 SETUP_FRAME_ADDRESSES ();
432 #endif
434 /* On the sparc, the return address is not in the frame, it is in a
435 register. There is no way to access it off of the current frame
436 pointer, but it can be accessed off the previous frame pointer by
437 reading the value from the register window save area. */
438 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
439 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
440 count--;
441 #endif
443 /* Scan back COUNT frames to the specified frame. */
444 for (i = 0; i < count; i++)
446 /* Assume the dynamic chain pointer is in the word that the
447 frame address points to, unless otherwise specified. */
448 #ifdef DYNAMIC_CHAIN_ADDRESS
449 tem = DYNAMIC_CHAIN_ADDRESS (tem);
450 #endif
451 tem = memory_address (Pmode, tem);
452 tem = gen_rtx_MEM (Pmode, tem);
453 set_mem_alias_set (tem, get_frame_alias_set ());
454 tem = copy_to_reg (tem);
457 /* For __builtin_frame_address, return what we've got. */
458 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
459 return tem;
461 /* For __builtin_return_address, Get the return address from that
462 frame. */
463 #ifdef RETURN_ADDR_RTX
464 tem = RETURN_ADDR_RTX (count, tem);
465 #else
466 tem = memory_address (Pmode,
467 plus_constant (tem, GET_MODE_SIZE (Pmode)));
468 tem = gen_rtx_MEM (Pmode, tem);
469 set_mem_alias_set (tem, get_frame_alias_set ());
470 #endif
471 return tem;
474 /* Alias set used for setjmp buffer. */
475 static HOST_WIDE_INT setjmp_alias_set = -1;
477 /* Construct the leading half of a __builtin_setjmp call. Control will
478 return to RECEIVER_LABEL. This is used directly by sjlj exception
479 handling code. */
481 void
482 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
484 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
485 rtx stack_save;
486 rtx mem;
488 if (setjmp_alias_set == -1)
489 setjmp_alias_set = new_alias_set ();
491 buf_addr = convert_memory_address (Pmode, buf_addr);
493 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
495 emit_queue ();
497 /* We store the frame pointer and the address of receiver_label in
498 the buffer and use the rest of it for the stack save area, which
499 is machine-dependent. */
501 #ifndef BUILTIN_SETJMP_FRAME_VALUE
502 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
503 #endif
505 mem = gen_rtx_MEM (Pmode, buf_addr);
506 set_mem_alias_set (mem, setjmp_alias_set);
507 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
509 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
510 set_mem_alias_set (mem, setjmp_alias_set);
512 emit_move_insn (validize_mem (mem),
513 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
515 stack_save = gen_rtx_MEM (sa_mode,
516 plus_constant (buf_addr,
517 2 * GET_MODE_SIZE (Pmode)));
518 set_mem_alias_set (stack_save, setjmp_alias_set);
519 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
521 /* If there is further processing to do, do it. */
522 #ifdef HAVE_builtin_setjmp_setup
523 if (HAVE_builtin_setjmp_setup)
524 emit_insn (gen_builtin_setjmp_setup (buf_addr));
525 #endif
527 /* Tell optimize_save_area_alloca that extra work is going to
528 need to go on during alloca. */
529 current_function_calls_setjmp = 1;
531 /* Set this so all the registers get saved in our frame; we need to be
532 able to copy the saved values for any registers from frames we unwind. */
533 current_function_has_nonlocal_label = 1;
536 /* Construct the trailing part of a __builtin_setjmp call.
537 This is used directly by sjlj exception handling code. */
539 void
540 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
542 /* Clobber the FP when we get here, so we have to make sure it's
543 marked as used by this function. */
544 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
546 /* Mark the static chain as clobbered here so life information
547 doesn't get messed up for it. */
548 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
550 /* Now put in the code to restore the frame pointer, and argument
551 pointer, if needed. The code below is from expand_end_bindings
552 in stmt.c; see detailed documentation there. */
553 #ifdef HAVE_nonlocal_goto
554 if (! HAVE_nonlocal_goto)
555 #endif
556 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
558 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
559 if (fixed_regs[ARG_POINTER_REGNUM])
561 #ifdef ELIMINABLE_REGS
562 size_t i;
563 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
565 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
566 if (elim_regs[i].from == ARG_POINTER_REGNUM
567 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
568 break;
570 if (i == ARRAY_SIZE (elim_regs))
571 #endif
573 /* Now restore our arg pointer from the address at which it
574 was saved in our stack frame. */
575 emit_move_insn (virtual_incoming_args_rtx,
576 copy_to_reg (get_arg_pointer_save_area (cfun)));
579 #endif
581 #ifdef HAVE_builtin_setjmp_receiver
582 if (HAVE_builtin_setjmp_receiver)
583 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
584 else
585 #endif
586 #ifdef HAVE_nonlocal_goto_receiver
587 if (HAVE_nonlocal_goto_receiver)
588 emit_insn (gen_nonlocal_goto_receiver ());
589 else
590 #endif
591 { /* Nothing */ }
593 /* @@@ This is a kludge. Not all machine descriptions define a blockage
594 insn, but we must not allow the code we just generated to be reordered
595 by scheduling. Specifically, the update of the frame pointer must
596 happen immediately, not later. So emit an ASM_INPUT to act as blockage
597 insn. */
598 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
601 /* __builtin_setjmp is passed a pointer to an array of five words (not
602 all will be used on all machines). It operates similarly to the C
603 library function of the same name, but is more efficient. Much of
604 the code below (and for longjmp) is copied from the handling of
605 non-local gotos.
607 NOTE: This is intended for use by GNAT and the exception handling
608 scheme in the compiler and will only work in the method used by
609 them. */
611 static rtx
612 expand_builtin_setjmp (tree arglist, rtx target)
614 rtx buf_addr, next_lab, cont_lab;
616 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
617 return NULL_RTX;
619 if (target == 0 || GET_CODE (target) != REG
620 || REGNO (target) < FIRST_PSEUDO_REGISTER)
621 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
623 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
625 next_lab = gen_label_rtx ();
626 cont_lab = gen_label_rtx ();
628 expand_builtin_setjmp_setup (buf_addr, next_lab);
630 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
631 ensure that pending stack adjustments are flushed. */
632 emit_move_insn (target, const0_rtx);
633 emit_jump (cont_lab);
635 emit_label (next_lab);
637 expand_builtin_setjmp_receiver (next_lab);
639 /* Set TARGET to one. */
640 emit_move_insn (target, const1_rtx);
641 emit_label (cont_lab);
643 /* Tell flow about the strange goings on. Putting `next_lab' on
644 `nonlocal_goto_handler_labels' to indicates that function
645 calls may traverse the arc back to this label. */
647 current_function_has_nonlocal_label = 1;
648 nonlocal_goto_handler_labels
649 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
651 return target;
654 /* __builtin_longjmp is passed a pointer to an array of five words (not
655 all will be used on all machines). It operates similarly to the C
656 library function of the same name, but is more efficient. Much of
657 the code below is copied from the handling of non-local gotos.
659 NOTE: This is intended for use by GNAT and the exception handling
660 scheme in the compiler and will only work in the method used by
661 them. */
663 void
664 expand_builtin_longjmp (rtx buf_addr, rtx value)
666 rtx fp, lab, stack, insn, last;
667 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
669 if (setjmp_alias_set == -1)
670 setjmp_alias_set = new_alias_set ();
672 buf_addr = convert_memory_address (Pmode, buf_addr);
674 buf_addr = force_reg (Pmode, buf_addr);
676 /* We used to store value in static_chain_rtx, but that fails if pointers
677 are smaller than integers. We instead require that the user must pass
678 a second argument of 1, because that is what builtin_setjmp will
679 return. This also makes EH slightly more efficient, since we are no
680 longer copying around a value that we don't care about. */
681 if (value != const1_rtx)
682 abort ();
684 current_function_calls_longjmp = 1;
686 last = get_last_insn ();
687 #ifdef HAVE_builtin_longjmp
688 if (HAVE_builtin_longjmp)
689 emit_insn (gen_builtin_longjmp (buf_addr));
690 else
691 #endif
693 fp = gen_rtx_MEM (Pmode, buf_addr);
694 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
695 GET_MODE_SIZE (Pmode)));
697 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
698 2 * GET_MODE_SIZE (Pmode)));
699 set_mem_alias_set (fp, setjmp_alias_set);
700 set_mem_alias_set (lab, setjmp_alias_set);
701 set_mem_alias_set (stack, setjmp_alias_set);
703 /* Pick up FP, label, and SP from the block and jump. This code is
704 from expand_goto in stmt.c; see there for detailed comments. */
705 #if HAVE_nonlocal_goto
706 if (HAVE_nonlocal_goto)
707 /* We have to pass a value to the nonlocal_goto pattern that will
708 get copied into the static_chain pointer, but it does not matter
709 what that value is, because builtin_setjmp does not use it. */
710 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
711 else
712 #endif
714 lab = copy_to_reg (lab);
716 emit_insn (gen_rtx_CLOBBER (VOIDmode,
717 gen_rtx_MEM (BLKmode,
718 gen_rtx_SCRATCH (VOIDmode))));
719 emit_insn (gen_rtx_CLOBBER (VOIDmode,
720 gen_rtx_MEM (BLKmode,
721 hard_frame_pointer_rtx)));
723 emit_move_insn (hard_frame_pointer_rtx, fp);
724 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
726 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
727 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
728 emit_indirect_jump (lab);
732 /* Search backwards and mark the jump insn as a non-local goto.
733 Note that this precludes the use of __builtin_longjmp to a
734 __builtin_setjmp target in the same function. However, we've
735 already cautioned the user that these functions are for
736 internal exception handling use only. */
737 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
739 if (insn == last)
740 abort ();
741 if (GET_CODE (insn) == JUMP_INSN)
743 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
744 REG_NOTES (insn));
745 break;
747 else if (GET_CODE (insn) == CALL_INSN)
748 break;
752 /* Expand a call to __builtin_prefetch. For a target that does not support
753 data prefetch, evaluate the memory address argument in case it has side
754 effects. */
756 static void
757 expand_builtin_prefetch (tree arglist)
759 tree arg0, arg1, arg2;
760 rtx op0, op1, op2;
762 if (!validate_arglist (arglist, POINTER_TYPE, 0))
763 return;
765 arg0 = TREE_VALUE (arglist);
766 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
767 zero (read) and argument 2 (locality) defaults to 3 (high degree of
768 locality). */
769 if (TREE_CHAIN (arglist))
771 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
772 if (TREE_CHAIN (TREE_CHAIN (arglist)))
773 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
774 else
775 arg2 = build_int_2 (3, 0);
777 else
779 arg1 = integer_zero_node;
780 arg2 = build_int_2 (3, 0);
783 /* Argument 0 is an address. */
784 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
786 /* Argument 1 (read/write flag) must be a compile-time constant int. */
787 if (TREE_CODE (arg1) != INTEGER_CST)
789 error ("second arg to `__builtin_prefetch' must be a constant");
790 arg1 = integer_zero_node;
792 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
793 /* Argument 1 must be either zero or one. */
794 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
796 warning ("invalid second arg to __builtin_prefetch; using zero");
797 op1 = const0_rtx;
800 /* Argument 2 (locality) must be a compile-time constant int. */
801 if (TREE_CODE (arg2) != INTEGER_CST)
803 error ("third arg to `__builtin_prefetch' must be a constant");
804 arg2 = integer_zero_node;
806 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
807 /* Argument 2 must be 0, 1, 2, or 3. */
808 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
810 warning ("invalid third arg to __builtin_prefetch; using zero");
811 op2 = const0_rtx;
814 #ifdef HAVE_prefetch
815 if (HAVE_prefetch)
817 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
818 (op0,
819 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
820 || (GET_MODE (op0) != Pmode))
822 op0 = convert_memory_address (Pmode, op0);
823 op0 = force_reg (Pmode, op0);
825 emit_insn (gen_prefetch (op0, op1, op2));
827 else
828 #endif
829 op0 = protect_from_queue (op0, 0);
830 /* Don't do anything with direct references to volatile memory, but
831 generate code to handle other side effects. */
832 if (GET_CODE (op0) != MEM && side_effects_p (op0))
833 emit_insn (op0);
836 /* Get a MEM rtx for expression EXP which is the address of an operand
837 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
839 static rtx
840 get_memory_rtx (tree exp)
842 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
843 rtx mem;
845 addr = convert_memory_address (Pmode, addr);
847 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
849 /* Get an expression we can use to find the attributes to assign to MEM.
850 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
851 we can. First remove any nops. */
852 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
853 || TREE_CODE (exp) == NON_LVALUE_EXPR)
854 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
855 exp = TREE_OPERAND (exp, 0);
857 if (TREE_CODE (exp) == ADDR_EXPR)
859 exp = TREE_OPERAND (exp, 0);
860 set_mem_attributes (mem, exp, 0);
862 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
864 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
865 /* memcpy, memset and other builtin stringops can alias with anything. */
866 set_mem_alias_set (mem, 0);
869 return mem;
872 /* Built-in functions to perform an untyped call and return. */
874 /* For each register that may be used for calling a function, this
875 gives a mode used to copy the register's value. VOIDmode indicates
876 the register is not used for calling a function. If the machine
877 has register windows, this gives only the outbound registers.
878 INCOMING_REGNO gives the corresponding inbound register. */
879 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
881 /* For each register that may be used for returning values, this gives
882 a mode used to copy the register's value. VOIDmode indicates the
883 register is not used for returning values. If the machine has
884 register windows, this gives only the outbound registers.
885 INCOMING_REGNO gives the corresponding inbound register. */
886 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
888 /* For each register that may be used for calling a function, this
889 gives the offset of that register into the block returned by
890 __builtin_apply_args. 0 indicates that the register is not
891 used for calling a function. */
892 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
894 /* Return the offset of register REGNO into the block returned by
895 __builtin_apply_args. This is not declared static, since it is
896 needed in objc-act.c. */
899 apply_args_register_offset (int regno)
901 apply_args_size ();
903 /* Arguments are always put in outgoing registers (in the argument
904 block) if such make sense. */
905 #ifdef OUTGOING_REGNO
906 regno = OUTGOING_REGNO (regno);
907 #endif
908 return apply_args_reg_offset[regno];
911 /* Return the size required for the block returned by __builtin_apply_args,
912 and initialize apply_args_mode. */
914 static int
915 apply_args_size (void)
917 static int size = -1;
918 int align;
919 unsigned int regno;
920 enum machine_mode mode;
922 /* The values computed by this function never change. */
923 if (size < 0)
925 /* The first value is the incoming arg-pointer. */
926 size = GET_MODE_SIZE (Pmode);
928 /* The second value is the structure value address unless this is
929 passed as an "invisible" first argument. */
930 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
931 size += GET_MODE_SIZE (Pmode);
933 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
934 if (FUNCTION_ARG_REGNO_P (regno))
936 /* Search for the proper mode for copying this register's
937 value. I'm not sure this is right, but it works so far. */
938 enum machine_mode best_mode = VOIDmode;
940 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
941 mode != VOIDmode;
942 mode = GET_MODE_WIDER_MODE (mode))
943 if (HARD_REGNO_MODE_OK (regno, mode)
944 && hard_regno_nregs[regno][mode] == 1)
945 best_mode = mode;
947 if (best_mode == VOIDmode)
948 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
949 mode != VOIDmode;
950 mode = GET_MODE_WIDER_MODE (mode))
951 if (HARD_REGNO_MODE_OK (regno, mode)
952 && have_insn_for (SET, mode))
953 best_mode = mode;
955 if (best_mode == VOIDmode)
956 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
957 mode != VOIDmode;
958 mode = GET_MODE_WIDER_MODE (mode))
959 if (HARD_REGNO_MODE_OK (regno, mode)
960 && have_insn_for (SET, mode))
961 best_mode = mode;
963 if (best_mode == VOIDmode)
964 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
965 mode != VOIDmode;
966 mode = GET_MODE_WIDER_MODE (mode))
967 if (HARD_REGNO_MODE_OK (regno, mode)
968 && have_insn_for (SET, mode))
969 best_mode = mode;
971 mode = best_mode;
972 if (mode == VOIDmode)
973 abort ();
975 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
976 if (size % align != 0)
977 size = CEIL (size, align) * align;
978 apply_args_reg_offset[regno] = size;
979 size += GET_MODE_SIZE (mode);
980 apply_args_mode[regno] = mode;
982 else
984 apply_args_mode[regno] = VOIDmode;
985 apply_args_reg_offset[regno] = 0;
988 return size;
991 /* Return the size required for the block returned by __builtin_apply,
992 and initialize apply_result_mode. */
994 static int
995 apply_result_size (void)
997 static int size = -1;
998 int align, regno;
999 enum machine_mode mode;
1001 /* The values computed by this function never change. */
1002 if (size < 0)
1004 size = 0;
1006 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1007 if (FUNCTION_VALUE_REGNO_P (regno))
1009 /* Search for the proper mode for copying this register's
1010 value. I'm not sure this is right, but it works so far. */
1011 enum machine_mode best_mode = VOIDmode;
1013 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1014 mode != TImode;
1015 mode = GET_MODE_WIDER_MODE (mode))
1016 if (HARD_REGNO_MODE_OK (regno, mode))
1017 best_mode = mode;
1019 if (best_mode == VOIDmode)
1020 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1021 mode != VOIDmode;
1022 mode = GET_MODE_WIDER_MODE (mode))
1023 if (HARD_REGNO_MODE_OK (regno, mode)
1024 && have_insn_for (SET, mode))
1025 best_mode = mode;
1027 if (best_mode == VOIDmode)
1028 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1029 mode != VOIDmode;
1030 mode = GET_MODE_WIDER_MODE (mode))
1031 if (HARD_REGNO_MODE_OK (regno, mode)
1032 && have_insn_for (SET, mode))
1033 best_mode = mode;
1035 if (best_mode == VOIDmode)
1036 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1037 mode != VOIDmode;
1038 mode = GET_MODE_WIDER_MODE (mode))
1039 if (HARD_REGNO_MODE_OK (regno, mode)
1040 && have_insn_for (SET, mode))
1041 best_mode = mode;
1043 mode = best_mode;
1044 if (mode == VOIDmode)
1045 abort ();
1047 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1048 if (size % align != 0)
1049 size = CEIL (size, align) * align;
1050 size += GET_MODE_SIZE (mode);
1051 apply_result_mode[regno] = mode;
1053 else
1054 apply_result_mode[regno] = VOIDmode;
1056 /* Allow targets that use untyped_call and untyped_return to override
1057 the size so that machine-specific information can be stored here. */
1058 #ifdef APPLY_RESULT_SIZE
1059 size = APPLY_RESULT_SIZE;
1060 #endif
1062 return size;
1065 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1066 /* Create a vector describing the result block RESULT. If SAVEP is true,
1067 the result block is used to save the values; otherwise it is used to
1068 restore the values. */
1070 static rtx
1071 result_vector (int savep, rtx result)
1073 int regno, size, align, nelts;
1074 enum machine_mode mode;
1075 rtx reg, mem;
1076 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1078 size = nelts = 0;
1079 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1080 if ((mode = apply_result_mode[regno]) != VOIDmode)
1082 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1083 if (size % align != 0)
1084 size = CEIL (size, align) * align;
1085 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1086 mem = adjust_address (result, mode, size);
1087 savevec[nelts++] = (savep
1088 ? gen_rtx_SET (VOIDmode, mem, reg)
1089 : gen_rtx_SET (VOIDmode, reg, mem));
1090 size += GET_MODE_SIZE (mode);
1092 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1094 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1096 /* Save the state required to perform an untyped call with the same
1097 arguments as were passed to the current function. */
1099 static rtx
1100 expand_builtin_apply_args_1 (void)
1102 rtx registers, tem;
1103 int size, align, regno;
1104 enum machine_mode mode;
1105 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1107 /* Create a block where the arg-pointer, structure value address,
1108 and argument registers can be saved. */
1109 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1111 /* Walk past the arg-pointer and structure value address. */
1112 size = GET_MODE_SIZE (Pmode);
1113 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1114 size += GET_MODE_SIZE (Pmode);
1116 /* Save each register used in calling a function to the block. */
1117 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1118 if ((mode = apply_args_mode[regno]) != VOIDmode)
1120 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1121 if (size % align != 0)
1122 size = CEIL (size, align) * align;
1124 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1126 emit_move_insn (adjust_address (registers, mode, size), tem);
1127 size += GET_MODE_SIZE (mode);
1130 /* Save the arg pointer to the block. */
1131 tem = copy_to_reg (virtual_incoming_args_rtx);
1132 #ifdef STACK_GROWS_DOWNWARD
1133 /* We need the pointer as the caller actually passed them to us, not
1134 as we might have pretended they were passed. Make sure it's a valid
1135 operand, as emit_move_insn isn't expected to handle a PLUS. */
1137 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1138 NULL_RTX);
1139 #endif
1140 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1142 size = GET_MODE_SIZE (Pmode);
1144 /* Save the structure value address unless this is passed as an
1145 "invisible" first argument. */
1146 if (struct_incoming_value)
1148 emit_move_insn (adjust_address (registers, Pmode, size),
1149 copy_to_reg (struct_incoming_value));
1150 size += GET_MODE_SIZE (Pmode);
1153 /* Return the address of the block. */
1154 return copy_addr_to_reg (XEXP (registers, 0));
1157 /* __builtin_apply_args returns block of memory allocated on
1158 the stack into which is stored the arg pointer, structure
1159 value address, static chain, and all the registers that might
1160 possibly be used in performing a function call. The code is
1161 moved to the start of the function so the incoming values are
1162 saved. */
1164 static rtx
1165 expand_builtin_apply_args (void)
1167 /* Don't do __builtin_apply_args more than once in a function.
1168 Save the result of the first call and reuse it. */
1169 if (apply_args_value != 0)
1170 return apply_args_value;
1172 /* When this function is called, it means that registers must be
1173 saved on entry to this function. So we migrate the
1174 call to the first insn of this function. */
1175 rtx temp;
1176 rtx seq;
1178 start_sequence ();
1179 temp = expand_builtin_apply_args_1 ();
1180 seq = get_insns ();
1181 end_sequence ();
1183 apply_args_value = temp;
1185 /* Put the insns after the NOTE that starts the function.
1186 If this is inside a start_sequence, make the outer-level insn
1187 chain current, so the code is placed at the start of the
1188 function. */
1189 push_topmost_sequence ();
1190 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1191 pop_topmost_sequence ();
1192 return temp;
1196 /* Perform an untyped call and save the state required to perform an
1197 untyped return of whatever value was returned by the given function. */
1199 static rtx
1200 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1202 int size, align, regno;
1203 enum machine_mode mode;
1204 rtx incoming_args, result, reg, dest, src, call_insn;
1205 rtx old_stack_level = 0;
1206 rtx call_fusage = 0;
1207 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1209 arguments = convert_memory_address (Pmode, arguments);
1211 /* Create a block where the return registers can be saved. */
1212 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1214 /* Fetch the arg pointer from the ARGUMENTS block. */
1215 incoming_args = gen_reg_rtx (Pmode);
1216 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1217 #ifndef STACK_GROWS_DOWNWARD
1218 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1219 incoming_args, 0, OPTAB_LIB_WIDEN);
1220 #endif
1222 /* Perform postincrements before actually calling the function. */
1223 emit_queue ();
1225 /* Push a new argument block and copy the arguments. Do not allow
1226 the (potential) memcpy call below to interfere with our stack
1227 manipulations. */
1228 do_pending_stack_adjust ();
1229 NO_DEFER_POP;
1231 /* Save the stack with nonlocal if available. */
1232 #ifdef HAVE_save_stack_nonlocal
1233 if (HAVE_save_stack_nonlocal)
1234 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1235 else
1236 #endif
1237 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1239 /* Allocate a block of memory onto the stack and copy the memory
1240 arguments to the outgoing arguments address. */
1241 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1242 dest = virtual_outgoing_args_rtx;
1243 #ifndef STACK_GROWS_DOWNWARD
1244 if (GET_CODE (argsize) == CONST_INT)
1245 dest = plus_constant (dest, -INTVAL (argsize));
1246 else
1247 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1248 #endif
1249 dest = gen_rtx_MEM (BLKmode, dest);
1250 set_mem_align (dest, PARM_BOUNDARY);
1251 src = gen_rtx_MEM (BLKmode, incoming_args);
1252 set_mem_align (src, PARM_BOUNDARY);
1253 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1255 /* Refer to the argument block. */
1256 apply_args_size ();
1257 arguments = gen_rtx_MEM (BLKmode, arguments);
1258 set_mem_align (arguments, PARM_BOUNDARY);
1260 /* Walk past the arg-pointer and structure value address. */
1261 size = GET_MODE_SIZE (Pmode);
1262 if (struct_value)
1263 size += GET_MODE_SIZE (Pmode);
1265 /* Restore each of the registers previously saved. Make USE insns
1266 for each of these registers for use in making the call. */
1267 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1268 if ((mode = apply_args_mode[regno]) != VOIDmode)
1270 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1271 if (size % align != 0)
1272 size = CEIL (size, align) * align;
1273 reg = gen_rtx_REG (mode, regno);
1274 emit_move_insn (reg, adjust_address (arguments, mode, size));
1275 use_reg (&call_fusage, reg);
1276 size += GET_MODE_SIZE (mode);
1279 /* Restore the structure value address unless this is passed as an
1280 "invisible" first argument. */
1281 size = GET_MODE_SIZE (Pmode);
1282 if (struct_value)
1284 rtx value = gen_reg_rtx (Pmode);
1285 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1286 emit_move_insn (struct_value, value);
1287 if (GET_CODE (struct_value) == REG)
1288 use_reg (&call_fusage, struct_value);
1289 size += GET_MODE_SIZE (Pmode);
1292 /* All arguments and registers used for the call are set up by now! */
1293 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1295 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1296 and we don't want to load it into a register as an optimization,
1297 because prepare_call_address already did it if it should be done. */
1298 if (GET_CODE (function) != SYMBOL_REF)
1299 function = memory_address (FUNCTION_MODE, function);
1301 /* Generate the actual call instruction and save the return value. */
1302 #ifdef HAVE_untyped_call
1303 if (HAVE_untyped_call)
1304 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1305 result, result_vector (1, result)));
1306 else
1307 #endif
1308 #ifdef HAVE_call_value
1309 if (HAVE_call_value)
1311 rtx valreg = 0;
1313 /* Locate the unique return register. It is not possible to
1314 express a call that sets more than one return register using
1315 call_value; use untyped_call for that. In fact, untyped_call
1316 only needs to save the return registers in the given block. */
1317 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1318 if ((mode = apply_result_mode[regno]) != VOIDmode)
1320 if (valreg)
1321 abort (); /* HAVE_untyped_call required. */
1322 valreg = gen_rtx_REG (mode, regno);
1325 emit_call_insn (GEN_CALL_VALUE (valreg,
1326 gen_rtx_MEM (FUNCTION_MODE, function),
1327 const0_rtx, NULL_RTX, const0_rtx));
1329 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1331 else
1332 #endif
1333 abort ();
1335 /* Find the CALL insn we just emitted, and attach the register usage
1336 information. */
1337 call_insn = last_call_insn ();
1338 add_function_usage_to (call_insn, call_fusage);
1340 /* Restore the stack. */
1341 #ifdef HAVE_save_stack_nonlocal
1342 if (HAVE_save_stack_nonlocal)
1343 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1344 else
1345 #endif
1346 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1348 OK_DEFER_POP;
1350 /* Return the address of the result block. */
1351 result = copy_addr_to_reg (XEXP (result, 0));
1352 return convert_memory_address (ptr_mode, result);
1355 /* Perform an untyped return. */
1357 static void
1358 expand_builtin_return (rtx result)
1360 int size, align, regno;
1361 enum machine_mode mode;
1362 rtx reg;
1363 rtx call_fusage = 0;
1365 result = convert_memory_address (Pmode, result);
1367 apply_result_size ();
1368 result = gen_rtx_MEM (BLKmode, result);
1370 #ifdef HAVE_untyped_return
1371 if (HAVE_untyped_return)
1373 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1374 emit_barrier ();
1375 return;
1377 #endif
1379 /* Restore the return value and note that each value is used. */
1380 size = 0;
1381 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1382 if ((mode = apply_result_mode[regno]) != VOIDmode)
1384 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1385 if (size % align != 0)
1386 size = CEIL (size, align) * align;
1387 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1388 emit_move_insn (reg, adjust_address (result, mode, size));
1390 push_to_sequence (call_fusage);
1391 emit_insn (gen_rtx_USE (VOIDmode, reg));
1392 call_fusage = get_insns ();
1393 end_sequence ();
1394 size += GET_MODE_SIZE (mode);
1397 /* Put the USE insns before the return. */
1398 emit_insn (call_fusage);
1400 /* Return whatever values was restored by jumping directly to the end
1401 of the function. */
1402 expand_naked_return ();
1405 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1407 static enum type_class
1408 type_to_class (tree type)
1410 switch (TREE_CODE (type))
1412 case VOID_TYPE: return void_type_class;
1413 case INTEGER_TYPE: return integer_type_class;
1414 case CHAR_TYPE: return char_type_class;
1415 case ENUMERAL_TYPE: return enumeral_type_class;
1416 case BOOLEAN_TYPE: return boolean_type_class;
1417 case POINTER_TYPE: return pointer_type_class;
1418 case REFERENCE_TYPE: return reference_type_class;
1419 case OFFSET_TYPE: return offset_type_class;
1420 case REAL_TYPE: return real_type_class;
1421 case COMPLEX_TYPE: return complex_type_class;
1422 case FUNCTION_TYPE: return function_type_class;
1423 case METHOD_TYPE: return method_type_class;
1424 case RECORD_TYPE: return record_type_class;
1425 case UNION_TYPE:
1426 case QUAL_UNION_TYPE: return union_type_class;
1427 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1428 ? string_type_class : array_type_class);
1429 case SET_TYPE: return set_type_class;
1430 case FILE_TYPE: return file_type_class;
1431 case LANG_TYPE: return lang_type_class;
1432 default: return no_type_class;
1436 /* Expand a call to __builtin_classify_type with arguments found in
1437 ARGLIST. */
1439 static rtx
1440 expand_builtin_classify_type (tree arglist)
1442 if (arglist != 0)
1443 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1444 return GEN_INT (no_type_class);
1447 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1449 static rtx
1450 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1452 rtx tmp;
1454 if (arglist == 0)
1455 return const0_rtx;
1456 arglist = TREE_VALUE (arglist);
1458 /* We have taken care of the easy cases during constant folding. This
1459 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1460 get a chance to see if it can deduce whether ARGLIST is constant.
1461 If CSE isn't going to run, of course, don't bother waiting. */
1463 if (cse_not_expected)
1464 return const0_rtx;
1466 current_function_calls_constant_p = 1;
1468 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1469 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1470 return tmp;
1473 /* This helper macro, meant to be used in mathfn_built_in below,
1474 determines which among a set of three builtin math functions is
1475 appropriate for a given type mode. The `F' and `L' cases are
1476 automatically generated from the `double' case. */
1477 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1478 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1479 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1480 fcodel = BUILT_IN_MATHFN##L ; break;
1482 /* Return mathematic function equivalent to FN but operating directly
1483 on TYPE, if available. If we can't do the conversion, return zero. */
1484 tree
1485 mathfn_built_in (tree type, enum built_in_function fn)
1487 const enum machine_mode type_mode = TYPE_MODE (type);
1488 enum built_in_function fcode, fcodef, fcodel;
1490 switch (fn)
1492 CASE_MATHFN (BUILT_IN_ACOS)
1493 CASE_MATHFN (BUILT_IN_ACOSH)
1494 CASE_MATHFN (BUILT_IN_ASIN)
1495 CASE_MATHFN (BUILT_IN_ASINH)
1496 CASE_MATHFN (BUILT_IN_ATAN)
1497 CASE_MATHFN (BUILT_IN_ATAN2)
1498 CASE_MATHFN (BUILT_IN_ATANH)
1499 CASE_MATHFN (BUILT_IN_CBRT)
1500 CASE_MATHFN (BUILT_IN_CEIL)
1501 CASE_MATHFN (BUILT_IN_COPYSIGN)
1502 CASE_MATHFN (BUILT_IN_COS)
1503 CASE_MATHFN (BUILT_IN_COSH)
1504 CASE_MATHFN (BUILT_IN_DREM)
1505 CASE_MATHFN (BUILT_IN_ERF)
1506 CASE_MATHFN (BUILT_IN_ERFC)
1507 CASE_MATHFN (BUILT_IN_EXP)
1508 CASE_MATHFN (BUILT_IN_EXP10)
1509 CASE_MATHFN (BUILT_IN_EXP2)
1510 CASE_MATHFN (BUILT_IN_EXPM1)
1511 CASE_MATHFN (BUILT_IN_FABS)
1512 CASE_MATHFN (BUILT_IN_FDIM)
1513 CASE_MATHFN (BUILT_IN_FLOOR)
1514 CASE_MATHFN (BUILT_IN_FMA)
1515 CASE_MATHFN (BUILT_IN_FMAX)
1516 CASE_MATHFN (BUILT_IN_FMIN)
1517 CASE_MATHFN (BUILT_IN_FMOD)
1518 CASE_MATHFN (BUILT_IN_FREXP)
1519 CASE_MATHFN (BUILT_IN_GAMMA)
1520 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1521 CASE_MATHFN (BUILT_IN_HYPOT)
1522 CASE_MATHFN (BUILT_IN_ILOGB)
1523 CASE_MATHFN (BUILT_IN_INF)
1524 CASE_MATHFN (BUILT_IN_J0)
1525 CASE_MATHFN (BUILT_IN_J1)
1526 CASE_MATHFN (BUILT_IN_JN)
1527 CASE_MATHFN (BUILT_IN_LDEXP)
1528 CASE_MATHFN (BUILT_IN_LGAMMA)
1529 CASE_MATHFN (BUILT_IN_LLRINT)
1530 CASE_MATHFN (BUILT_IN_LLROUND)
1531 CASE_MATHFN (BUILT_IN_LOG)
1532 CASE_MATHFN (BUILT_IN_LOG10)
1533 CASE_MATHFN (BUILT_IN_LOG1P)
1534 CASE_MATHFN (BUILT_IN_LOG2)
1535 CASE_MATHFN (BUILT_IN_LOGB)
1536 CASE_MATHFN (BUILT_IN_LRINT)
1537 CASE_MATHFN (BUILT_IN_LROUND)
1538 CASE_MATHFN (BUILT_IN_MODF)
1539 CASE_MATHFN (BUILT_IN_NAN)
1540 CASE_MATHFN (BUILT_IN_NANS)
1541 CASE_MATHFN (BUILT_IN_NEARBYINT)
1542 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1543 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1544 CASE_MATHFN (BUILT_IN_POW)
1545 CASE_MATHFN (BUILT_IN_POW10)
1546 CASE_MATHFN (BUILT_IN_REMAINDER)
1547 CASE_MATHFN (BUILT_IN_REMQUO)
1548 CASE_MATHFN (BUILT_IN_RINT)
1549 CASE_MATHFN (BUILT_IN_ROUND)
1550 CASE_MATHFN (BUILT_IN_SCALB)
1551 CASE_MATHFN (BUILT_IN_SCALBLN)
1552 CASE_MATHFN (BUILT_IN_SCALBN)
1553 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1554 CASE_MATHFN (BUILT_IN_SIN)
1555 CASE_MATHFN (BUILT_IN_SINCOS)
1556 CASE_MATHFN (BUILT_IN_SINH)
1557 CASE_MATHFN (BUILT_IN_SQRT)
1558 CASE_MATHFN (BUILT_IN_TAN)
1559 CASE_MATHFN (BUILT_IN_TANH)
1560 CASE_MATHFN (BUILT_IN_TGAMMA)
1561 CASE_MATHFN (BUILT_IN_TRUNC)
1562 CASE_MATHFN (BUILT_IN_Y0)
1563 CASE_MATHFN (BUILT_IN_Y1)
1564 CASE_MATHFN (BUILT_IN_YN)
1566 default:
1567 return 0;
1570 if (type_mode == TYPE_MODE (double_type_node))
1571 return implicit_built_in_decls[fcode];
1572 else if (type_mode == TYPE_MODE (float_type_node))
1573 return implicit_built_in_decls[fcodef];
1574 else if (type_mode == TYPE_MODE (long_double_type_node))
1575 return implicit_built_in_decls[fcodel];
1576 else
1577 return 0;
1580 /* If errno must be maintained, expand the RTL to check if the result,
1581 TARGET, of a built-in function call, EXP, is NaN, and if so set
1582 errno to EDOM. */
1584 static void
1585 expand_errno_check (tree exp, rtx target)
1587 rtx lab = gen_label_rtx ();
1589 /* Test the result; if it is NaN, set errno=EDOM because
1590 the argument was not in the domain. */
1591 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1592 0, lab);
1594 #ifdef TARGET_EDOM
1595 /* If this built-in doesn't throw an exception, set errno directly. */
1596 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1598 #ifdef GEN_ERRNO_RTX
1599 rtx errno_rtx = GEN_ERRNO_RTX;
1600 #else
1601 rtx errno_rtx
1602 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1603 #endif
1604 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1605 emit_label (lab);
1606 return;
1608 #endif
1610 /* We can't set errno=EDOM directly; let the library call do it.
1611 Pop the arguments right away in case the call gets deleted. */
1612 NO_DEFER_POP;
1613 expand_call (exp, target, 0);
1614 OK_DEFER_POP;
1615 emit_label (lab);
1619 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1620 Return 0 if a normal call should be emitted rather than expanding the
1621 function in-line. EXP is the expression that is a call to the builtin
1622 function; if convenient, the result should be placed in TARGET.
1623 SUBTARGET may be used as the target for computing one of EXP's operands. */
1625 static rtx
1626 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1628 optab builtin_optab;
1629 rtx op0, insns, before_call;
1630 tree fndecl = get_callee_fndecl (exp);
1631 tree arglist = TREE_OPERAND (exp, 1);
1632 enum machine_mode mode;
1633 bool errno_set = false;
1634 tree arg, narg;
1636 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1637 return 0;
1639 arg = TREE_VALUE (arglist);
1641 switch (DECL_FUNCTION_CODE (fndecl))
1643 case BUILT_IN_SIN:
1644 case BUILT_IN_SINF:
1645 case BUILT_IN_SINL:
1646 builtin_optab = sin_optab; break;
1647 case BUILT_IN_COS:
1648 case BUILT_IN_COSF:
1649 case BUILT_IN_COSL:
1650 builtin_optab = cos_optab; break;
1651 case BUILT_IN_SQRT:
1652 case BUILT_IN_SQRTF:
1653 case BUILT_IN_SQRTL:
1654 errno_set = ! tree_expr_nonnegative_p (arg);
1655 builtin_optab = sqrt_optab;
1656 break;
1657 case BUILT_IN_EXP:
1658 case BUILT_IN_EXPF:
1659 case BUILT_IN_EXPL:
1660 errno_set = true; builtin_optab = exp_optab; break;
1661 case BUILT_IN_LOG:
1662 case BUILT_IN_LOGF:
1663 case BUILT_IN_LOGL:
1664 errno_set = true; builtin_optab = log_optab; break;
1665 case BUILT_IN_LOG10:
1666 case BUILT_IN_LOG10F:
1667 case BUILT_IN_LOG10L:
1668 errno_set = true; builtin_optab = log10_optab; break;
1669 case BUILT_IN_LOG2:
1670 case BUILT_IN_LOG2F:
1671 case BUILT_IN_LOG2L:
1672 errno_set = true; builtin_optab = log2_optab; break;
1673 case BUILT_IN_TAN:
1674 case BUILT_IN_TANF:
1675 case BUILT_IN_TANL:
1676 builtin_optab = tan_optab; break;
1677 case BUILT_IN_ATAN:
1678 case BUILT_IN_ATANF:
1679 case BUILT_IN_ATANL:
1680 builtin_optab = atan_optab; break;
1681 case BUILT_IN_FLOOR:
1682 case BUILT_IN_FLOORF:
1683 case BUILT_IN_FLOORL:
1684 builtin_optab = floor_optab; break;
1685 case BUILT_IN_CEIL:
1686 case BUILT_IN_CEILF:
1687 case BUILT_IN_CEILL:
1688 builtin_optab = ceil_optab; break;
1689 case BUILT_IN_TRUNC:
1690 case BUILT_IN_TRUNCF:
1691 case BUILT_IN_TRUNCL:
1692 builtin_optab = btrunc_optab; break;
1693 case BUILT_IN_ROUND:
1694 case BUILT_IN_ROUNDF:
1695 case BUILT_IN_ROUNDL:
1696 builtin_optab = round_optab; break;
1697 case BUILT_IN_NEARBYINT:
1698 case BUILT_IN_NEARBYINTF:
1699 case BUILT_IN_NEARBYINTL:
1700 builtin_optab = nearbyint_optab; break;
1701 default:
1702 abort ();
1705 /* Make a suitable register to place result in. */
1706 mode = TYPE_MODE (TREE_TYPE (exp));
1708 if (! flag_errno_math || ! HONOR_NANS (mode))
1709 errno_set = false;
1711 /* Before working hard, check whether the instruction is available. */
1712 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1714 target = gen_reg_rtx (mode);
1716 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1717 need to expand the argument again. This way, we will not perform
1718 side-effects more the once. */
1719 narg = save_expr (arg);
1720 if (narg != arg)
1722 arglist = build_tree_list (NULL_TREE, arg);
1723 exp = build_function_call_expr (fndecl, arglist);
1726 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1728 emit_queue ();
1729 start_sequence ();
1731 /* Compute into TARGET.
1732 Set TARGET to wherever the result comes back. */
1733 target = expand_unop (mode, builtin_optab, op0, target, 0);
1735 if (target != 0)
1737 if (errno_set)
1738 expand_errno_check (exp, target);
1740 /* Output the entire sequence. */
1741 insns = get_insns ();
1742 end_sequence ();
1743 emit_insn (insns);
1744 return target;
1747 /* If we were unable to expand via the builtin, stop the sequence
1748 (without outputting the insns) and call to the library function
1749 with the stabilized argument list. */
1750 end_sequence ();
1753 before_call = get_last_insn ();
1755 target = expand_call (exp, target, target == const0_rtx);
1757 /* If this is a sqrt operation and we don't care about errno, try to
1758 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1759 This allows the semantics of the libcall to be visible to the RTL
1760 optimizers. */
1761 if (builtin_optab == sqrt_optab && !errno_set)
1763 /* Search backwards through the insns emitted by expand_call looking
1764 for the instruction with the REG_RETVAL note. */
1765 rtx last = get_last_insn ();
1766 while (last != before_call)
1768 if (find_reg_note (last, REG_RETVAL, NULL))
1770 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1771 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1772 two elements, i.e. symbol_ref(sqrt) and the operand. */
1773 if (note
1774 && GET_CODE (note) == EXPR_LIST
1775 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1776 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1777 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1779 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1780 /* Check operand is a register with expected mode. */
1781 if (operand
1782 && GET_CODE (operand) == REG
1783 && GET_MODE (operand) == mode)
1785 /* Replace the REG_EQUAL note with a SQRT rtx. */
1786 rtx equiv = gen_rtx_SQRT (mode, operand);
1787 set_unique_reg_note (last, REG_EQUAL, equiv);
1790 break;
1792 last = PREV_INSN (last);
1796 return target;
1799 /* Expand a call to the builtin binary math functions (pow and atan2).
1800 Return 0 if a normal call should be emitted rather than expanding the
1801 function in-line. EXP is the expression that is a call to the builtin
1802 function; if convenient, the result should be placed in TARGET.
1803 SUBTARGET may be used as the target for computing one of EXP's
1804 operands. */
1806 static rtx
1807 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1809 optab builtin_optab;
1810 rtx op0, op1, insns;
1811 tree fndecl = get_callee_fndecl (exp);
1812 tree arglist = TREE_OPERAND (exp, 1);
1813 tree arg0, arg1, temp, narg;
1814 enum machine_mode mode;
1815 bool errno_set = true;
1816 bool stable = true;
1818 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1819 return 0;
1821 arg0 = TREE_VALUE (arglist);
1822 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1824 switch (DECL_FUNCTION_CODE (fndecl))
1826 case BUILT_IN_POW:
1827 case BUILT_IN_POWF:
1828 case BUILT_IN_POWL:
1829 builtin_optab = pow_optab; break;
1830 case BUILT_IN_ATAN2:
1831 case BUILT_IN_ATAN2F:
1832 case BUILT_IN_ATAN2L:
1833 builtin_optab = atan2_optab; break;
1834 default:
1835 abort ();
1838 /* Make a suitable register to place result in. */
1839 mode = TYPE_MODE (TREE_TYPE (exp));
1841 /* Before working hard, check whether the instruction is available. */
1842 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1843 return 0;
1845 target = gen_reg_rtx (mode);
1847 if (! flag_errno_math || ! HONOR_NANS (mode))
1848 errno_set = false;
1850 /* Alway stabilize the argument list. */
1851 narg = save_expr (arg1);
1852 if (narg != arg1)
1854 temp = build_tree_list (NULL_TREE, narg);
1855 stable = false;
1857 else
1858 temp = TREE_CHAIN (arglist);
1860 narg = save_expr (arg0);
1861 if (narg != arg0)
1863 arglist = tree_cons (NULL_TREE, narg, temp);
1864 stable = false;
1866 else if (! stable)
1867 arglist = tree_cons (NULL_TREE, arg0, temp);
1869 if (! stable)
1870 exp = build_function_call_expr (fndecl, arglist);
1872 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1873 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1875 emit_queue ();
1876 start_sequence ();
1878 /* Compute into TARGET.
1879 Set TARGET to wherever the result comes back. */
1880 target = expand_binop (mode, builtin_optab, op0, op1,
1881 target, 0, OPTAB_DIRECT);
1883 /* If we were unable to expand via the builtin, stop the sequence
1884 (without outputting the insns) and call to the library function
1885 with the stabilized argument list. */
1886 if (target == 0)
1888 end_sequence ();
1889 return expand_call (exp, target, target == const0_rtx);
1892 if (errno_set)
1893 expand_errno_check (exp, target);
1895 /* Output the entire sequence. */
1896 insns = get_insns ();
1897 end_sequence ();
1898 emit_insn (insns);
1900 return target;
1903 /* To evaluate powi(x,n), the floating point value x raised to the
1904 constant integer exponent n, we use a hybrid algorithm that
1905 combines the "window method" with look-up tables. For an
1906 introduction to exponentiation algorithms and "addition chains",
1907 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1908 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1909 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1910 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1912 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1913 multiplications to inline before calling the system library's pow
1914 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1915 so this default never requires calling pow, powf or powl. */
1917 #ifndef POWI_MAX_MULTS
1918 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1919 #endif
1921 /* The size of the "optimal power tree" lookup table. All
1922 exponents less than this value are simply looked up in the
1923 powi_table below. This threshold is also used to size the
1924 cache of pseudo registers that hold intermediate results. */
1925 #define POWI_TABLE_SIZE 256
1927 /* The size, in bits of the window, used in the "window method"
1928 exponentiation algorithm. This is equivalent to a radix of
1929 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1930 #define POWI_WINDOW_SIZE 3
1932 /* The following table is an efficient representation of an
1933 "optimal power tree". For each value, i, the corresponding
1934 value, j, in the table states than an optimal evaluation
1935 sequence for calculating pow(x,i) can be found by evaluating
1936 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1937 100 integers is given in Knuth's "Seminumerical algorithms". */
1939 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1941 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1942 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1943 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1944 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1945 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1946 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1947 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1948 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1949 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1950 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1951 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1952 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1953 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1954 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1955 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1956 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1957 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1958 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1959 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1960 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1961 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1962 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1963 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1964 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1965 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1966 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1967 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1968 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1969 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1970 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1971 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1972 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1976 /* Return the number of multiplications required to calculate
1977 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
1978 subroutine of powi_cost. CACHE is an array indicating
1979 which exponents have already been calculated. */
1981 static int
1982 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1984 /* If we've already calculated this exponent, then this evaluation
1985 doesn't require any additional multiplications. */
1986 if (cache[n])
1987 return 0;
1989 cache[n] = true;
1990 return powi_lookup_cost (n - powi_table[n], cache)
1991 + powi_lookup_cost (powi_table[n], cache) + 1;
1994 /* Return the number of multiplications required to calculate
1995 powi(x,n) for an arbitrary x, given the exponent N. This
1996 function needs to be kept in sync with expand_powi below. */
1998 static int
1999 powi_cost (HOST_WIDE_INT n)
2001 bool cache[POWI_TABLE_SIZE];
2002 unsigned HOST_WIDE_INT digit;
2003 unsigned HOST_WIDE_INT val;
2004 int result;
2006 if (n == 0)
2007 return 0;
2009 /* Ignore the reciprocal when calculating the cost. */
2010 val = (n < 0) ? -n : n;
2012 /* Initialize the exponent cache. */
2013 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2014 cache[1] = true;
2016 result = 0;
2018 while (val >= POWI_TABLE_SIZE)
2020 if (val & 1)
2022 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2023 result += powi_lookup_cost (digit, cache)
2024 + POWI_WINDOW_SIZE + 1;
2025 val >>= POWI_WINDOW_SIZE;
2027 else
2029 val >>= 1;
2030 result++;
2034 return result + powi_lookup_cost (val, cache);
2037 /* Recursive subroutine of expand_powi. This function takes the array,
2038 CACHE, of already calculated exponents and an exponent N and returns
2039 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2041 static rtx
2042 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2044 unsigned HOST_WIDE_INT digit;
2045 rtx target, result;
2046 rtx op0, op1;
2048 if (n < POWI_TABLE_SIZE)
2050 if (cache[n])
2051 return cache[n];
2053 target = gen_reg_rtx (mode);
2054 cache[n] = target;
2056 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2057 op1 = expand_powi_1 (mode, powi_table[n], cache);
2059 else if (n & 1)
2061 target = gen_reg_rtx (mode);
2062 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2063 op0 = expand_powi_1 (mode, n - digit, cache);
2064 op1 = expand_powi_1 (mode, digit, cache);
2066 else
2068 target = gen_reg_rtx (mode);
2069 op0 = expand_powi_1 (mode, n >> 1, cache);
2070 op1 = op0;
2073 result = expand_mult (mode, op0, op1, target, 0);
2074 if (result != target)
2075 emit_move_insn (target, result);
2076 return target;
2079 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2080 floating point operand in mode MODE, and N is the exponent. This
2081 function needs to be kept in sync with powi_cost above. */
2083 static rtx
2084 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2086 unsigned HOST_WIDE_INT val;
2087 rtx cache[POWI_TABLE_SIZE];
2088 rtx result;
2090 if (n == 0)
2091 return CONST1_RTX (mode);
2093 val = (n < 0) ? -n : n;
2095 memset (cache, 0, sizeof (cache));
2096 cache[1] = x;
2098 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2100 /* If the original exponent was negative, reciprocate the result. */
2101 if (n < 0)
2102 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2103 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2105 return result;
2108 /* Expand a call to the pow built-in mathematical function. Return 0 if
2109 a normal call should be emitted rather than expanding the function
2110 in-line. EXP is the expression that is a call to the builtin
2111 function; if convenient, the result should be placed in TARGET. */
2113 static rtx
2114 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2116 tree arglist = TREE_OPERAND (exp, 1);
2117 tree arg0, arg1;
2119 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2120 return 0;
2122 arg0 = TREE_VALUE (arglist);
2123 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2125 if (TREE_CODE (arg1) == REAL_CST
2126 && ! TREE_CONSTANT_OVERFLOW (arg1))
2128 REAL_VALUE_TYPE cint;
2129 REAL_VALUE_TYPE c;
2130 HOST_WIDE_INT n;
2132 c = TREE_REAL_CST (arg1);
2133 n = real_to_integer (&c);
2134 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2135 if (real_identical (&c, &cint))
2137 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2138 Otherwise, check the number of multiplications required.
2139 Note that pow never sets errno for an integer exponent. */
2140 if ((n >= -1 && n <= 2)
2141 || (flag_unsafe_math_optimizations
2142 && ! optimize_size
2143 && powi_cost (n) <= POWI_MAX_MULTS))
2145 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2146 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2147 op = force_reg (mode, op);
2148 return expand_powi (op, mode, n);
2153 if (! flag_unsafe_math_optimizations)
2154 return NULL_RTX;
2155 return expand_builtin_mathfn_2 (exp, target, subtarget);
2158 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2159 if we failed the caller should emit a normal call, otherwise
2160 try to get the result in TARGET, if convenient. */
2162 static rtx
2163 expand_builtin_strlen (tree arglist, rtx target,
2164 enum machine_mode target_mode)
2166 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2167 return 0;
2168 else
2170 rtx pat;
2171 tree len, src = TREE_VALUE (arglist);
2172 rtx result, src_reg, char_rtx, before_strlen;
2173 enum machine_mode insn_mode = target_mode, char_mode;
2174 enum insn_code icode = CODE_FOR_nothing;
2175 int align;
2177 /* If the length can be computed at compile-time, return it. */
2178 len = c_strlen (src, 0);
2179 if (len)
2180 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2182 /* If the length can be computed at compile-time and is constant
2183 integer, but there are side-effects in src, evaluate
2184 src for side-effects, then return len.
2185 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2186 can be optimized into: i++; x = 3; */
2187 len = c_strlen (src, 1);
2188 if (len && TREE_CODE (len) == INTEGER_CST)
2190 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2191 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2194 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2196 /* If SRC is not a pointer type, don't do this operation inline. */
2197 if (align == 0)
2198 return 0;
2200 /* Bail out if we can't compute strlen in the right mode. */
2201 while (insn_mode != VOIDmode)
2203 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2204 if (icode != CODE_FOR_nothing)
2205 break;
2207 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2209 if (insn_mode == VOIDmode)
2210 return 0;
2212 /* Make a place to write the result of the instruction. */
2213 result = target;
2214 if (! (result != 0
2215 && GET_CODE (result) == REG
2216 && GET_MODE (result) == insn_mode
2217 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2218 result = gen_reg_rtx (insn_mode);
2220 /* Make a place to hold the source address. We will not expand
2221 the actual source until we are sure that the expansion will
2222 not fail -- there are trees that cannot be expanded twice. */
2223 src_reg = gen_reg_rtx (Pmode);
2225 /* Mark the beginning of the strlen sequence so we can emit the
2226 source operand later. */
2227 before_strlen = get_last_insn ();
2229 char_rtx = const0_rtx;
2230 char_mode = insn_data[(int) icode].operand[2].mode;
2231 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2232 char_mode))
2233 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2235 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2236 char_rtx, GEN_INT (align));
2237 if (! pat)
2238 return 0;
2239 emit_insn (pat);
2241 /* Now that we are assured of success, expand the source. */
2242 start_sequence ();
2243 pat = memory_address (BLKmode,
2244 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2245 if (pat != src_reg)
2246 emit_move_insn (src_reg, pat);
2247 pat = get_insns ();
2248 end_sequence ();
2250 if (before_strlen)
2251 emit_insn_after (pat, before_strlen);
2252 else
2253 emit_insn_before (pat, get_insns ());
2255 /* Return the value in the proper mode for this function. */
2256 if (GET_MODE (result) == target_mode)
2257 target = result;
2258 else if (target != 0)
2259 convert_move (target, result, 0);
2260 else
2261 target = convert_to_mode (target_mode, result, 0);
2263 return target;
2267 /* Expand a call to the strstr builtin. Return 0 if we failed the
2268 caller should emit a normal call, otherwise try to get the result
2269 in TARGET, if convenient (and in mode MODE if that's convenient). */
2271 static rtx
2272 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2274 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2275 return 0;
2276 else
2278 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2279 tree fn;
2280 const char *p1, *p2;
2282 p2 = c_getstr (s2);
2283 if (p2 == NULL)
2284 return 0;
2286 p1 = c_getstr (s1);
2287 if (p1 != NULL)
2289 const char *r = strstr (p1, p2);
2291 if (r == NULL)
2292 return const0_rtx;
2294 /* Return an offset into the constant string argument. */
2295 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2296 s1, convert (TREE_TYPE (s1),
2297 ssize_int (r - p1)))),
2298 target, mode, EXPAND_NORMAL);
2301 if (p2[0] == '\0')
2302 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2304 if (p2[1] != '\0')
2305 return 0;
2307 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2308 if (!fn)
2309 return 0;
2311 /* New argument list transforming strstr(s1, s2) to
2312 strchr(s1, s2[0]). */
2313 arglist =
2314 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2315 arglist = tree_cons (NULL_TREE, s1, arglist);
2316 return expand_expr (build_function_call_expr (fn, arglist),
2317 target, mode, EXPAND_NORMAL);
2321 /* Expand a call to the strchr builtin. Return 0 if we failed the
2322 caller should emit a normal call, otherwise try to get the result
2323 in TARGET, if convenient (and in mode MODE if that's convenient). */
2325 static rtx
2326 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2328 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2329 return 0;
2330 else
2332 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2333 const char *p1;
2335 if (TREE_CODE (s2) != INTEGER_CST)
2336 return 0;
2338 p1 = c_getstr (s1);
2339 if (p1 != NULL)
2341 char c;
2342 const char *r;
2344 if (target_char_cast (s2, &c))
2345 return 0;
2347 r = strchr (p1, c);
2349 if (r == NULL)
2350 return const0_rtx;
2352 /* Return an offset into the constant string argument. */
2353 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2354 s1, convert (TREE_TYPE (s1),
2355 ssize_int (r - p1)))),
2356 target, mode, EXPAND_NORMAL);
2359 /* FIXME: Should use here strchrM optab so that ports can optimize
2360 this. */
2361 return 0;
2365 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2366 caller should emit a normal call, otherwise try to get the result
2367 in TARGET, if convenient (and in mode MODE if that's convenient). */
2369 static rtx
2370 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2372 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2373 return 0;
2374 else
2376 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2377 tree fn;
2378 const char *p1;
2380 if (TREE_CODE (s2) != INTEGER_CST)
2381 return 0;
2383 p1 = c_getstr (s1);
2384 if (p1 != NULL)
2386 char c;
2387 const char *r;
2389 if (target_char_cast (s2, &c))
2390 return 0;
2392 r = strrchr (p1, c);
2394 if (r == NULL)
2395 return const0_rtx;
2397 /* Return an offset into the constant string argument. */
2398 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2399 s1, convert (TREE_TYPE (s1),
2400 ssize_int (r - p1)))),
2401 target, mode, EXPAND_NORMAL);
2404 if (! integer_zerop (s2))
2405 return 0;
2407 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2408 if (!fn)
2409 return 0;
2411 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2412 return expand_expr (build_function_call_expr (fn, arglist),
2413 target, mode, EXPAND_NORMAL);
2417 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2418 caller should emit a normal call, otherwise try to get the result
2419 in TARGET, if convenient (and in mode MODE if that's convenient). */
2421 static rtx
2422 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2424 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2425 return 0;
2426 else
2428 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2429 tree fn;
2430 const char *p1, *p2;
2432 p2 = c_getstr (s2);
2433 if (p2 == NULL)
2434 return 0;
2436 p1 = c_getstr (s1);
2437 if (p1 != NULL)
2439 const char *r = strpbrk (p1, p2);
2441 if (r == NULL)
2442 return const0_rtx;
2444 /* Return an offset into the constant string argument. */
2445 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2446 s1, convert (TREE_TYPE (s1),
2447 ssize_int (r - p1)))),
2448 target, mode, EXPAND_NORMAL);
2451 if (p2[0] == '\0')
2453 /* strpbrk(x, "") == NULL.
2454 Evaluate and ignore the arguments in case they had
2455 side-effects. */
2456 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2457 return const0_rtx;
2460 if (p2[1] != '\0')
2461 return 0; /* Really call strpbrk. */
2463 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2464 if (!fn)
2465 return 0;
2467 /* New argument list transforming strpbrk(s1, s2) to
2468 strchr(s1, s2[0]). */
2469 arglist =
2470 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2471 arglist = tree_cons (NULL_TREE, s1, arglist);
2472 return expand_expr (build_function_call_expr (fn, arglist),
2473 target, mode, EXPAND_NORMAL);
2477 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2478 bytes from constant string DATA + OFFSET and return it as target
2479 constant. */
2481 static rtx
2482 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2483 enum machine_mode mode)
2485 const char *str = (const char *) data;
2487 if (offset < 0
2488 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2489 > strlen (str) + 1))
2490 abort (); /* Attempt to read past the end of constant string. */
2492 return c_readstr (str + offset, mode);
2495 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2496 Return 0 if we failed, the caller should emit a normal call,
2497 otherwise try to get the result in TARGET, if convenient (and in
2498 mode MODE if that's convenient). */
2499 static rtx
2500 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2502 if (!validate_arglist (arglist,
2503 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2504 return 0;
2505 else
2507 tree dest = TREE_VALUE (arglist);
2508 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2509 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2510 const char *src_str;
2511 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2512 unsigned int dest_align
2513 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2514 rtx dest_mem, src_mem, dest_addr, len_rtx;
2516 /* If DEST is not a pointer type, call the normal function. */
2517 if (dest_align == 0)
2518 return 0;
2520 /* If the LEN parameter is zero, return DEST. */
2521 if (integer_zerop (len))
2523 /* Evaluate and ignore SRC in case it has side-effects. */
2524 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2525 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2528 /* If SRC and DEST are the same (and not volatile), return DEST. */
2529 if (operand_equal_p (src, dest, 0))
2531 /* Evaluate and ignore LEN in case it has side-effects. */
2532 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2533 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2536 /* If either SRC is not a pointer type, don't do this
2537 operation in-line. */
2538 if (src_align == 0)
2539 return 0;
2541 dest_mem = get_memory_rtx (dest);
2542 set_mem_align (dest_mem, dest_align);
2543 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2544 src_str = c_getstr (src);
2546 /* If SRC is a string constant and block move would be done
2547 by pieces, we can avoid loading the string from memory
2548 and only stored the computed constants. */
2549 if (src_str
2550 && GET_CODE (len_rtx) == CONST_INT
2551 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2552 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2553 (void *) src_str, dest_align))
2555 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2556 builtin_memcpy_read_str,
2557 (void *) src_str, dest_align, 0);
2558 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2559 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2560 return dest_mem;
2563 src_mem = get_memory_rtx (src);
2564 set_mem_align (src_mem, src_align);
2566 /* Copy word part most expediently. */
2567 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2568 BLOCK_OP_NORMAL);
2570 if (dest_addr == 0)
2572 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2573 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2575 return dest_addr;
2579 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2580 Return 0 if we failed the caller should emit a normal call,
2581 otherwise try to get the result in TARGET, if convenient (and in
2582 mode MODE if that's convenient). If ENDP is 0 return the
2583 destination pointer, if ENDP is 1 return the end pointer ala
2584 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2585 stpcpy. */
2587 static rtx
2588 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2589 int endp)
2591 if (!validate_arglist (arglist,
2592 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2593 return 0;
2594 /* If return value is ignored, transform mempcpy into memcpy. */
2595 else if (target == const0_rtx)
2597 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2599 if (!fn)
2600 return 0;
2602 return expand_expr (build_function_call_expr (fn, arglist),
2603 target, mode, EXPAND_NORMAL);
2605 else
2607 tree dest = TREE_VALUE (arglist);
2608 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2609 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2610 const char *src_str;
2611 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2612 unsigned int dest_align
2613 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2614 rtx dest_mem, src_mem, len_rtx;
2616 /* If DEST is not a pointer type, call the normal function. */
2617 if (dest_align == 0)
2618 return 0;
2620 /* If SRC and DEST are the same (and not volatile), do nothing. */
2621 if (operand_equal_p (src, dest, 0))
2623 tree expr;
2625 if (endp == 0)
2627 /* Evaluate and ignore LEN in case it has side-effects. */
2628 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2629 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2632 if (endp == 2)
2633 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2634 integer_one_node));
2635 len = convert (TREE_TYPE (dest), len);
2636 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2637 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2640 /* If LEN is not constant, call the normal function. */
2641 if (! host_integerp (len, 1))
2642 return 0;
2644 /* If the LEN parameter is zero, return DEST. */
2645 if (tree_low_cst (len, 1) == 0)
2647 /* Evaluate and ignore SRC in case it has side-effects. */
2648 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2649 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2652 /* If either SRC is not a pointer type, don't do this
2653 operation in-line. */
2654 if (src_align == 0)
2655 return 0;
2657 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2658 src_str = c_getstr (src);
2660 /* If SRC is a string constant and block move would be done
2661 by pieces, we can avoid loading the string from memory
2662 and only stored the computed constants. */
2663 if (src_str
2664 && GET_CODE (len_rtx) == CONST_INT
2665 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2666 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2667 (void *) src_str, dest_align))
2669 dest_mem = get_memory_rtx (dest);
2670 set_mem_align (dest_mem, dest_align);
2671 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2672 builtin_memcpy_read_str,
2673 (void *) src_str, dest_align, endp);
2674 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2675 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2676 return dest_mem;
2679 if (GET_CODE (len_rtx) == CONST_INT
2680 && can_move_by_pieces (INTVAL (len_rtx),
2681 MIN (dest_align, src_align)))
2683 dest_mem = get_memory_rtx (dest);
2684 set_mem_align (dest_mem, dest_align);
2685 src_mem = get_memory_rtx (src);
2686 set_mem_align (src_mem, src_align);
2687 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2688 MIN (dest_align, src_align), endp);
2689 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2690 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2691 return dest_mem;
2694 return 0;
2698 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2699 if we failed the caller should emit a normal call. */
2701 static rtx
2702 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2704 if (!validate_arglist (arglist,
2705 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2706 return 0;
2707 else
2709 tree dest = TREE_VALUE (arglist);
2710 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2711 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2713 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2714 unsigned int dest_align
2715 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2717 /* If DEST is not a pointer type, call the normal function. */
2718 if (dest_align == 0)
2719 return 0;
2721 /* If the LEN parameter is zero, return DEST. */
2722 if (integer_zerop (len))
2724 /* Evaluate and ignore SRC in case it has side-effects. */
2725 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2726 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2729 /* If SRC and DEST are the same (and not volatile), return DEST. */
2730 if (operand_equal_p (src, dest, 0))
2732 /* Evaluate and ignore LEN in case it has side-effects. */
2733 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2734 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2737 /* If either SRC is not a pointer type, don't do this
2738 operation in-line. */
2739 if (src_align == 0)
2740 return 0;
2742 /* If src is categorized for a readonly section we can use
2743 normal memcpy. */
2744 if (readonly_data_expr (src))
2746 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2747 if (!fn)
2748 return 0;
2749 return expand_expr (build_function_call_expr (fn, arglist),
2750 target, mode, EXPAND_NORMAL);
2753 /* Otherwise, call the normal function. */
2754 return 0;
2758 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2759 if we failed the caller should emit a normal call. */
2761 static rtx
2762 expand_builtin_bcopy (tree arglist)
2764 tree src, dest, size, newarglist;
2766 if (!validate_arglist (arglist,
2767 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2768 return NULL_RTX;
2770 src = TREE_VALUE (arglist);
2771 dest = TREE_VALUE (TREE_CHAIN (arglist));
2772 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2774 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2775 memmove(ptr y, ptr x, size_t z). This is done this way
2776 so that if it isn't expanded inline, we fallback to
2777 calling bcopy instead of memmove. */
2779 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2780 newarglist = tree_cons (NULL_TREE, src, newarglist);
2781 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2783 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2786 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2787 if we failed the caller should emit a normal call, otherwise try to get
2788 the result in TARGET, if convenient (and in mode MODE if that's
2789 convenient). */
2791 static rtx
2792 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2794 tree fn, len, src, dst;
2796 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2797 return 0;
2799 src = TREE_VALUE (TREE_CHAIN (arglist));
2800 dst = TREE_VALUE (arglist);
2802 /* If SRC and DST are equal (and not volatile), return DST. */
2803 if (operand_equal_p (src, dst, 0))
2804 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2806 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2807 if (!fn)
2808 return 0;
2810 len = c_strlen (src, 1);
2811 if (len == 0 || TREE_SIDE_EFFECTS (len))
2812 return 0;
2814 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2815 arglist = build_tree_list (NULL_TREE, len);
2816 arglist = tree_cons (NULL_TREE, src, arglist);
2817 arglist = tree_cons (NULL_TREE, dst, arglist);
2818 return expand_expr (build_function_call_expr (fn, arglist),
2819 target, mode, EXPAND_NORMAL);
2822 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2823 Return 0 if we failed the caller should emit a normal call,
2824 otherwise try to get the result in TARGET, if convenient (and in
2825 mode MODE if that's convenient). */
2827 static rtx
2828 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2830 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2831 return 0;
2832 else
2834 tree dst, src, len;
2836 /* If return value is ignored, transform stpcpy into strcpy. */
2837 if (target == const0_rtx)
2839 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2840 if (!fn)
2841 return 0;
2843 return expand_expr (build_function_call_expr (fn, arglist),
2844 target, mode, EXPAND_NORMAL);
2847 /* Ensure we get an actual string whose length can be evaluated at
2848 compile-time, not an expression containing a string. This is
2849 because the latter will potentially produce pessimized code
2850 when used to produce the return value. */
2851 src = TREE_VALUE (TREE_CHAIN (arglist));
2852 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2853 return 0;
2855 dst = TREE_VALUE (arglist);
2856 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2857 arglist = build_tree_list (NULL_TREE, len);
2858 arglist = tree_cons (NULL_TREE, src, arglist);
2859 arglist = tree_cons (NULL_TREE, dst, arglist);
2860 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2864 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2865 bytes from constant string DATA + OFFSET and return it as target
2866 constant. */
2868 static rtx
2869 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2870 enum machine_mode mode)
2872 const char *str = (const char *) data;
2874 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2875 return const0_rtx;
2877 return c_readstr (str + offset, mode);
2880 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2881 if we failed the caller should emit a normal call. */
2883 static rtx
2884 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2886 if (!validate_arglist (arglist,
2887 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2888 return 0;
2889 else
2891 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2892 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2893 tree fn;
2895 /* We must be passed a constant len parameter. */
2896 if (TREE_CODE (len) != INTEGER_CST)
2897 return 0;
2899 /* If the len parameter is zero, return the dst parameter. */
2900 if (integer_zerop (len))
2902 /* Evaluate and ignore the src argument in case it has
2903 side-effects. */
2904 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2905 VOIDmode, EXPAND_NORMAL);
2906 /* Return the dst parameter. */
2907 return expand_expr (TREE_VALUE (arglist), target, mode,
2908 EXPAND_NORMAL);
2911 /* Now, we must be passed a constant src ptr parameter. */
2912 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2913 return 0;
2915 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2917 /* We're required to pad with trailing zeros if the requested
2918 len is greater than strlen(s2)+1. In that case try to
2919 use store_by_pieces, if it fails, punt. */
2920 if (tree_int_cst_lt (slen, len))
2922 tree dest = TREE_VALUE (arglist);
2923 unsigned int dest_align
2924 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2925 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2926 rtx dest_mem;
2928 if (!p || dest_align == 0 || !host_integerp (len, 1)
2929 || !can_store_by_pieces (tree_low_cst (len, 1),
2930 builtin_strncpy_read_str,
2931 (void *) p, dest_align))
2932 return 0;
2934 dest_mem = get_memory_rtx (dest);
2935 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2936 builtin_strncpy_read_str,
2937 (void *) p, dest_align, 0);
2938 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2939 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2940 return dest_mem;
2943 /* OK transform into builtin memcpy. */
2944 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2945 if (!fn)
2946 return 0;
2947 return expand_expr (build_function_call_expr (fn, arglist),
2948 target, mode, EXPAND_NORMAL);
2952 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2953 bytes from constant string DATA + OFFSET and return it as target
2954 constant. */
2956 static rtx
2957 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2958 enum machine_mode mode)
2960 const char *c = (const char *) data;
2961 char *p = alloca (GET_MODE_SIZE (mode));
2963 memset (p, *c, GET_MODE_SIZE (mode));
2965 return c_readstr (p, mode);
2968 /* Callback routine for store_by_pieces. Return the RTL of a register
2969 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2970 char value given in the RTL register data. For example, if mode is
2971 4 bytes wide, return the RTL for 0x01010101*data. */
2973 static rtx
2974 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2975 enum machine_mode mode)
2977 rtx target, coeff;
2978 size_t size;
2979 char *p;
2981 size = GET_MODE_SIZE (mode);
2982 if (size == 1)
2983 return (rtx) data;
2985 p = alloca (size);
2986 memset (p, 1, size);
2987 coeff = c_readstr (p, mode);
2989 target = convert_to_mode (mode, (rtx) data, 1);
2990 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2991 return force_reg (mode, target);
2994 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2995 if we failed the caller should emit a normal call, otherwise try to get
2996 the result in TARGET, if convenient (and in mode MODE if that's
2997 convenient). */
2999 static rtx
3000 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3002 if (!validate_arglist (arglist,
3003 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3004 return 0;
3005 else
3007 tree dest = TREE_VALUE (arglist);
3008 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3009 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3010 char c;
3012 unsigned int dest_align
3013 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3014 rtx dest_mem, dest_addr, len_rtx;
3016 /* If DEST is not a pointer type, don't do this
3017 operation in-line. */
3018 if (dest_align == 0)
3019 return 0;
3021 /* If the LEN parameter is zero, return DEST. */
3022 if (integer_zerop (len))
3024 /* Evaluate and ignore VAL in case it has side-effects. */
3025 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3026 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3029 if (TREE_CODE (val) != INTEGER_CST)
3031 rtx val_rtx;
3033 if (!host_integerp (len, 1))
3034 return 0;
3036 if (optimize_size && tree_low_cst (len, 1) > 1)
3037 return 0;
3039 /* Assume that we can memset by pieces if we can store the
3040 * the coefficients by pieces (in the required modes).
3041 * We can't pass builtin_memset_gen_str as that emits RTL. */
3042 c = 1;
3043 if (!can_store_by_pieces (tree_low_cst (len, 1),
3044 builtin_memset_read_str,
3045 &c, dest_align))
3046 return 0;
3048 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3049 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3050 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3051 val_rtx);
3052 dest_mem = get_memory_rtx (dest);
3053 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3054 builtin_memset_gen_str,
3055 val_rtx, dest_align, 0);
3056 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3057 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3058 return dest_mem;
3061 if (target_char_cast (val, &c))
3062 return 0;
3064 if (c)
3066 if (!host_integerp (len, 1))
3067 return 0;
3068 if (!can_store_by_pieces (tree_low_cst (len, 1),
3069 builtin_memset_read_str, &c,
3070 dest_align))
3071 return 0;
3073 dest_mem = get_memory_rtx (dest);
3074 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3075 builtin_memset_read_str,
3076 &c, dest_align, 0);
3077 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3078 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3079 return dest_mem;
3082 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3084 dest_mem = get_memory_rtx (dest);
3085 set_mem_align (dest_mem, dest_align);
3086 dest_addr = clear_storage (dest_mem, len_rtx);
3088 if (dest_addr == 0)
3090 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3091 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3094 return dest_addr;
3098 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3099 if we failed the caller should emit a normal call. */
3101 static rtx
3102 expand_builtin_bzero (tree arglist)
3104 tree dest, size, newarglist;
3106 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3107 return NULL_RTX;
3109 dest = TREE_VALUE (arglist);
3110 size = TREE_VALUE (TREE_CHAIN (arglist));
3112 /* New argument list transforming bzero(ptr x, int y) to
3113 memset(ptr x, int 0, size_t y). This is done this way
3114 so that if it isn't expanded inline, we fallback to
3115 calling bzero instead of memset. */
3117 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3118 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3119 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3121 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3124 /* Expand expression EXP, which is a call to the memcmp built-in function.
3125 ARGLIST is the argument list for this call. Return 0 if we failed and the
3126 caller should emit a normal call, otherwise try to get the result in
3127 TARGET, if convenient (and in mode MODE, if that's convenient). */
3129 static rtx
3130 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3131 enum machine_mode mode)
3133 tree arg1, arg2, len;
3134 const char *p1, *p2;
3136 if (!validate_arglist (arglist,
3137 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3138 return 0;
3140 arg1 = TREE_VALUE (arglist);
3141 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3142 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3144 /* If the len parameter is zero, return zero. */
3145 if (integer_zerop (len))
3147 /* Evaluate and ignore arg1 and arg2 in case they have
3148 side-effects. */
3149 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3150 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3151 return const0_rtx;
3154 /* If both arguments are equal (and not volatile), return zero. */
3155 if (operand_equal_p (arg1, arg2, 0))
3157 /* Evaluate and ignore len in case it has side-effects. */
3158 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3159 return const0_rtx;
3162 p1 = c_getstr (arg1);
3163 p2 = c_getstr (arg2);
3165 /* If all arguments are constant, and the value of len is not greater
3166 than the lengths of arg1 and arg2, evaluate at compile-time. */
3167 if (host_integerp (len, 1) && p1 && p2
3168 && compare_tree_int (len, strlen (p1) + 1) <= 0
3169 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3171 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3173 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3176 /* If len parameter is one, return an expression corresponding to
3177 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3178 if (integer_onep (len))
3180 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3181 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3182 tree ind1 =
3183 fold (build1 (CONVERT_EXPR, integer_type_node,
3184 build1 (INDIRECT_REF, cst_uchar_node,
3185 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3186 tree ind2 =
3187 fold (build1 (CONVERT_EXPR, integer_type_node,
3188 build1 (INDIRECT_REF, cst_uchar_node,
3189 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3190 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3191 return expand_expr (result, target, mode, EXPAND_NORMAL);
3194 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3196 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3197 rtx result;
3198 rtx insn;
3200 int arg1_align
3201 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3202 int arg2_align
3203 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3204 enum machine_mode insn_mode;
3206 #ifdef HAVE_cmpmemsi
3207 if (HAVE_cmpmemsi)
3208 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3209 else
3210 #endif
3211 #ifdef HAVE_cmpstrsi
3212 if (HAVE_cmpstrsi)
3213 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3214 else
3215 #endif
3216 return 0;
3218 /* If we don't have POINTER_TYPE, call the function. */
3219 if (arg1_align == 0 || arg2_align == 0)
3220 return 0;
3222 /* Make a place to write the result of the instruction. */
3223 result = target;
3224 if (! (result != 0
3225 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3226 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3227 result = gen_reg_rtx (insn_mode);
3229 arg1_rtx = get_memory_rtx (arg1);
3230 arg2_rtx = get_memory_rtx (arg2);
3231 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3232 #ifdef HAVE_cmpmemsi
3233 if (HAVE_cmpmemsi)
3234 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3235 GEN_INT (MIN (arg1_align, arg2_align)));
3236 else
3237 #endif
3238 #ifdef HAVE_cmpstrsi
3239 if (HAVE_cmpstrsi)
3240 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3241 GEN_INT (MIN (arg1_align, arg2_align)));
3242 else
3243 #endif
3244 abort ();
3246 if (insn)
3247 emit_insn (insn);
3248 else
3249 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3250 TYPE_MODE (integer_type_node), 3,
3251 XEXP (arg1_rtx, 0), Pmode,
3252 XEXP (arg2_rtx, 0), Pmode,
3253 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3254 TREE_UNSIGNED (sizetype)),
3255 TYPE_MODE (sizetype));
3257 /* Return the value in the proper mode for this function. */
3258 mode = TYPE_MODE (TREE_TYPE (exp));
3259 if (GET_MODE (result) == mode)
3260 return result;
3261 else if (target != 0)
3263 convert_move (target, result, 0);
3264 return target;
3266 else
3267 return convert_to_mode (mode, result, 0);
3269 #endif
3271 return 0;
3274 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3275 if we failed the caller should emit a normal call, otherwise try to get
3276 the result in TARGET, if convenient. */
3278 static rtx
3279 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3281 tree arglist = TREE_OPERAND (exp, 1);
3282 tree arg1, arg2;
3283 const char *p1, *p2;
3285 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3286 return 0;
3288 arg1 = TREE_VALUE (arglist);
3289 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3291 /* If both arguments are equal (and not volatile), return zero. */
3292 if (operand_equal_p (arg1, arg2, 0))
3293 return const0_rtx;
3295 p1 = c_getstr (arg1);
3296 p2 = c_getstr (arg2);
3298 if (p1 && p2)
3300 const int i = strcmp (p1, p2);
3301 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3304 /* If either arg is "", return an expression corresponding to
3305 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3306 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3308 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3309 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3310 tree ind1 =
3311 fold (build1 (CONVERT_EXPR, integer_type_node,
3312 build1 (INDIRECT_REF, cst_uchar_node,
3313 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3314 tree ind2 =
3315 fold (build1 (CONVERT_EXPR, integer_type_node,
3316 build1 (INDIRECT_REF, cst_uchar_node,
3317 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3318 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3319 return expand_expr (result, target, mode, EXPAND_NORMAL);
3322 #ifdef HAVE_cmpstrsi
3323 if (HAVE_cmpstrsi)
3325 tree len, len1, len2;
3326 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3327 rtx result, insn;
3328 tree fndecl;
3330 int arg1_align
3331 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3332 int arg2_align
3333 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3334 enum machine_mode insn_mode
3335 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3337 len1 = c_strlen (arg1, 1);
3338 len2 = c_strlen (arg2, 1);
3340 if (len1)
3341 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3342 if (len2)
3343 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3345 /* If we don't have a constant length for the first, use the length
3346 of the second, if we know it. We don't require a constant for
3347 this case; some cost analysis could be done if both are available
3348 but neither is constant. For now, assume they're equally cheap,
3349 unless one has side effects. If both strings have constant lengths,
3350 use the smaller. */
3352 if (!len1)
3353 len = len2;
3354 else if (!len2)
3355 len = len1;
3356 else if (TREE_SIDE_EFFECTS (len1))
3357 len = len2;
3358 else if (TREE_SIDE_EFFECTS (len2))
3359 len = len1;
3360 else if (TREE_CODE (len1) != INTEGER_CST)
3361 len = len2;
3362 else if (TREE_CODE (len2) != INTEGER_CST)
3363 len = len1;
3364 else if (tree_int_cst_lt (len1, len2))
3365 len = len1;
3366 else
3367 len = len2;
3369 /* If both arguments have side effects, we cannot optimize. */
3370 if (!len || TREE_SIDE_EFFECTS (len))
3371 return 0;
3373 /* If we don't have POINTER_TYPE, call the function. */
3374 if (arg1_align == 0 || arg2_align == 0)
3375 return 0;
3377 /* Make a place to write the result of the instruction. */
3378 result = target;
3379 if (! (result != 0
3380 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3381 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3382 result = gen_reg_rtx (insn_mode);
3384 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3385 arg1 = save_expr (arg1);
3386 arg2 = save_expr (arg2);
3388 arg1_rtx = get_memory_rtx (arg1);
3389 arg2_rtx = get_memory_rtx (arg2);
3390 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3391 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3392 GEN_INT (MIN (arg1_align, arg2_align)));
3393 if (insn)
3395 emit_insn (insn);
3397 /* Return the value in the proper mode for this function. */
3398 mode = TYPE_MODE (TREE_TYPE (exp));
3399 if (GET_MODE (result) == mode)
3400 return result;
3401 if (target == 0)
3402 return convert_to_mode (mode, result, 0);
3403 convert_move (target, result, 0);
3404 return target;
3407 /* Expand the library call ourselves using a stabilized argument
3408 list to avoid re-evaluating the function's arguments twice. */
3409 arglist = build_tree_list (NULL_TREE, arg2);
3410 arglist = tree_cons (NULL_TREE, arg1, arglist);
3411 fndecl = get_callee_fndecl (exp);
3412 exp = build_function_call_expr (fndecl, arglist);
3413 return expand_call (exp, target, target == const0_rtx);
3415 #endif
3416 return 0;
3419 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3420 if we failed the caller should emit a normal call, otherwise try to get
3421 the result in TARGET, if convenient. */
3423 static rtx
3424 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3426 tree arglist = TREE_OPERAND (exp, 1);
3427 tree arg1, arg2, arg3;
3428 const char *p1, *p2;
3430 if (!validate_arglist (arglist,
3431 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3432 return 0;
3434 arg1 = TREE_VALUE (arglist);
3435 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3436 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3438 /* If the len parameter is zero, return zero. */
3439 if (integer_zerop (arg3))
3441 /* Evaluate and ignore arg1 and arg2 in case they have
3442 side-effects. */
3443 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3444 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3445 return const0_rtx;
3448 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3449 if (operand_equal_p (arg1, arg2, 0))
3451 /* Evaluate and ignore arg3 in case it has side-effects. */
3452 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3453 return const0_rtx;
3456 p1 = c_getstr (arg1);
3457 p2 = c_getstr (arg2);
3459 /* If all arguments are constant, evaluate at compile-time. */
3460 if (host_integerp (arg3, 1) && p1 && p2)
3462 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3463 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3466 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3467 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3468 if (host_integerp (arg3, 1)
3469 && (tree_low_cst (arg3, 1) == 1
3470 || (tree_low_cst (arg3, 1) > 1
3471 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3473 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3474 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3475 tree ind1 =
3476 fold (build1 (CONVERT_EXPR, integer_type_node,
3477 build1 (INDIRECT_REF, cst_uchar_node,
3478 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3479 tree ind2 =
3480 fold (build1 (CONVERT_EXPR, integer_type_node,
3481 build1 (INDIRECT_REF, cst_uchar_node,
3482 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3483 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3484 return expand_expr (result, target, mode, EXPAND_NORMAL);
3487 /* If c_strlen can determine an expression for one of the string
3488 lengths, and it doesn't have side effects, then emit cmpstrsi
3489 using length MIN(strlen(string)+1, arg3). */
3490 #ifdef HAVE_cmpstrsi
3491 if (HAVE_cmpstrsi)
3493 tree len, len1, len2;
3494 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3495 rtx result, insn;
3496 tree fndecl;
3498 int arg1_align
3499 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3500 int arg2_align
3501 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3502 enum machine_mode insn_mode
3503 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3505 len1 = c_strlen (arg1, 1);
3506 len2 = c_strlen (arg2, 1);
3508 if (len1)
3509 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3510 if (len2)
3511 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3513 /* If we don't have a constant length for the first, use the length
3514 of the second, if we know it. We don't require a constant for
3515 this case; some cost analysis could be done if both are available
3516 but neither is constant. For now, assume they're equally cheap,
3517 unless one has side effects. If both strings have constant lengths,
3518 use the smaller. */
3520 if (!len1)
3521 len = len2;
3522 else if (!len2)
3523 len = len1;
3524 else if (TREE_SIDE_EFFECTS (len1))
3525 len = len2;
3526 else if (TREE_SIDE_EFFECTS (len2))
3527 len = len1;
3528 else if (TREE_CODE (len1) != INTEGER_CST)
3529 len = len2;
3530 else if (TREE_CODE (len2) != INTEGER_CST)
3531 len = len1;
3532 else if (tree_int_cst_lt (len1, len2))
3533 len = len1;
3534 else
3535 len = len2;
3537 /* If both arguments have side effects, we cannot optimize. */
3538 if (!len || TREE_SIDE_EFFECTS (len))
3539 return 0;
3541 /* The actual new length parameter is MIN(len,arg3). */
3542 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3544 /* If we don't have POINTER_TYPE, call the function. */
3545 if (arg1_align == 0 || arg2_align == 0)
3546 return 0;
3548 /* Make a place to write the result of the instruction. */
3549 result = target;
3550 if (! (result != 0
3551 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3552 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3553 result = gen_reg_rtx (insn_mode);
3555 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3556 arg1 = save_expr (arg1);
3557 arg2 = save_expr (arg2);
3558 len = save_expr (len);
3560 arg1_rtx = get_memory_rtx (arg1);
3561 arg2_rtx = get_memory_rtx (arg2);
3562 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3563 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3564 GEN_INT (MIN (arg1_align, arg2_align)));
3565 if (insn)
3567 emit_insn (insn);
3569 /* Return the value in the proper mode for this function. */
3570 mode = TYPE_MODE (TREE_TYPE (exp));
3571 if (GET_MODE (result) == mode)
3572 return result;
3573 if (target == 0)
3574 return convert_to_mode (mode, result, 0);
3575 convert_move (target, result, 0);
3576 return target;
3579 /* Expand the library call ourselves using a stabilized argument
3580 list to avoid re-evaluating the function's arguments twice. */
3581 arglist = build_tree_list (NULL_TREE, len);
3582 arglist = tree_cons (NULL_TREE, arg2, arglist);
3583 arglist = tree_cons (NULL_TREE, arg1, arglist);
3584 fndecl = get_callee_fndecl (exp);
3585 exp = build_function_call_expr (fndecl, arglist);
3586 return expand_call (exp, target, target == const0_rtx);
3588 #endif
3589 return 0;
3592 /* Expand expression EXP, which is a call to the strcat builtin.
3593 Return 0 if we failed the caller should emit a normal call,
3594 otherwise try to get the result in TARGET, if convenient. */
3596 static rtx
3597 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3599 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3600 return 0;
3601 else
3603 tree dst = TREE_VALUE (arglist),
3604 src = TREE_VALUE (TREE_CHAIN (arglist));
3605 const char *p = c_getstr (src);
3607 if (p)
3609 /* If the string length is zero, return the dst parameter. */
3610 if (*p == '\0')
3611 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3612 else if (!optimize_size)
3614 /* Otherwise if !optimize_size, see if we can store by
3615 pieces into (dst + strlen(dst)). */
3616 tree newdst, arglist,
3617 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3619 /* This is the length argument. */
3620 arglist = build_tree_list (NULL_TREE,
3621 fold (size_binop (PLUS_EXPR,
3622 c_strlen (src, 0),
3623 ssize_int (1))));
3624 /* Prepend src argument. */
3625 arglist = tree_cons (NULL_TREE, src, arglist);
3627 /* We're going to use dst more than once. */
3628 dst = save_expr (dst);
3630 /* Create strlen (dst). */
3631 newdst =
3632 fold (build_function_call_expr (strlen_fn,
3633 build_tree_list (NULL_TREE,
3634 dst)));
3635 /* Create (dst + strlen (dst)). */
3636 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3638 /* Prepend the new dst argument. */
3639 arglist = tree_cons (NULL_TREE, newdst, arglist);
3641 /* We don't want to get turned into a memcpy if the
3642 target is const0_rtx, i.e. when the return value
3643 isn't used. That would produce pessimized code so
3644 pass in a target of zero, it should never actually be
3645 used. If this was successful return the original
3646 dst, not the result of mempcpy. */
3647 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3648 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3649 else
3650 return 0;
3654 return 0;
3658 /* Expand expression EXP, which is a call to the strncat builtin.
3659 Return 0 if we failed the caller should emit a normal call,
3660 otherwise try to get the result in TARGET, if convenient. */
3662 static rtx
3663 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3665 if (!validate_arglist (arglist,
3666 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3667 return 0;
3668 else
3670 tree dst = TREE_VALUE (arglist),
3671 src = TREE_VALUE (TREE_CHAIN (arglist)),
3672 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3673 const char *p = c_getstr (src);
3675 /* If the requested length is zero, or the src parameter string
3676 length is zero, return the dst parameter. */
3677 if (integer_zerop (len) || (p && *p == '\0'))
3679 /* Evaluate and ignore the src and len parameters in case
3680 they have side-effects. */
3681 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3682 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3683 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3686 /* If the requested len is greater than or equal to the string
3687 length, call strcat. */
3688 if (TREE_CODE (len) == INTEGER_CST && p
3689 && compare_tree_int (len, strlen (p)) >= 0)
3691 tree newarglist
3692 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3693 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3695 /* If the replacement _DECL isn't initialized, don't do the
3696 transformation. */
3697 if (!fn)
3698 return 0;
3700 return expand_expr (build_function_call_expr (fn, newarglist),
3701 target, mode, EXPAND_NORMAL);
3703 return 0;
3707 /* Expand expression EXP, which is a call to the strspn builtin.
3708 Return 0 if we failed the caller should emit a normal call,
3709 otherwise try to get the result in TARGET, if convenient. */
3711 static rtx
3712 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3714 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3715 return 0;
3716 else
3718 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3719 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3721 /* If both arguments are constants, evaluate at compile-time. */
3722 if (p1 && p2)
3724 const size_t r = strspn (p1, p2);
3725 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3728 /* If either argument is "", return 0. */
3729 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3731 /* Evaluate and ignore both arguments in case either one has
3732 side-effects. */
3733 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3734 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3735 return const0_rtx;
3737 return 0;
3741 /* Expand expression EXP, which is a call to the strcspn builtin.
3742 Return 0 if we failed the caller should emit a normal call,
3743 otherwise try to get the result in TARGET, if convenient. */
3745 static rtx
3746 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3748 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3749 return 0;
3750 else
3752 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3753 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3755 /* If both arguments are constants, evaluate at compile-time. */
3756 if (p1 && p2)
3758 const size_t r = strcspn (p1, p2);
3759 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3762 /* If the first argument is "", return 0. */
3763 if (p1 && *p1 == '\0')
3765 /* Evaluate and ignore argument s2 in case it has
3766 side-effects. */
3767 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3768 return const0_rtx;
3771 /* If the second argument is "", return __builtin_strlen(s1). */
3772 if (p2 && *p2 == '\0')
3774 tree newarglist = build_tree_list (NULL_TREE, s1),
3775 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3777 /* If the replacement _DECL isn't initialized, don't do the
3778 transformation. */
3779 if (!fn)
3780 return 0;
3782 return expand_expr (build_function_call_expr (fn, newarglist),
3783 target, mode, EXPAND_NORMAL);
3785 return 0;
3789 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3790 if that's convenient. */
3793 expand_builtin_saveregs (void)
3795 rtx val, seq;
3797 /* Don't do __builtin_saveregs more than once in a function.
3798 Save the result of the first call and reuse it. */
3799 if (saveregs_value != 0)
3800 return saveregs_value;
3802 /* When this function is called, it means that registers must be
3803 saved on entry to this function. So we migrate the call to the
3804 first insn of this function. */
3806 start_sequence ();
3808 /* Do whatever the machine needs done in this case. */
3809 val = targetm.calls.expand_builtin_saveregs ();
3811 seq = get_insns ();
3812 end_sequence ();
3814 saveregs_value = val;
3816 /* Put the insns after the NOTE that starts the function. If this
3817 is inside a start_sequence, make the outer-level insn chain current, so
3818 the code is placed at the start of the function. */
3819 push_topmost_sequence ();
3820 emit_insn_after (seq, get_insns ());
3821 pop_topmost_sequence ();
3823 return val;
3826 /* __builtin_args_info (N) returns word N of the arg space info
3827 for the current function. The number and meanings of words
3828 is controlled by the definition of CUMULATIVE_ARGS. */
3830 static rtx
3831 expand_builtin_args_info (tree arglist)
3833 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3834 int *word_ptr = (int *) &current_function_args_info;
3836 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3837 abort ();
3839 if (arglist != 0)
3841 if (!host_integerp (TREE_VALUE (arglist), 0))
3842 error ("argument of `__builtin_args_info' must be constant");
3843 else
3845 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3847 if (wordnum < 0 || wordnum >= nwords)
3848 error ("argument of `__builtin_args_info' out of range");
3849 else
3850 return GEN_INT (word_ptr[wordnum]);
3853 else
3854 error ("missing argument in `__builtin_args_info'");
3856 return const0_rtx;
3859 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3861 static rtx
3862 expand_builtin_next_arg (tree arglist)
3864 tree fntype = TREE_TYPE (current_function_decl);
3866 if (TYPE_ARG_TYPES (fntype) == 0
3867 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3868 == void_type_node))
3870 error ("`va_start' used in function with fixed args");
3871 return const0_rtx;
3874 if (arglist)
3876 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3877 tree arg = TREE_VALUE (arglist);
3879 /* Strip off all nops for the sake of the comparison. This
3880 is not quite the same as STRIP_NOPS. It does more.
3881 We must also strip off INDIRECT_EXPR for C++ reference
3882 parameters. */
3883 while (TREE_CODE (arg) == NOP_EXPR
3884 || TREE_CODE (arg) == CONVERT_EXPR
3885 || TREE_CODE (arg) == NON_LVALUE_EXPR
3886 || TREE_CODE (arg) == INDIRECT_REF)
3887 arg = TREE_OPERAND (arg, 0);
3888 if (arg != last_parm)
3889 warning ("second parameter of `va_start' not last named argument");
3891 else
3892 /* Evidently an out of date version of <stdarg.h>; can't validate
3893 va_start's second argument, but can still work as intended. */
3894 warning ("`__builtin_next_arg' called without an argument");
3896 return expand_binop (Pmode, add_optab,
3897 current_function_internal_arg_pointer,
3898 current_function_arg_offset_rtx,
3899 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3902 /* Make it easier for the backends by protecting the valist argument
3903 from multiple evaluations. */
3905 static tree
3906 stabilize_va_list (tree valist, int needs_lvalue)
3908 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3910 if (TREE_SIDE_EFFECTS (valist))
3911 valist = save_expr (valist);
3913 /* For this case, the backends will be expecting a pointer to
3914 TREE_TYPE (va_list_type_node), but it's possible we've
3915 actually been given an array (an actual va_list_type_node).
3916 So fix it. */
3917 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3919 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3920 tree p2 = build_pointer_type (va_list_type_node);
3922 valist = build1 (ADDR_EXPR, p2, valist);
3923 valist = fold (build1 (NOP_EXPR, p1, valist));
3926 else
3928 tree pt;
3930 if (! needs_lvalue)
3932 if (! TREE_SIDE_EFFECTS (valist))
3933 return valist;
3935 pt = build_pointer_type (va_list_type_node);
3936 valist = fold (build1 (ADDR_EXPR, pt, valist));
3937 TREE_SIDE_EFFECTS (valist) = 1;
3940 if (TREE_SIDE_EFFECTS (valist))
3941 valist = save_expr (valist);
3942 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3943 valist));
3946 return valist;
3949 /* The "standard" definition of va_list is void*. */
3951 tree
3952 std_build_builtin_va_list (void)
3954 return ptr_type_node;
3957 /* The "standard" implementation of va_start: just assign `nextarg' to
3958 the variable. */
3960 void
3961 std_expand_builtin_va_start (tree valist, rtx nextarg)
3963 tree t;
3965 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3966 make_tree (ptr_type_node, nextarg));
3967 TREE_SIDE_EFFECTS (t) = 1;
3969 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3972 /* Expand ARGLIST, from a call to __builtin_va_start. */
3974 static rtx
3975 expand_builtin_va_start (tree arglist)
3977 rtx nextarg;
3978 tree chain, valist;
3980 chain = TREE_CHAIN (arglist);
3982 if (TREE_CHAIN (chain))
3983 error ("too many arguments to function `va_start'");
3985 nextarg = expand_builtin_next_arg (chain);
3986 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3988 #ifdef EXPAND_BUILTIN_VA_START
3989 EXPAND_BUILTIN_VA_START (valist, nextarg);
3990 #else
3991 std_expand_builtin_va_start (valist, nextarg);
3992 #endif
3994 return const0_rtx;
3997 /* The "standard" implementation of va_arg: read the value from the
3998 current (padded) address and increment by the (padded) size. */
4001 std_expand_builtin_va_arg (tree valist, tree type)
4003 tree addr_tree, t, type_size = NULL;
4004 tree align, alignm1;
4005 tree rounded_size;
4006 rtx addr;
4007 HOST_WIDE_INT boundary;
4009 /* Compute the rounded size of the type. */
4010 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4011 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4012 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4014 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4015 requires greater alignment, we must perform dynamic alignment. */
4017 if (boundary > PARM_BOUNDARY)
4019 if (!PAD_VARARGS_DOWN)
4021 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4022 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4023 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4024 TREE_SIDE_EFFECTS (t) = 1;
4025 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4027 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4028 build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4029 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4030 TREE_SIDE_EFFECTS (t) = 1;
4031 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4033 if (type == error_mark_node
4034 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4035 || TREE_OVERFLOW (type_size))
4036 rounded_size = size_zero_node;
4037 else
4038 rounded_size = fold (build (MULT_EXPR, sizetype,
4039 fold (build (TRUNC_DIV_EXPR, sizetype,
4040 fold (build (PLUS_EXPR, sizetype,
4041 type_size, alignm1)),
4042 align)),
4043 align));
4045 /* Get AP. */
4046 addr_tree = valist;
4047 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4049 /* Small args are padded downward. */
4050 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4051 fold (build (COND_EXPR, sizetype,
4052 fold (build (GT_EXPR, sizetype,
4053 rounded_size,
4054 align)),
4055 size_zero_node,
4056 fold (build (MINUS_EXPR, sizetype,
4057 rounded_size,
4058 type_size))))));
4061 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4062 addr = copy_to_reg (addr);
4064 /* Compute new value for AP. */
4065 if (! integer_zerop (rounded_size))
4067 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4068 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4069 rounded_size));
4070 TREE_SIDE_EFFECTS (t) = 1;
4071 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4074 return addr;
4077 /* Expand __builtin_va_arg, which is not really a builtin function, but
4078 a very special sort of operator. */
4081 expand_builtin_va_arg (tree valist, tree type)
4083 rtx addr, result;
4084 tree promoted_type, want_va_type, have_va_type;
4086 /* Verify that valist is of the proper type. */
4088 want_va_type = va_list_type_node;
4089 have_va_type = TREE_TYPE (valist);
4090 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4092 /* If va_list is an array type, the argument may have decayed
4093 to a pointer type, e.g. by being passed to another function.
4094 In that case, unwrap both types so that we can compare the
4095 underlying records. */
4096 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4097 || TREE_CODE (have_va_type) == POINTER_TYPE)
4099 want_va_type = TREE_TYPE (want_va_type);
4100 have_va_type = TREE_TYPE (have_va_type);
4103 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4105 error ("first argument to `va_arg' not of type `va_list'");
4106 addr = const0_rtx;
4109 /* Generate a diagnostic for requesting data of a type that cannot
4110 be passed through `...' due to type promotion at the call site. */
4111 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4112 != type)
4114 const char *name = "<anonymous type>", *pname = 0;
4115 static bool gave_help;
4117 if (TYPE_NAME (type))
4119 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4120 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4121 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4122 && DECL_NAME (TYPE_NAME (type)))
4123 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4125 if (TYPE_NAME (promoted_type))
4127 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4128 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4129 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4130 && DECL_NAME (TYPE_NAME (promoted_type)))
4131 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4134 /* Unfortunately, this is merely undefined, rather than a constraint
4135 violation, so we cannot make this an error. If this call is never
4136 executed, the program is still strictly conforming. */
4137 warning ("`%s' is promoted to `%s' when passed through `...'",
4138 name, pname);
4139 if (! gave_help)
4141 gave_help = true;
4142 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4143 pname, name);
4146 /* We can, however, treat "undefined" any way we please.
4147 Call abort to encourage the user to fix the program. */
4148 expand_builtin_trap ();
4150 /* This is dead code, but go ahead and finish so that the
4151 mode of the result comes out right. */
4152 addr = const0_rtx;
4154 else
4156 /* Make it easier for the backends by protecting the valist argument
4157 from multiple evaluations. */
4158 valist = stabilize_va_list (valist, 0);
4160 #ifdef EXPAND_BUILTIN_VA_ARG
4161 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4162 #else
4163 addr = std_expand_builtin_va_arg (valist, type);
4164 #endif
4167 addr = convert_memory_address (Pmode, addr);
4169 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4170 set_mem_alias_set (result, get_varargs_alias_set ());
4172 return result;
4175 /* Expand ARGLIST, from a call to __builtin_va_end. */
4177 static rtx
4178 expand_builtin_va_end (tree arglist)
4180 tree valist = TREE_VALUE (arglist);
4182 /* Evaluate for side effects, if needed. I hate macros that don't
4183 do that. */
4184 if (TREE_SIDE_EFFECTS (valist))
4185 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4187 return const0_rtx;
4190 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4191 builtin rather than just as an assignment in stdarg.h because of the
4192 nastiness of array-type va_list types. */
4194 static rtx
4195 expand_builtin_va_copy (tree arglist)
4197 tree dst, src, t;
4199 dst = TREE_VALUE (arglist);
4200 src = TREE_VALUE (TREE_CHAIN (arglist));
4202 dst = stabilize_va_list (dst, 1);
4203 src = stabilize_va_list (src, 0);
4205 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4207 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4208 TREE_SIDE_EFFECTS (t) = 1;
4209 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4211 else
4213 rtx dstb, srcb, size;
4215 /* Evaluate to pointers. */
4216 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4217 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4218 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4219 VOIDmode, EXPAND_NORMAL);
4221 dstb = convert_memory_address (Pmode, dstb);
4222 srcb = convert_memory_address (Pmode, srcb);
4224 /* "Dereference" to BLKmode memories. */
4225 dstb = gen_rtx_MEM (BLKmode, dstb);
4226 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4227 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4228 srcb = gen_rtx_MEM (BLKmode, srcb);
4229 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4230 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4232 /* Copy. */
4233 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4236 return const0_rtx;
4239 /* Expand a call to one of the builtin functions __builtin_frame_address or
4240 __builtin_return_address. */
4242 static rtx
4243 expand_builtin_frame_address (tree fndecl, tree arglist)
4245 /* The argument must be a nonnegative integer constant.
4246 It counts the number of frames to scan up the stack.
4247 The value is the return address saved in that frame. */
4248 if (arglist == 0)
4249 /* Warning about missing arg was already issued. */
4250 return const0_rtx;
4251 else if (! host_integerp (TREE_VALUE (arglist), 1))
4253 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4254 error ("invalid arg to `__builtin_frame_address'");
4255 else
4256 error ("invalid arg to `__builtin_return_address'");
4257 return const0_rtx;
4259 else
4261 rtx tem
4262 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4263 tree_low_cst (TREE_VALUE (arglist), 1),
4264 hard_frame_pointer_rtx);
4266 /* Some ports cannot access arbitrary stack frames. */
4267 if (tem == NULL)
4269 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4270 warning ("unsupported arg to `__builtin_frame_address'");
4271 else
4272 warning ("unsupported arg to `__builtin_return_address'");
4273 return const0_rtx;
4276 /* For __builtin_frame_address, return what we've got. */
4277 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4278 return tem;
4280 if (GET_CODE (tem) != REG
4281 && ! CONSTANT_P (tem))
4282 tem = copy_to_mode_reg (Pmode, tem);
4283 return tem;
4287 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4288 we failed and the caller should emit a normal call, otherwise try to get
4289 the result in TARGET, if convenient. */
4291 static rtx
4292 expand_builtin_alloca (tree arglist, rtx target)
4294 rtx op0;
4295 rtx result;
4297 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4298 return 0;
4300 /* Compute the argument. */
4301 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4303 /* Allocate the desired space. */
4304 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4305 result = convert_memory_address (ptr_mode, result);
4307 return result;
4310 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4311 Return 0 if a normal call should be emitted rather than expanding the
4312 function in-line. If convenient, the result should be placed in TARGET.
4313 SUBTARGET may be used as the target for computing one of EXP's operands. */
4315 static rtx
4316 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4317 rtx subtarget, optab op_optab)
4319 rtx op0;
4320 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4321 return 0;
4323 /* Compute the argument. */
4324 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4325 /* Compute op, into TARGET if possible.
4326 Set TARGET to wherever the result comes back. */
4327 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4328 op_optab, op0, target, 1);
4329 if (target == 0)
4330 abort ();
4332 return convert_to_mode (target_mode, target, 0);
4335 /* If the string passed to fputs is a constant and is one character
4336 long, we attempt to transform this call into __builtin_fputc(). */
4338 static rtx
4339 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4341 tree len, fn;
4342 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4343 : implicit_built_in_decls[BUILT_IN_FPUTC];
4344 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4345 : implicit_built_in_decls[BUILT_IN_FWRITE];
4347 /* If the return value is used, or the replacement _DECL isn't
4348 initialized, don't do the transformation. */
4349 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4350 return 0;
4352 /* Verify the arguments in the original call. */
4353 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4354 return 0;
4356 /* Get the length of the string passed to fputs. If the length
4357 can't be determined, punt. */
4358 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4359 || TREE_CODE (len) != INTEGER_CST)
4360 return 0;
4362 switch (compare_tree_int (len, 1))
4364 case -1: /* length is 0, delete the call entirely . */
4366 /* Evaluate and ignore the argument in case it has
4367 side-effects. */
4368 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4369 VOIDmode, EXPAND_NORMAL);
4370 return const0_rtx;
4372 case 0: /* length is 1, call fputc. */
4374 const char *p = c_getstr (TREE_VALUE (arglist));
4376 if (p != NULL)
4378 /* New argument list transforming fputs(string, stream) to
4379 fputc(string[0], stream). */
4380 arglist =
4381 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4382 arglist =
4383 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4384 fn = fn_fputc;
4385 break;
4388 /* Fall through. */
4389 case 1: /* length is greater than 1, call fwrite. */
4391 tree string_arg;
4393 /* If optimizing for size keep fputs. */
4394 if (optimize_size)
4395 return 0;
4396 string_arg = TREE_VALUE (arglist);
4397 /* New argument list transforming fputs(string, stream) to
4398 fwrite(string, 1, len, stream). */
4399 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4400 arglist = tree_cons (NULL_TREE, len, arglist);
4401 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4402 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4403 fn = fn_fwrite;
4404 break;
4406 default:
4407 abort ();
4410 return expand_expr (build_function_call_expr (fn, arglist),
4411 const0_rtx, VOIDmode, EXPAND_NORMAL);
4414 /* Expand a call to __builtin_expect. We return our argument and emit a
4415 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4416 a non-jump context. */
4418 static rtx
4419 expand_builtin_expect (tree arglist, rtx target)
4421 tree exp, c;
4422 rtx note, rtx_c;
4424 if (arglist == NULL_TREE
4425 || TREE_CHAIN (arglist) == NULL_TREE)
4426 return const0_rtx;
4427 exp = TREE_VALUE (arglist);
4428 c = TREE_VALUE (TREE_CHAIN (arglist));
4430 if (TREE_CODE (c) != INTEGER_CST)
4432 error ("second arg to `__builtin_expect' must be a constant");
4433 c = integer_zero_node;
4436 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4438 /* Don't bother with expected value notes for integral constants. */
4439 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4441 /* We do need to force this into a register so that we can be
4442 moderately sure to be able to correctly interpret the branch
4443 condition later. */
4444 target = force_reg (GET_MODE (target), target);
4446 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4448 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4449 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4452 return target;
4455 /* Like expand_builtin_expect, except do this in a jump context. This is
4456 called from do_jump if the conditional is a __builtin_expect. Return either
4457 a list of insns to emit the jump or NULL if we cannot optimize
4458 __builtin_expect. We need to optimize this at jump time so that machines
4459 like the PowerPC don't turn the test into a SCC operation, and then jump
4460 based on the test being 0/1. */
4463 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4465 tree arglist = TREE_OPERAND (exp, 1);
4466 tree arg0 = TREE_VALUE (arglist);
4467 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4468 rtx ret = NULL_RTX;
4470 /* Only handle __builtin_expect (test, 0) and
4471 __builtin_expect (test, 1). */
4472 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4473 && (integer_zerop (arg1) || integer_onep (arg1)))
4475 rtx insn, drop_through_label, temp;
4477 /* Expand the jump insns. */
4478 start_sequence ();
4479 do_jump (arg0, if_false_label, if_true_label);
4480 ret = get_insns ();
4482 drop_through_label = get_last_insn ();
4483 if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4484 drop_through_label = prev_nonnote_insn (drop_through_label);
4485 if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4486 drop_through_label = NULL_RTX;
4487 end_sequence ();
4489 if (! if_true_label)
4490 if_true_label = drop_through_label;
4491 if (! if_false_label)
4492 if_false_label = drop_through_label;
4494 /* Go through and add the expect's to each of the conditional jumps. */
4495 insn = ret;
4496 while (insn != NULL_RTX)
4498 rtx next = NEXT_INSN (insn);
4500 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4502 rtx ifelse = SET_SRC (pc_set (insn));
4503 rtx then_dest = XEXP (ifelse, 1);
4504 rtx else_dest = XEXP (ifelse, 2);
4505 int taken = -1;
4507 /* First check if we recognize any of the labels. */
4508 if (GET_CODE (then_dest) == LABEL_REF
4509 && XEXP (then_dest, 0) == if_true_label)
4510 taken = 1;
4511 else if (GET_CODE (then_dest) == LABEL_REF
4512 && XEXP (then_dest, 0) == if_false_label)
4513 taken = 0;
4514 else if (GET_CODE (else_dest) == LABEL_REF
4515 && XEXP (else_dest, 0) == if_false_label)
4516 taken = 1;
4517 else if (GET_CODE (else_dest) == LABEL_REF
4518 && XEXP (else_dest, 0) == if_true_label)
4519 taken = 0;
4520 /* Otherwise check where we drop through. */
4521 else if (else_dest == pc_rtx)
4523 if (next && GET_CODE (next) == NOTE)
4524 next = next_nonnote_insn (next);
4526 if (next && GET_CODE (next) == JUMP_INSN
4527 && any_uncondjump_p (next))
4528 temp = XEXP (SET_SRC (pc_set (next)), 0);
4529 else
4530 temp = next;
4532 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4533 else that can't possibly match either target label. */
4534 if (temp == if_false_label)
4535 taken = 1;
4536 else if (temp == if_true_label)
4537 taken = 0;
4539 else if (then_dest == pc_rtx)
4541 if (next && GET_CODE (next) == NOTE)
4542 next = next_nonnote_insn (next);
4544 if (next && GET_CODE (next) == JUMP_INSN
4545 && any_uncondjump_p (next))
4546 temp = XEXP (SET_SRC (pc_set (next)), 0);
4547 else
4548 temp = next;
4550 if (temp == if_false_label)
4551 taken = 0;
4552 else if (temp == if_true_label)
4553 taken = 1;
4556 if (taken != -1)
4558 /* If the test is expected to fail, reverse the
4559 probabilities. */
4560 if (integer_zerop (arg1))
4561 taken = 1 - taken;
4562 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4566 insn = next;
4570 return ret;
4573 void
4574 expand_builtin_trap (void)
4576 #ifdef HAVE_trap
4577 if (HAVE_trap)
4578 emit_insn (gen_trap ());
4579 else
4580 #endif
4581 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4582 emit_barrier ();
4585 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4586 Return 0 if a normal call should be emitted rather than expanding
4587 the function inline. If convenient, the result should be placed
4588 in TARGET. SUBTARGET may be used as the target for computing
4589 the operand. */
4591 static rtx
4592 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4594 enum machine_mode mode;
4595 tree arg;
4596 rtx op0;
4598 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4599 return 0;
4601 arg = TREE_VALUE (arglist);
4602 mode = TYPE_MODE (TREE_TYPE (arg));
4603 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4604 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4607 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4608 Return 0 if a normal call should be emitted rather than expanding
4609 the function inline. If convenient, the result should be placed
4610 in target. */
4612 static rtx
4613 expand_builtin_cabs (tree arglist, rtx target)
4615 enum machine_mode mode;
4616 tree arg;
4617 rtx op0;
4619 if (arglist == 0 || TREE_CHAIN (arglist))
4620 return 0;
4621 arg = TREE_VALUE (arglist);
4622 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4623 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4624 return 0;
4626 mode = TYPE_MODE (TREE_TYPE (arg));
4627 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4628 return expand_complex_abs (mode, op0, target, 0);
4631 /* Create a new constant string literal and return a char* pointer to it.
4632 The STRING_CST value is the LEN characters at STR. */
4633 static tree
4634 build_string_literal (int len, const char *str)
4636 tree t, elem, index, type;
4638 t = build_string (len, str);
4639 elem = build_type_variant (char_type_node, 1, 0);
4640 index = build_index_type (build_int_2 (len - 1, 0));
4641 type = build_array_type (elem, index);
4642 TREE_TYPE (t) = type;
4643 TREE_CONSTANT (t) = 1;
4644 TREE_READONLY (t) = 1;
4645 TREE_STATIC (t) = 1;
4647 type = build_pointer_type (type);
4648 t = build1 (ADDR_EXPR, type, t);
4650 type = build_pointer_type (elem);
4651 t = build1 (NOP_EXPR, type, t);
4652 return t;
4655 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4656 Return 0 if a normal call should be emitted rather than transforming
4657 the function inline. If convenient, the result should be placed in
4658 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4659 call. */
4660 static rtx
4661 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4662 bool unlocked)
4664 tree fn_putchar = unlocked
4665 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4666 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4667 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4668 : implicit_built_in_decls[BUILT_IN_PUTS];
4669 const char *fmt_str;
4670 tree fn, fmt, arg;
4672 /* If the return value is used, don't do the transformation. */
4673 if (target != const0_rtx)
4674 return 0;
4676 /* Verify the required arguments in the original call. */
4677 if (! arglist)
4678 return 0;
4679 fmt = TREE_VALUE (arglist);
4680 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4681 return 0;
4682 arglist = TREE_CHAIN (arglist);
4684 /* Check whether the format is a literal string constant. */
4685 fmt_str = c_getstr (fmt);
4686 if (fmt_str == NULL)
4687 return 0;
4689 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4690 if (strcmp (fmt_str, "%s\n") == 0)
4692 if (! arglist
4693 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4694 || TREE_CHAIN (arglist))
4695 return 0;
4696 fn = fn_puts;
4698 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4699 else if (strcmp (fmt_str, "%c") == 0)
4701 if (! arglist
4702 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4703 || TREE_CHAIN (arglist))
4704 return 0;
4705 fn = fn_putchar;
4707 else
4709 /* We can't handle anything else with % args or %% ... yet. */
4710 if (strchr (fmt_str, '%'))
4711 return 0;
4713 if (arglist)
4714 return 0;
4716 /* If the format specifier was "", printf does nothing. */
4717 if (fmt_str[0] == '\0')
4718 return const0_rtx;
4719 /* If the format specifier has length of 1, call putchar. */
4720 if (fmt_str[1] == '\0')
4722 /* Given printf("c"), (where c is any one character,)
4723 convert "c"[0] to an int and pass that to the replacement
4724 function. */
4725 arg = build_int_2 (fmt_str[0], 0);
4726 arglist = build_tree_list (NULL_TREE, arg);
4727 fn = fn_putchar;
4729 else
4731 /* If the format specifier was "string\n", call puts("string"). */
4732 size_t len = strlen (fmt_str);
4733 if (fmt_str[len - 1] == '\n')
4735 /* Create a NUL-terminated string that's one char shorter
4736 than the original, stripping off the trailing '\n'. */
4737 char *newstr = (char *) alloca (len);
4738 memcpy (newstr, fmt_str, len - 1);
4739 newstr[len - 1] = 0;
4741 arg = build_string_literal (len, newstr);
4742 arglist = build_tree_list (NULL_TREE, arg);
4743 fn = fn_puts;
4745 else
4746 /* We'd like to arrange to call fputs(string,stdout) here,
4747 but we need stdout and don't have a way to get it yet. */
4748 return 0;
4752 if (!fn)
4753 return 0;
4754 return expand_expr (build_function_call_expr (fn, arglist),
4755 target, mode, EXPAND_NORMAL);
4758 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4759 Return 0 if a normal call should be emitted rather than transforming
4760 the function inline. If convenient, the result should be placed in
4761 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4762 call. */
4763 static rtx
4764 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4765 bool unlocked)
4767 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4768 : implicit_built_in_decls[BUILT_IN_FPUTC];
4769 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4770 : implicit_built_in_decls[BUILT_IN_FPUTS];
4771 const char *fmt_str;
4772 tree fn, fmt, fp, arg;
4774 /* If the return value is used, don't do the transformation. */
4775 if (target != const0_rtx)
4776 return 0;
4778 /* Verify the required arguments in the original call. */
4779 if (! arglist)
4780 return 0;
4781 fp = TREE_VALUE (arglist);
4782 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4783 return 0;
4784 arglist = TREE_CHAIN (arglist);
4785 if (! arglist)
4786 return 0;
4787 fmt = TREE_VALUE (arglist);
4788 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4789 return 0;
4790 arglist = TREE_CHAIN (arglist);
4792 /* Check whether the format is a literal string constant. */
4793 fmt_str = c_getstr (fmt);
4794 if (fmt_str == NULL)
4795 return 0;
4797 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4798 if (strcmp (fmt_str, "%s") == 0)
4800 if (! arglist
4801 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4802 || TREE_CHAIN (arglist))
4803 return 0;
4804 arg = TREE_VALUE (arglist);
4805 arglist = build_tree_list (NULL_TREE, fp);
4806 arglist = tree_cons (NULL_TREE, arg, arglist);
4807 fn = fn_fputs;
4809 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4810 else if (strcmp (fmt_str, "%c") == 0)
4812 if (! arglist
4813 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4814 || TREE_CHAIN (arglist))
4815 return 0;
4816 arg = TREE_VALUE (arglist);
4817 arglist = build_tree_list (NULL_TREE, fp);
4818 arglist = tree_cons (NULL_TREE, arg, arglist);
4819 fn = fn_fputc;
4821 else
4823 /* We can't handle anything else with % args or %% ... yet. */
4824 if (strchr (fmt_str, '%'))
4825 return 0;
4827 if (arglist)
4828 return 0;
4830 /* If the format specifier was "", fprintf does nothing. */
4831 if (fmt_str[0] == '\0')
4833 /* Evaluate and ignore FILE* argument for side-effects. */
4834 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4835 return const0_rtx;
4838 /* When "string" doesn't contain %, replace all cases of
4839 fprintf(stream,string) with fputs(string,stream). The fputs
4840 builtin will take care of special cases like length == 1. */
4841 arglist = build_tree_list (NULL_TREE, fp);
4842 arglist = tree_cons (NULL_TREE, fmt, arglist);
4843 fn = fn_fputs;
4846 if (!fn)
4847 return 0;
4848 return expand_expr (build_function_call_expr (fn, arglist),
4849 target, mode, EXPAND_NORMAL);
4852 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4853 a normal call should be emitted rather than expanding the function
4854 inline. If convenient, the result should be placed in TARGET with
4855 mode MODE. */
4857 static rtx
4858 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4860 tree orig_arglist, dest, fmt;
4861 const char *fmt_str;
4863 orig_arglist = arglist;
4865 /* Verify the required arguments in the original call. */
4866 if (! arglist)
4867 return 0;
4868 dest = TREE_VALUE (arglist);
4869 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4870 return 0;
4871 arglist = TREE_CHAIN (arglist);
4872 if (! arglist)
4873 return 0;
4874 fmt = TREE_VALUE (arglist);
4875 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4876 return 0;
4877 arglist = TREE_CHAIN (arglist);
4879 /* Check whether the format is a literal string constant. */
4880 fmt_str = c_getstr (fmt);
4881 if (fmt_str == NULL)
4882 return 0;
4884 /* If the format doesn't contain % args or %%, use strcpy. */
4885 if (strchr (fmt_str, '%') == 0)
4887 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4888 tree exp;
4890 if (arglist || ! fn)
4891 return 0;
4892 expand_expr (build_function_call_expr (fn, orig_arglist),
4893 const0_rtx, VOIDmode, EXPAND_NORMAL);
4894 if (target == const0_rtx)
4895 return const0_rtx;
4896 exp = build_int_2 (strlen (fmt_str), 0);
4897 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4898 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4900 /* If the format is "%s", use strcpy if the result isn't used. */
4901 else if (strcmp (fmt_str, "%s") == 0)
4903 tree fn, arg, len;
4904 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4906 if (! fn)
4907 return 0;
4909 if (! arglist || TREE_CHAIN (arglist))
4910 return 0;
4911 arg = TREE_VALUE (arglist);
4912 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4913 return 0;
4915 if (target != const0_rtx)
4917 len = c_strlen (arg, 1);
4918 if (! len || TREE_CODE (len) != INTEGER_CST)
4919 return 0;
4921 else
4922 len = NULL_TREE;
4924 arglist = build_tree_list (NULL_TREE, arg);
4925 arglist = tree_cons (NULL_TREE, dest, arglist);
4926 expand_expr (build_function_call_expr (fn, arglist),
4927 const0_rtx, VOIDmode, EXPAND_NORMAL);
4929 if (target == const0_rtx)
4930 return const0_rtx;
4931 return expand_expr (len, target, mode, EXPAND_NORMAL);
4934 return 0;
4937 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4938 Return NULL_RTX if a normal call should be emitted rather than expanding
4939 the function in-line. EXP is the expression that is a call to the builtin
4940 function; if convenient, the result should be placed in TARGET. */
4942 static rtx
4943 expand_builtin_signbit (tree exp, rtx target)
4945 const struct real_format *fmt;
4946 enum machine_mode fmode, imode, rmode;
4947 HOST_WIDE_INT hi, lo;
4948 tree arg, arglist;
4949 int bitpos;
4950 rtx temp;
4952 arglist = TREE_OPERAND (exp, 1);
4953 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4954 return 0;
4956 arg = TREE_VALUE (arglist);
4957 fmode = TYPE_MODE (TREE_TYPE (arg));
4958 rmode = TYPE_MODE (TREE_TYPE (exp));
4959 fmt = REAL_MODE_FORMAT (fmode);
4961 /* For floating point formats without a sign bit, implement signbit
4962 as "ARG < 0.0". */
4963 if (fmt->signbit < 0)
4965 /* But we can't do this if the format supports signed zero. */
4966 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4967 return 0;
4969 arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
4970 build_real (TREE_TYPE (arg), dconst0)));
4971 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4974 imode = int_mode_for_mode (fmode);
4975 if (imode == BLKmode)
4976 return 0;
4978 bitpos = fmt->signbit;
4979 /* Handle targets with different FP word orders. */
4980 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4982 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4983 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4984 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4987 /* If the sign bit is not in the lowpart and the floating point format
4988 is wider than an integer, check that is twice the size of an integer
4989 so that we can use gen_highpart below. */
4990 if (bitpos >= GET_MODE_BITSIZE (rmode)
4991 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4992 return 0;
4994 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4995 temp = gen_lowpart (imode, temp);
4997 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4999 if (BITS_BIG_ENDIAN)
5000 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5001 temp = copy_to_mode_reg (imode, temp);
5002 temp = extract_bit_field (temp, 1, bitpos, 1,
5003 NULL_RTX, rmode, rmode,
5004 GET_MODE_SIZE (imode));
5006 else
5008 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5009 temp = gen_lowpart (rmode, temp);
5010 if (bitpos < HOST_BITS_PER_WIDE_INT)
5012 hi = 0;
5013 lo = (HOST_WIDE_INT) 1 << bitpos;
5015 else
5017 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5018 lo = 0;
5021 temp = force_reg (rmode, temp);
5022 temp = expand_binop (rmode, and_optab, temp,
5023 immed_double_const (lo, hi, rmode),
5024 target, 1, OPTAB_LIB_WIDEN);
5026 return temp;
5029 /* Expand an expression EXP that calls a built-in function,
5030 with result going to TARGET if that's convenient
5031 (and in mode MODE if that's convenient).
5032 SUBTARGET may be used as the target for computing one of EXP's operands.
5033 IGNORE is nonzero if the value is to be ignored. */
5036 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5037 int ignore)
5039 tree fndecl = get_callee_fndecl (exp);
5040 tree arglist = TREE_OPERAND (exp, 1);
5041 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5042 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5044 /* Perform postincrements before expanding builtin functions. */
5045 emit_queue ();
5047 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5048 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
5050 /* When not optimizing, generate calls to library functions for a certain
5051 set of builtins. */
5052 if (!optimize
5053 && !CALLED_AS_BUILT_IN (fndecl)
5054 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5055 && fcode != BUILT_IN_ALLOCA)
5056 return expand_call (exp, target, ignore);
5058 /* The built-in function expanders test for target == const0_rtx
5059 to determine whether the function's result will be ignored. */
5060 if (ignore)
5061 target = const0_rtx;
5063 /* If the result of a pure or const built-in function is ignored, and
5064 none of its arguments are volatile, we can avoid expanding the
5065 built-in call and just evaluate the arguments for side-effects. */
5066 if (target == const0_rtx
5067 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5069 bool volatilep = false;
5070 tree arg;
5072 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5073 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5075 volatilep = true;
5076 break;
5079 if (! volatilep)
5081 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5082 expand_expr (TREE_VALUE (arg), const0_rtx,
5083 VOIDmode, EXPAND_NORMAL);
5084 return const0_rtx;
5088 switch (fcode)
5090 case BUILT_IN_ABS:
5091 case BUILT_IN_LABS:
5092 case BUILT_IN_LLABS:
5093 case BUILT_IN_IMAXABS:
5094 /* build_function_call changes these into ABS_EXPR. */
5095 abort ();
5097 case BUILT_IN_FABS:
5098 case BUILT_IN_FABSF:
5099 case BUILT_IN_FABSL:
5100 target = expand_builtin_fabs (arglist, target, subtarget);
5101 if (target)
5102 return target;
5103 break;
5105 case BUILT_IN_CABS:
5106 case BUILT_IN_CABSF:
5107 case BUILT_IN_CABSL:
5108 if (flag_unsafe_math_optimizations)
5110 target = expand_builtin_cabs (arglist, target);
5111 if (target)
5112 return target;
5114 break;
5116 case BUILT_IN_CONJ:
5117 case BUILT_IN_CONJF:
5118 case BUILT_IN_CONJL:
5119 case BUILT_IN_CREAL:
5120 case BUILT_IN_CREALF:
5121 case BUILT_IN_CREALL:
5122 case BUILT_IN_CIMAG:
5123 case BUILT_IN_CIMAGF:
5124 case BUILT_IN_CIMAGL:
5125 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5126 and IMAGPART_EXPR. */
5127 abort ();
5129 case BUILT_IN_SIN:
5130 case BUILT_IN_SINF:
5131 case BUILT_IN_SINL:
5132 case BUILT_IN_COS:
5133 case BUILT_IN_COSF:
5134 case BUILT_IN_COSL:
5135 case BUILT_IN_EXP:
5136 case BUILT_IN_EXPF:
5137 case BUILT_IN_EXPL:
5138 case BUILT_IN_LOG:
5139 case BUILT_IN_LOGF:
5140 case BUILT_IN_LOGL:
5141 case BUILT_IN_LOG10:
5142 case BUILT_IN_LOG10F:
5143 case BUILT_IN_LOG10L:
5144 case BUILT_IN_LOG2:
5145 case BUILT_IN_LOG2F:
5146 case BUILT_IN_LOG2L:
5147 case BUILT_IN_TAN:
5148 case BUILT_IN_TANF:
5149 case BUILT_IN_TANL:
5150 case BUILT_IN_ATAN:
5151 case BUILT_IN_ATANF:
5152 case BUILT_IN_ATANL:
5153 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5154 because of possible accuracy problems. */
5155 if (! flag_unsafe_math_optimizations)
5156 break;
5157 case BUILT_IN_SQRT:
5158 case BUILT_IN_SQRTF:
5159 case BUILT_IN_SQRTL:
5160 case BUILT_IN_FLOOR:
5161 case BUILT_IN_FLOORF:
5162 case BUILT_IN_FLOORL:
5163 case BUILT_IN_CEIL:
5164 case BUILT_IN_CEILF:
5165 case BUILT_IN_CEILL:
5166 case BUILT_IN_TRUNC:
5167 case BUILT_IN_TRUNCF:
5168 case BUILT_IN_TRUNCL:
5169 case BUILT_IN_ROUND:
5170 case BUILT_IN_ROUNDF:
5171 case BUILT_IN_ROUNDL:
5172 case BUILT_IN_NEARBYINT:
5173 case BUILT_IN_NEARBYINTF:
5174 case BUILT_IN_NEARBYINTL:
5175 target = expand_builtin_mathfn (exp, target, subtarget);
5176 if (target)
5177 return target;
5178 break;
5180 case BUILT_IN_POW:
5181 case BUILT_IN_POWF:
5182 case BUILT_IN_POWL:
5183 target = expand_builtin_pow (exp, target, subtarget);
5184 if (target)
5185 return target;
5186 break;
5188 case BUILT_IN_ATAN2:
5189 case BUILT_IN_ATAN2F:
5190 case BUILT_IN_ATAN2L:
5191 if (! flag_unsafe_math_optimizations)
5192 break;
5193 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5194 if (target)
5195 return target;
5196 break;
5198 case BUILT_IN_APPLY_ARGS:
5199 return expand_builtin_apply_args ();
5201 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5202 FUNCTION with a copy of the parameters described by
5203 ARGUMENTS, and ARGSIZE. It returns a block of memory
5204 allocated on the stack into which is stored all the registers
5205 that might possibly be used for returning the result of a
5206 function. ARGUMENTS is the value returned by
5207 __builtin_apply_args. ARGSIZE is the number of bytes of
5208 arguments that must be copied. ??? How should this value be
5209 computed? We'll also need a safe worst case value for varargs
5210 functions. */
5211 case BUILT_IN_APPLY:
5212 if (!validate_arglist (arglist, POINTER_TYPE,
5213 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5214 && !validate_arglist (arglist, REFERENCE_TYPE,
5215 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5216 return const0_rtx;
5217 else
5219 int i;
5220 tree t;
5221 rtx ops[3];
5223 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5224 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5226 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5229 /* __builtin_return (RESULT) causes the function to return the
5230 value described by RESULT. RESULT is address of the block of
5231 memory returned by __builtin_apply. */
5232 case BUILT_IN_RETURN:
5233 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5234 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5235 NULL_RTX, VOIDmode, 0));
5236 return const0_rtx;
5238 case BUILT_IN_SAVEREGS:
5239 return expand_builtin_saveregs ();
5241 case BUILT_IN_ARGS_INFO:
5242 return expand_builtin_args_info (arglist);
5244 /* Return the address of the first anonymous stack arg. */
5245 case BUILT_IN_NEXT_ARG:
5246 return expand_builtin_next_arg (arglist);
5248 case BUILT_IN_CLASSIFY_TYPE:
5249 return expand_builtin_classify_type (arglist);
5251 case BUILT_IN_CONSTANT_P:
5252 return expand_builtin_constant_p (arglist, target_mode);
5254 case BUILT_IN_FRAME_ADDRESS:
5255 case BUILT_IN_RETURN_ADDRESS:
5256 return expand_builtin_frame_address (fndecl, arglist);
5258 /* Returns the address of the area where the structure is returned.
5259 0 otherwise. */
5260 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5261 if (arglist != 0
5262 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5263 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5264 return const0_rtx;
5265 else
5266 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5268 case BUILT_IN_ALLOCA:
5269 target = expand_builtin_alloca (arglist, target);
5270 if (target)
5271 return target;
5272 break;
5274 case BUILT_IN_FFS:
5275 case BUILT_IN_FFSL:
5276 case BUILT_IN_FFSLL:
5277 target = expand_builtin_unop (target_mode, arglist, target,
5278 subtarget, ffs_optab);
5279 if (target)
5280 return target;
5281 break;
5283 case BUILT_IN_CLZ:
5284 case BUILT_IN_CLZL:
5285 case BUILT_IN_CLZLL:
5286 target = expand_builtin_unop (target_mode, arglist, target,
5287 subtarget, clz_optab);
5288 if (target)
5289 return target;
5290 break;
5292 case BUILT_IN_CTZ:
5293 case BUILT_IN_CTZL:
5294 case BUILT_IN_CTZLL:
5295 target = expand_builtin_unop (target_mode, arglist, target,
5296 subtarget, ctz_optab);
5297 if (target)
5298 return target;
5299 break;
5301 case BUILT_IN_POPCOUNT:
5302 case BUILT_IN_POPCOUNTL:
5303 case BUILT_IN_POPCOUNTLL:
5304 target = expand_builtin_unop (target_mode, arglist, target,
5305 subtarget, popcount_optab);
5306 if (target)
5307 return target;
5308 break;
5310 case BUILT_IN_PARITY:
5311 case BUILT_IN_PARITYL:
5312 case BUILT_IN_PARITYLL:
5313 target = expand_builtin_unop (target_mode, arglist, target,
5314 subtarget, parity_optab);
5315 if (target)
5316 return target;
5317 break;
5319 case BUILT_IN_STRLEN:
5320 target = expand_builtin_strlen (arglist, target, target_mode);
5321 if (target)
5322 return target;
5323 break;
5325 case BUILT_IN_STRCPY:
5326 target = expand_builtin_strcpy (arglist, target, mode);
5327 if (target)
5328 return target;
5329 break;
5331 case BUILT_IN_STRNCPY:
5332 target = expand_builtin_strncpy (arglist, target, mode);
5333 if (target)
5334 return target;
5335 break;
5337 case BUILT_IN_STPCPY:
5338 target = expand_builtin_stpcpy (arglist, target, mode);
5339 if (target)
5340 return target;
5341 break;
5343 case BUILT_IN_STRCAT:
5344 target = expand_builtin_strcat (arglist, target, mode);
5345 if (target)
5346 return target;
5347 break;
5349 case BUILT_IN_STRNCAT:
5350 target = expand_builtin_strncat (arglist, target, mode);
5351 if (target)
5352 return target;
5353 break;
5355 case BUILT_IN_STRSPN:
5356 target = expand_builtin_strspn (arglist, target, mode);
5357 if (target)
5358 return target;
5359 break;
5361 case BUILT_IN_STRCSPN:
5362 target = expand_builtin_strcspn (arglist, target, mode);
5363 if (target)
5364 return target;
5365 break;
5367 case BUILT_IN_STRSTR:
5368 target = expand_builtin_strstr (arglist, target, mode);
5369 if (target)
5370 return target;
5371 break;
5373 case BUILT_IN_STRPBRK:
5374 target = expand_builtin_strpbrk (arglist, target, mode);
5375 if (target)
5376 return target;
5377 break;
5379 case BUILT_IN_INDEX:
5380 case BUILT_IN_STRCHR:
5381 target = expand_builtin_strchr (arglist, target, mode);
5382 if (target)
5383 return target;
5384 break;
5386 case BUILT_IN_RINDEX:
5387 case BUILT_IN_STRRCHR:
5388 target = expand_builtin_strrchr (arglist, target, mode);
5389 if (target)
5390 return target;
5391 break;
5393 case BUILT_IN_MEMCPY:
5394 target = expand_builtin_memcpy (arglist, target, mode);
5395 if (target)
5396 return target;
5397 break;
5399 case BUILT_IN_MEMPCPY:
5400 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5401 if (target)
5402 return target;
5403 break;
5405 case BUILT_IN_MEMMOVE:
5406 target = expand_builtin_memmove (arglist, target, mode);
5407 if (target)
5408 return target;
5409 break;
5411 case BUILT_IN_BCOPY:
5412 target = expand_builtin_bcopy (arglist);
5413 if (target)
5414 return target;
5415 break;
5417 case BUILT_IN_MEMSET:
5418 target = expand_builtin_memset (arglist, target, mode);
5419 if (target)
5420 return target;
5421 break;
5423 case BUILT_IN_BZERO:
5424 target = expand_builtin_bzero (arglist);
5425 if (target)
5426 return target;
5427 break;
5429 case BUILT_IN_STRCMP:
5430 target = expand_builtin_strcmp (exp, target, mode);
5431 if (target)
5432 return target;
5433 break;
5435 case BUILT_IN_STRNCMP:
5436 target = expand_builtin_strncmp (exp, target, mode);
5437 if (target)
5438 return target;
5439 break;
5441 case BUILT_IN_BCMP:
5442 case BUILT_IN_MEMCMP:
5443 target = expand_builtin_memcmp (exp, arglist, target, mode);
5444 if (target)
5445 return target;
5446 break;
5448 case BUILT_IN_SETJMP:
5449 target = expand_builtin_setjmp (arglist, target);
5450 if (target)
5451 return target;
5452 break;
5454 /* __builtin_longjmp is passed a pointer to an array of five words.
5455 It's similar to the C library longjmp function but works with
5456 __builtin_setjmp above. */
5457 case BUILT_IN_LONGJMP:
5458 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5459 break;
5460 else
5462 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5463 VOIDmode, 0);
5464 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5465 NULL_RTX, VOIDmode, 0);
5467 if (value != const1_rtx)
5469 error ("__builtin_longjmp second argument must be 1");
5470 return const0_rtx;
5473 expand_builtin_longjmp (buf_addr, value);
5474 return const0_rtx;
5477 case BUILT_IN_TRAP:
5478 expand_builtin_trap ();
5479 return const0_rtx;
5481 case BUILT_IN_PRINTF:
5482 target = expand_builtin_printf (arglist, target, mode, false);
5483 if (target)
5484 return target;
5485 break;
5487 case BUILT_IN_PRINTF_UNLOCKED:
5488 target = expand_builtin_printf (arglist, target, mode, true);
5489 if (target)
5490 return target;
5491 break;
5493 case BUILT_IN_FPUTS:
5494 target = expand_builtin_fputs (arglist, target, false);
5495 if (target)
5496 return target;
5497 break;
5499 case BUILT_IN_FPUTS_UNLOCKED:
5500 target = expand_builtin_fputs (arglist, target, true);
5501 if (target)
5502 return target;
5503 break;
5505 case BUILT_IN_FPRINTF:
5506 target = expand_builtin_fprintf (arglist, target, mode, false);
5507 if (target)
5508 return target;
5509 break;
5511 case BUILT_IN_FPRINTF_UNLOCKED:
5512 target = expand_builtin_fprintf (arglist, target, mode, true);
5513 if (target)
5514 return target;
5515 break;
5517 case BUILT_IN_SPRINTF:
5518 target = expand_builtin_sprintf (arglist, target, mode);
5519 if (target)
5520 return target;
5521 break;
5523 case BUILT_IN_SIGNBIT:
5524 case BUILT_IN_SIGNBITF:
5525 case BUILT_IN_SIGNBITL:
5526 target = expand_builtin_signbit (exp, target);
5527 if (target)
5528 return target;
5529 break;
5531 /* Various hooks for the DWARF 2 __throw routine. */
5532 case BUILT_IN_UNWIND_INIT:
5533 expand_builtin_unwind_init ();
5534 return const0_rtx;
5535 case BUILT_IN_DWARF_CFA:
5536 return virtual_cfa_rtx;
5537 #ifdef DWARF2_UNWIND_INFO
5538 case BUILT_IN_DWARF_SP_COLUMN:
5539 return expand_builtin_dwarf_sp_column ();
5540 case BUILT_IN_INIT_DWARF_REG_SIZES:
5541 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5542 return const0_rtx;
5543 #endif
5544 case BUILT_IN_FROB_RETURN_ADDR:
5545 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5546 case BUILT_IN_EXTRACT_RETURN_ADDR:
5547 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5548 case BUILT_IN_EH_RETURN:
5549 expand_builtin_eh_return (TREE_VALUE (arglist),
5550 TREE_VALUE (TREE_CHAIN (arglist)));
5551 return const0_rtx;
5552 #ifdef EH_RETURN_DATA_REGNO
5553 case BUILT_IN_EH_RETURN_DATA_REGNO:
5554 return expand_builtin_eh_return_data_regno (arglist);
5555 #endif
5556 case BUILT_IN_EXTEND_POINTER:
5557 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5559 case BUILT_IN_VA_START:
5560 case BUILT_IN_STDARG_START:
5561 return expand_builtin_va_start (arglist);
5562 case BUILT_IN_VA_END:
5563 return expand_builtin_va_end (arglist);
5564 case BUILT_IN_VA_COPY:
5565 return expand_builtin_va_copy (arglist);
5566 case BUILT_IN_EXPECT:
5567 return expand_builtin_expect (arglist, target);
5568 case BUILT_IN_PREFETCH:
5569 expand_builtin_prefetch (arglist);
5570 return const0_rtx;
5573 default: /* just do library call, if unknown builtin */
5574 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5575 error ("built-in function `%s' not currently supported",
5576 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5579 /* The switch statement above can drop through to cause the function
5580 to be called normally. */
5581 return expand_call (exp, target, ignore);
5584 /* Determine whether a tree node represents a call to a built-in
5585 function. If the tree T is a call to a built-in function with
5586 the right number of arguments of the appropriate types, return
5587 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5588 Otherwise the return value is END_BUILTINS. */
5590 enum built_in_function
5591 builtin_mathfn_code (tree t)
5593 tree fndecl, arglist, parmlist;
5594 tree argtype, parmtype;
5596 if (TREE_CODE (t) != CALL_EXPR
5597 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5598 return END_BUILTINS;
5600 fndecl = get_callee_fndecl (t);
5601 if (fndecl == NULL_TREE
5602 || TREE_CODE (fndecl) != FUNCTION_DECL
5603 || ! DECL_BUILT_IN (fndecl)
5604 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5605 return END_BUILTINS;
5607 arglist = TREE_OPERAND (t, 1);
5608 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5609 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5611 /* If a function doesn't take a variable number of arguments,
5612 the last element in the list will have type `void'. */
5613 parmtype = TREE_VALUE (parmlist);
5614 if (VOID_TYPE_P (parmtype))
5616 if (arglist)
5617 return END_BUILTINS;
5618 return DECL_FUNCTION_CODE (fndecl);
5621 if (! arglist)
5622 return END_BUILTINS;
5624 argtype = TREE_TYPE (TREE_VALUE (arglist));
5626 if (SCALAR_FLOAT_TYPE_P (parmtype))
5628 if (! SCALAR_FLOAT_TYPE_P (argtype))
5629 return END_BUILTINS;
5631 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5633 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5634 return END_BUILTINS;
5636 else if (POINTER_TYPE_P (parmtype))
5638 if (! POINTER_TYPE_P (argtype))
5639 return END_BUILTINS;
5641 else if (INTEGRAL_TYPE_P (parmtype))
5643 if (! INTEGRAL_TYPE_P (argtype))
5644 return END_BUILTINS;
5646 else
5647 return END_BUILTINS;
5649 arglist = TREE_CHAIN (arglist);
5652 /* Variable-length argument list. */
5653 return DECL_FUNCTION_CODE (fndecl);
5656 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5657 constant. ARGLIST is the argument list of the call. */
5659 static tree
5660 fold_builtin_constant_p (tree arglist)
5662 if (arglist == 0)
5663 return 0;
5665 arglist = TREE_VALUE (arglist);
5667 /* We return 1 for a numeric type that's known to be a constant
5668 value at compile-time or for an aggregate type that's a
5669 literal constant. */
5670 STRIP_NOPS (arglist);
5672 /* If we know this is a constant, emit the constant of one. */
5673 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5674 || (TREE_CODE (arglist) == CONSTRUCTOR
5675 && TREE_CONSTANT (arglist))
5676 || (TREE_CODE (arglist) == ADDR_EXPR
5677 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5678 return integer_one_node;
5680 /* If this expression has side effects, show we don't know it to be a
5681 constant. Likewise if it's a pointer or aggregate type since in
5682 those case we only want literals, since those are only optimized
5683 when generating RTL, not later.
5684 And finally, if we are compiling an initializer, not code, we
5685 need to return a definite result now; there's not going to be any
5686 more optimization done. */
5687 if (TREE_SIDE_EFFECTS (arglist)
5688 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5689 || POINTER_TYPE_P (TREE_TYPE (arglist))
5690 || cfun == 0)
5691 return integer_zero_node;
5693 return 0;
5696 /* Fold a call to __builtin_classify_type. */
5698 static tree
5699 fold_builtin_classify_type (tree arglist)
5701 if (arglist == 0)
5702 return build_int_2 (no_type_class, 0);
5704 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5707 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5709 static tree
5710 fold_builtin_inf (tree type, int warn)
5712 REAL_VALUE_TYPE real;
5714 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5715 warning ("target format does not support infinity");
5717 real_inf (&real);
5718 return build_real (type, real);
5721 /* Fold a call to __builtin_nan or __builtin_nans. */
5723 static tree
5724 fold_builtin_nan (tree arglist, tree type, int quiet)
5726 REAL_VALUE_TYPE real;
5727 const char *str;
5729 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5730 return 0;
5731 str = c_getstr (TREE_VALUE (arglist));
5732 if (!str)
5733 return 0;
5735 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5736 return 0;
5738 return build_real (type, real);
5741 /* Return true if the floating point expression T has an integer value.
5742 We also allow +Inf, -Inf and NaN to be considered integer values. */
5744 static bool
5745 integer_valued_real_p (tree t)
5747 switch (TREE_CODE (t))
5749 case FLOAT_EXPR:
5750 return true;
5752 case ABS_EXPR:
5753 case SAVE_EXPR:
5754 case NON_LVALUE_EXPR:
5755 return integer_valued_real_p (TREE_OPERAND (t, 0));
5757 case COMPOUND_EXPR:
5758 case MODIFY_EXPR:
5759 case BIND_EXPR:
5760 return integer_valued_real_p (TREE_OPERAND (t, 1));
5762 case PLUS_EXPR:
5763 case MINUS_EXPR:
5764 case MULT_EXPR:
5765 case MIN_EXPR:
5766 case MAX_EXPR:
5767 return integer_valued_real_p (TREE_OPERAND (t, 0))
5768 && integer_valued_real_p (TREE_OPERAND (t, 1));
5770 case COND_EXPR:
5771 return integer_valued_real_p (TREE_OPERAND (t, 1))
5772 && integer_valued_real_p (TREE_OPERAND (t, 2));
5774 case REAL_CST:
5775 if (! TREE_CONSTANT_OVERFLOW (t))
5777 REAL_VALUE_TYPE c, cint;
5779 c = TREE_REAL_CST (t);
5780 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5781 return real_identical (&c, &cint);
5784 case NOP_EXPR:
5786 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5787 if (TREE_CODE (type) == INTEGER_TYPE)
5788 return true;
5789 if (TREE_CODE (type) == REAL_TYPE)
5790 return integer_valued_real_p (TREE_OPERAND (t, 0));
5791 break;
5794 case CALL_EXPR:
5795 switch (builtin_mathfn_code (t))
5797 case BUILT_IN_CEIL:
5798 case BUILT_IN_CEILF:
5799 case BUILT_IN_CEILL:
5800 case BUILT_IN_FLOOR:
5801 case BUILT_IN_FLOORF:
5802 case BUILT_IN_FLOORL:
5803 case BUILT_IN_NEARBYINT:
5804 case BUILT_IN_NEARBYINTF:
5805 case BUILT_IN_NEARBYINTL:
5806 case BUILT_IN_ROUND:
5807 case BUILT_IN_ROUNDF:
5808 case BUILT_IN_ROUNDL:
5809 case BUILT_IN_TRUNC:
5810 case BUILT_IN_TRUNCF:
5811 case BUILT_IN_TRUNCL:
5812 return true;
5814 default:
5815 break;
5817 break;
5819 default:
5820 break;
5822 return false;
5825 /* EXP is assumed to be builtin call where truncation can be propagated
5826 across (for instance floor((double)f) == (double)floorf (f).
5827 Do the transformation. */
5829 static tree
5830 fold_trunc_transparent_mathfn (tree exp)
5832 tree fndecl = get_callee_fndecl (exp);
5833 tree arglist = TREE_OPERAND (exp, 1);
5834 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5835 tree arg;
5837 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5838 return 0;
5840 arg = TREE_VALUE (arglist);
5841 /* Integer rounding functions are idempotent. */
5842 if (fcode == builtin_mathfn_code (arg))
5843 return arg;
5845 /* If argument is already integer valued, and we don't need to worry
5846 about setting errno, there's no need to perform rounding. */
5847 if (! flag_errno_math && integer_valued_real_p (arg))
5848 return arg;
5850 if (optimize)
5852 tree arg0 = strip_float_extensions (arg);
5853 tree ftype = TREE_TYPE (exp);
5854 tree newtype = TREE_TYPE (arg0);
5855 tree decl;
5857 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5858 && (decl = mathfn_built_in (newtype, fcode)))
5860 arglist =
5861 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5862 return convert (ftype,
5863 build_function_call_expr (decl, arglist));
5866 return 0;
5869 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5870 function's DECL, ARGLIST is the argument list and TYPE is the return
5871 type. Return NULL_TREE if no simplification can be made. */
5873 static tree
5874 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5876 tree arg;
5878 if (!arglist || TREE_CHAIN (arglist))
5879 return NULL_TREE;
5881 arg = TREE_VALUE (arglist);
5882 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5883 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5884 return NULL_TREE;
5886 /* Evaluate cabs of a constant at compile-time. */
5887 if (flag_unsafe_math_optimizations
5888 && TREE_CODE (arg) == COMPLEX_CST
5889 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5890 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5891 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5892 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5894 REAL_VALUE_TYPE r, i;
5896 r = TREE_REAL_CST (TREE_REALPART (arg));
5897 i = TREE_REAL_CST (TREE_IMAGPART (arg));
5899 real_arithmetic (&r, MULT_EXPR, &r, &r);
5900 real_arithmetic (&i, MULT_EXPR, &i, &i);
5901 real_arithmetic (&r, PLUS_EXPR, &r, &i);
5902 if (real_sqrt (&r, TYPE_MODE (type), &r)
5903 || ! flag_trapping_math)
5904 return build_real (type, r);
5907 /* If either part is zero, cabs is fabs of the other. */
5908 if (TREE_CODE (arg) == COMPLEX_EXPR
5909 && real_zerop (TREE_OPERAND (arg, 0)))
5910 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5911 if (TREE_CODE (arg) == COMPLEX_EXPR
5912 && real_zerop (TREE_OPERAND (arg, 1)))
5913 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5915 if (flag_unsafe_math_optimizations)
5917 enum built_in_function fcode;
5918 tree sqrtfn;
5920 fcode = DECL_FUNCTION_CODE (fndecl);
5921 if (fcode == BUILT_IN_CABS)
5922 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5923 else if (fcode == BUILT_IN_CABSF)
5924 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5925 else if (fcode == BUILT_IN_CABSL)
5926 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5927 else
5928 sqrtfn = NULL_TREE;
5930 if (sqrtfn != NULL_TREE)
5932 tree rpart, ipart, result, arglist;
5934 arg = save_expr (arg);
5936 rpart = fold (build1 (REALPART_EXPR, type, arg));
5937 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5939 rpart = save_expr (rpart);
5940 ipart = save_expr (ipart);
5942 result = fold (build (PLUS_EXPR, type,
5943 fold (build (MULT_EXPR, type,
5944 rpart, rpart)),
5945 fold (build (MULT_EXPR, type,
5946 ipart, ipart))));
5948 arglist = build_tree_list (NULL_TREE, result);
5949 return build_function_call_expr (sqrtfn, arglist);
5953 return NULL_TREE;
5956 /* Fold function call to builtin trunc, truncf or truncl. Return
5957 NULL_TREE if no simplification can be made. */
5959 static tree
5960 fold_builtin_trunc (tree exp)
5962 tree arglist = TREE_OPERAND (exp, 1);
5963 tree arg;
5965 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5966 return 0;
5968 /* Optimize trunc of constant value. */
5969 arg = TREE_VALUE (arglist);
5970 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5972 REAL_VALUE_TYPE r, x;
5973 tree type = TREE_TYPE (exp);
5975 x = TREE_REAL_CST (arg);
5976 real_trunc (&r, TYPE_MODE (type), &x);
5977 return build_real (type, r);
5980 return fold_trunc_transparent_mathfn (exp);
5983 /* Fold function call to builtin floor, floorf or floorl. Return
5984 NULL_TREE if no simplification can be made. */
5986 static tree
5987 fold_builtin_floor (tree exp)
5989 tree arglist = TREE_OPERAND (exp, 1);
5990 tree arg;
5992 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5993 return 0;
5995 /* Optimize floor of constant value. */
5996 arg = TREE_VALUE (arglist);
5997 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5999 REAL_VALUE_TYPE x;
6001 x = TREE_REAL_CST (arg);
6002 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6004 tree type = TREE_TYPE (exp);
6005 REAL_VALUE_TYPE r;
6007 real_floor (&r, TYPE_MODE (type), &x);
6008 return build_real (type, r);
6012 return fold_trunc_transparent_mathfn (exp);
6015 /* Fold function call to builtin ceil, ceilf or ceill. Return
6016 NULL_TREE if no simplification can be made. */
6018 static tree
6019 fold_builtin_ceil (tree exp)
6021 tree arglist = TREE_OPERAND (exp, 1);
6022 tree arg;
6024 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6025 return 0;
6027 /* Optimize ceil of constant value. */
6028 arg = TREE_VALUE (arglist);
6029 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6031 REAL_VALUE_TYPE x;
6033 x = TREE_REAL_CST (arg);
6034 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6036 tree type = TREE_TYPE (exp);
6037 REAL_VALUE_TYPE r;
6039 real_ceil (&r, TYPE_MODE (type), &x);
6040 return build_real (type, r);
6044 return fold_trunc_transparent_mathfn (exp);
6047 /* Fold function call to builtin round, roundf or roundl. Return
6048 NULL_TREE if no simplification can be made. */
6050 static tree
6051 fold_builtin_round (tree exp)
6053 tree arglist = TREE_OPERAND (exp, 1);
6054 tree arg;
6056 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6057 return 0;
6059 /* Optimize ceil of constant value. */
6060 arg = TREE_VALUE (arglist);
6061 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6063 REAL_VALUE_TYPE x;
6065 x = TREE_REAL_CST (arg);
6066 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6068 tree type = TREE_TYPE (exp);
6069 REAL_VALUE_TYPE r;
6071 real_round (&r, TYPE_MODE (type), &x);
6072 return build_real (type, r);
6076 return fold_trunc_transparent_mathfn (exp);
6079 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6080 and their long and long long variants (i.e. ffsl and ffsll).
6081 Return NULL_TREE if no simplification can be made. */
6083 static tree
6084 fold_builtin_bitop (tree exp)
6086 tree fndecl = get_callee_fndecl (exp);
6087 tree arglist = TREE_OPERAND (exp, 1);
6088 tree arg;
6090 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6091 return NULL_TREE;
6093 /* Optimize for constant argument. */
6094 arg = TREE_VALUE (arglist);
6095 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6097 HOST_WIDE_INT hi, width, result;
6098 unsigned HOST_WIDE_INT lo;
6099 tree type, t;
6101 type = TREE_TYPE (arg);
6102 width = TYPE_PRECISION (type);
6103 lo = TREE_INT_CST_LOW (arg);
6105 /* Clear all the bits that are beyond the type's precision. */
6106 if (width > HOST_BITS_PER_WIDE_INT)
6108 hi = TREE_INT_CST_HIGH (arg);
6109 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6110 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6112 else
6114 hi = 0;
6115 if (width < HOST_BITS_PER_WIDE_INT)
6116 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6119 switch (DECL_FUNCTION_CODE (fndecl))
6121 case BUILT_IN_FFS:
6122 case BUILT_IN_FFSL:
6123 case BUILT_IN_FFSLL:
6124 if (lo != 0)
6125 result = exact_log2 (lo & -lo) + 1;
6126 else if (hi != 0)
6127 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6128 else
6129 result = 0;
6130 break;
6132 case BUILT_IN_CLZ:
6133 case BUILT_IN_CLZL:
6134 case BUILT_IN_CLZLL:
6135 if (hi != 0)
6136 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6137 else if (lo != 0)
6138 result = width - floor_log2 (lo) - 1;
6139 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6140 result = width;
6141 break;
6143 case BUILT_IN_CTZ:
6144 case BUILT_IN_CTZL:
6145 case BUILT_IN_CTZLL:
6146 if (lo != 0)
6147 result = exact_log2 (lo & -lo);
6148 else if (hi != 0)
6149 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6150 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6151 result = width;
6152 break;
6154 case BUILT_IN_POPCOUNT:
6155 case BUILT_IN_POPCOUNTL:
6156 case BUILT_IN_POPCOUNTLL:
6157 result = 0;
6158 while (lo)
6159 result++, lo &= lo - 1;
6160 while (hi)
6161 result++, hi &= hi - 1;
6162 break;
6164 case BUILT_IN_PARITY:
6165 case BUILT_IN_PARITYL:
6166 case BUILT_IN_PARITYLL:
6167 result = 0;
6168 while (lo)
6169 result++, lo &= lo - 1;
6170 while (hi)
6171 result++, hi &= hi - 1;
6172 result &= 1;
6173 break;
6175 default:
6176 abort();
6179 t = build_int_2 (result, 0);
6180 TREE_TYPE (t) = TREE_TYPE (exp);
6181 return t;
6184 return NULL_TREE;
6187 /* Return true if EXPR is the real constant contained in VALUE. */
6189 static bool
6190 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6192 STRIP_NOPS (expr);
6194 return ((TREE_CODE (expr) == REAL_CST
6195 && ! TREE_CONSTANT_OVERFLOW (expr)
6196 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6197 || (TREE_CODE (expr) == COMPLEX_CST
6198 && real_dconstp (TREE_REALPART (expr), value)
6199 && real_zerop (TREE_IMAGPART (expr))));
6202 /* A subroutine of fold_builtin to fold the various logarithmic
6203 functions. EXP is the CALL_EXPR of a call to a builtin log*
6204 function. VALUE is the base of the log* function. */
6206 static tree
6207 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6209 tree arglist = TREE_OPERAND (exp, 1);
6211 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6213 tree fndecl = get_callee_fndecl (exp);
6214 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6215 tree arg = TREE_VALUE (arglist);
6216 const enum built_in_function fcode = builtin_mathfn_code (arg);
6218 /* Optimize log*(1.0) = 0.0. */
6219 if (real_onep (arg))
6220 return build_real (type, dconst0);
6222 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6223 exactly, then only do this if flag_unsafe_math_optimizations. */
6224 if (exact_real_truncate (TYPE_MODE (type), value)
6225 || flag_unsafe_math_optimizations)
6227 const REAL_VALUE_TYPE value_truncate =
6228 real_value_truncate (TYPE_MODE (type), *value);
6229 if (real_dconstp (arg, &value_truncate))
6230 return build_real (type, dconst1);
6233 /* Special case, optimize logN(expN(x)) = x. */
6234 if (flag_unsafe_math_optimizations
6235 && ((value == &dconste
6236 && (fcode == BUILT_IN_EXP
6237 || fcode == BUILT_IN_EXPF
6238 || fcode == BUILT_IN_EXPL))
6239 || (value == &dconst2
6240 && (fcode == BUILT_IN_EXP2
6241 || fcode == BUILT_IN_EXP2F
6242 || fcode == BUILT_IN_EXP2L))
6243 || (value == &dconst10
6244 && (fcode == BUILT_IN_EXP10
6245 || fcode == BUILT_IN_EXP10F
6246 || fcode == BUILT_IN_EXP10L))))
6247 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6249 /* Optimize log*(func()) for various exponential functions. We
6250 want to determine the value "x" and the power "exponent" in
6251 order to transform logN(x**exponent) into exponent*logN(x). */
6252 if (flag_unsafe_math_optimizations)
6254 tree exponent = 0, x = 0;
6256 switch (fcode)
6258 case BUILT_IN_EXP:
6259 case BUILT_IN_EXPF:
6260 case BUILT_IN_EXPL:
6261 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6262 x = build_real (type,
6263 real_value_truncate (TYPE_MODE (type), dconste));
6264 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6265 break;
6266 case BUILT_IN_EXP2:
6267 case BUILT_IN_EXP2F:
6268 case BUILT_IN_EXP2L:
6269 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6270 x = build_real (type, dconst2);
6271 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6272 break;
6273 case BUILT_IN_EXP10:
6274 case BUILT_IN_EXP10F:
6275 case BUILT_IN_EXP10L:
6276 case BUILT_IN_POW10:
6277 case BUILT_IN_POW10F:
6278 case BUILT_IN_POW10L:
6279 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6280 x = build_real (type, dconst10);
6281 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6282 break;
6283 case BUILT_IN_SQRT:
6284 case BUILT_IN_SQRTF:
6285 case BUILT_IN_SQRTL:
6286 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6287 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6288 exponent = build_real (type, dconsthalf);
6289 break;
6290 case BUILT_IN_CBRT:
6291 case BUILT_IN_CBRTF:
6292 case BUILT_IN_CBRTL:
6293 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6294 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6295 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6296 dconstthird));
6297 break;
6298 case BUILT_IN_POW:
6299 case BUILT_IN_POWF:
6300 case BUILT_IN_POWL:
6301 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6302 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6303 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6304 break;
6305 default:
6306 break;
6309 /* Now perform the optimization. */
6310 if (x && exponent)
6312 tree logfn;
6313 arglist = build_tree_list (NULL_TREE, x);
6314 logfn = build_function_call_expr (fndecl, arglist);
6315 return fold (build (MULT_EXPR, type, exponent, logfn));
6320 return 0;
6323 /* A subroutine of fold_builtin to fold the various exponent
6324 functions. EXP is the CALL_EXPR of a call to a builtin function.
6325 VALUE is the value which will be raised to a power. */
6327 static tree
6328 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6330 tree arglist = TREE_OPERAND (exp, 1);
6332 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6334 tree fndecl = get_callee_fndecl (exp);
6335 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6336 tree arg = TREE_VALUE (arglist);
6338 /* Optimize exp*(0.0) = 1.0. */
6339 if (real_zerop (arg))
6340 return build_real (type, dconst1);
6342 /* Optimize expN(1.0) = N. */
6343 if (real_onep (arg))
6345 REAL_VALUE_TYPE cst;
6347 real_convert (&cst, TYPE_MODE (type), value);
6348 return build_real (type, cst);
6351 /* Attempt to evaluate expN(integer) at compile-time. */
6352 if (flag_unsafe_math_optimizations
6353 && TREE_CODE (arg) == REAL_CST
6354 && ! TREE_CONSTANT_OVERFLOW (arg))
6356 REAL_VALUE_TYPE cint;
6357 REAL_VALUE_TYPE c;
6358 HOST_WIDE_INT n;
6360 c = TREE_REAL_CST (arg);
6361 n = real_to_integer (&c);
6362 real_from_integer (&cint, VOIDmode, n,
6363 n < 0 ? -1 : 0, 0);
6364 if (real_identical (&c, &cint))
6366 REAL_VALUE_TYPE x;
6368 real_powi (&x, TYPE_MODE (type), value, n);
6369 return build_real (type, x);
6373 /* Optimize expN(logN(x)) = x. */
6374 if (flag_unsafe_math_optimizations)
6376 const enum built_in_function fcode = builtin_mathfn_code (arg);
6378 if ((value == &dconste
6379 && (fcode == BUILT_IN_LOG
6380 || fcode == BUILT_IN_LOGF
6381 || fcode == BUILT_IN_LOGL))
6382 || (value == &dconst2
6383 && (fcode == BUILT_IN_LOG2
6384 || fcode == BUILT_IN_LOG2F
6385 || fcode == BUILT_IN_LOG2L))
6386 || (value == &dconst10
6387 && (fcode == BUILT_IN_LOG10
6388 || fcode == BUILT_IN_LOG10F
6389 || fcode == BUILT_IN_LOG10L)))
6390 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6394 return 0;
6397 /* Fold function call to builtin memcpy. Return
6398 NULL_TREE if no simplification can be made. */
6400 static tree
6401 fold_builtin_memcpy (tree exp)
6403 tree arglist = TREE_OPERAND (exp, 1);
6404 tree dest, src, len;
6406 if (!validate_arglist (arglist,
6407 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6408 return 0;
6410 dest = TREE_VALUE (arglist);
6411 src = TREE_VALUE (TREE_CHAIN (arglist));
6412 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6414 /* If the LEN parameter is zero, return DEST. */
6415 if (integer_zerop (len))
6416 return omit_one_operand (TREE_TYPE (exp), dest, src);
6418 /* If SRC and DEST are the same (and not volatile), return DEST. */
6419 if (operand_equal_p (src, dest, 0))
6420 return omit_one_operand (TREE_TYPE (exp), dest, len);
6422 return 0;
6425 /* Fold function call to builtin mempcpy. Return
6426 NULL_TREE if no simplification can be made. */
6428 static tree
6429 fold_builtin_mempcpy (tree exp)
6431 tree arglist = TREE_OPERAND (exp, 1);
6432 tree dest, src, len;
6434 if (!validate_arglist (arglist,
6435 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6436 return 0;
6438 dest = TREE_VALUE (arglist);
6439 src = TREE_VALUE (TREE_CHAIN (arglist));
6440 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6442 /* If the LEN parameter is zero, return DEST. */
6443 if (integer_zerop (len))
6444 return omit_one_operand (TREE_TYPE (exp), dest, src);
6446 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6447 if (operand_equal_p (src, dest, 0))
6449 tree temp = convert (TREE_TYPE (dest), len);
6450 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6451 return convert (TREE_TYPE (exp), temp);
6454 return 0;
6457 /* Fold function call to builtin memmove. Return
6458 NULL_TREE if no simplification can be made. */
6460 static tree
6461 fold_builtin_memmove (tree exp)
6463 tree arglist = TREE_OPERAND (exp, 1);
6464 tree dest, src, len;
6466 if (!validate_arglist (arglist,
6467 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6468 return 0;
6470 dest = TREE_VALUE (arglist);
6471 src = TREE_VALUE (TREE_CHAIN (arglist));
6472 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6474 /* If the LEN parameter is zero, return DEST. */
6475 if (integer_zerop (len))
6476 return omit_one_operand (TREE_TYPE (exp), dest, src);
6478 /* If SRC and DEST are the same (and not volatile), return DEST. */
6479 if (operand_equal_p (src, dest, 0))
6480 return omit_one_operand (TREE_TYPE (exp), dest, len);
6482 return 0;
6485 /* Fold function call to builtin strcpy. Return
6486 NULL_TREE if no simplification can be made. */
6488 static tree
6489 fold_builtin_strcpy (tree exp)
6491 tree arglist = TREE_OPERAND (exp, 1);
6492 tree dest, src;
6494 if (!validate_arglist (arglist,
6495 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6496 return 0;
6498 dest = TREE_VALUE (arglist);
6499 src = TREE_VALUE (TREE_CHAIN (arglist));
6501 /* If SRC and DEST are the same (and not volatile), return DEST. */
6502 if (operand_equal_p (src, dest, 0))
6503 return convert (TREE_TYPE (exp), dest);
6505 return 0;
6508 /* Fold function call to builtin strncpy. Return
6509 NULL_TREE if no simplification can be made. */
6511 static tree
6512 fold_builtin_strncpy (tree exp)
6514 tree arglist = TREE_OPERAND (exp, 1);
6515 tree dest, src, len;
6517 if (!validate_arglist (arglist,
6518 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6519 return 0;
6521 dest = TREE_VALUE (arglist);
6522 src = TREE_VALUE (TREE_CHAIN (arglist));
6523 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6525 /* If the LEN parameter is zero, return DEST. */
6526 if (integer_zerop (len))
6527 return omit_one_operand (TREE_TYPE (exp), dest, src);
6529 return 0;
6532 /* Fold function call to builtin memcmp. Return
6533 NULL_TREE if no simplification can be made. */
6535 static tree
6536 fold_builtin_memcmp (tree exp)
6538 tree arglist = TREE_OPERAND (exp, 1);
6539 tree arg1, arg2, len;
6541 if (!validate_arglist (arglist,
6542 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6543 return 0;
6545 arg1 = TREE_VALUE (arglist);
6546 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6547 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6549 /* If the LEN parameter is zero, return zero. */
6550 if (integer_zerop (len))
6552 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6553 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6556 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6557 if (operand_equal_p (arg1, arg2, 0))
6558 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6560 return 0;
6563 /* Fold function call to builtin strcmp. Return
6564 NULL_TREE if no simplification can be made. */
6566 static tree
6567 fold_builtin_strcmp (tree exp)
6569 tree arglist = TREE_OPERAND (exp, 1);
6570 tree arg1, arg2;
6571 const char *p1, *p2;
6573 if (!validate_arglist (arglist,
6574 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6575 return 0;
6577 arg1 = TREE_VALUE (arglist);
6578 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6580 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6581 if (operand_equal_p (arg1, arg2, 0))
6582 return convert (TREE_TYPE (exp), integer_zero_node);
6584 p1 = c_getstr (arg1);
6585 p2 = c_getstr (arg2);
6587 if (p1 && p2)
6589 tree temp;
6590 const int i = strcmp (p1, p2);
6591 if (i < 0)
6592 temp = integer_minus_one_node;
6593 else if (i > 0)
6594 temp = integer_one_node;
6595 else
6596 temp = integer_zero_node;
6597 return convert (TREE_TYPE (exp), temp);
6600 return 0;
6603 /* Fold function call to builtin strncmp. Return
6604 NULL_TREE if no simplification can be made. */
6606 static tree
6607 fold_builtin_strncmp (tree exp)
6609 tree arglist = TREE_OPERAND (exp, 1);
6610 tree arg1, arg2, len;
6611 const char *p1, *p2;
6613 if (!validate_arglist (arglist,
6614 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6615 return 0;
6617 arg1 = TREE_VALUE (arglist);
6618 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6619 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6621 /* If the LEN parameter is zero, return zero. */
6622 if (integer_zerop (len))
6624 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6625 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6628 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6629 if (operand_equal_p (arg1, arg2, 0))
6630 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6632 p1 = c_getstr (arg1);
6633 p2 = c_getstr (arg2);
6635 if (host_integerp (len, 1) && p1 && p2)
6637 tree temp;
6638 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6639 if (i < 0)
6640 temp = integer_minus_one_node;
6641 else if (i > 0)
6642 temp = integer_one_node;
6643 else
6644 temp = integer_zero_node;
6645 return convert (TREE_TYPE (exp), temp);
6648 return 0;
6651 /* Fold function call to builtin signbit, signbitf or signbitl. Return
6652 NULL_TREE if no simplification can be made. */
6654 static tree
6655 fold_builtin_signbit (tree exp)
6657 tree arglist = TREE_OPERAND (exp, 1);
6658 tree arg, temp;
6660 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6661 return NULL_TREE;
6663 arg = TREE_VALUE (arglist);
6665 /* If ARG is a compile-time constant, determine the result. */
6666 if (TREE_CODE (arg) == REAL_CST
6667 && !TREE_CONSTANT_OVERFLOW (arg))
6669 REAL_VALUE_TYPE c;
6671 c = TREE_REAL_CST (arg);
6672 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
6673 return convert (TREE_TYPE (exp), temp);
6676 /* If ARG is non-negative, the result is always zero. */
6677 if (tree_expr_nonnegative_p (arg))
6678 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
6680 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
6681 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
6682 return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
6683 build_real (TREE_TYPE (arg), dconst0)));
6685 return NULL_TREE;
6689 /* Used by constant folding to eliminate some builtin calls early. EXP is
6690 the CALL_EXPR of a call to a builtin function. */
6692 tree
6693 fold_builtin (tree exp)
6695 tree fndecl = get_callee_fndecl (exp);
6696 tree arglist = TREE_OPERAND (exp, 1);
6697 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6699 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6700 return 0;
6702 switch (DECL_FUNCTION_CODE (fndecl))
6704 case BUILT_IN_CONSTANT_P:
6705 return fold_builtin_constant_p (arglist);
6707 case BUILT_IN_CLASSIFY_TYPE:
6708 return fold_builtin_classify_type (arglist);
6710 case BUILT_IN_STRLEN:
6711 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6713 tree len = c_strlen (TREE_VALUE (arglist), 0);
6714 if (len)
6716 /* Convert from the internal "sizetype" type to "size_t". */
6717 if (size_type_node)
6718 len = convert (size_type_node, len);
6719 return len;
6722 break;
6724 case BUILT_IN_FABS:
6725 case BUILT_IN_FABSF:
6726 case BUILT_IN_FABSL:
6727 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6728 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6729 break;
6731 case BUILT_IN_CABS:
6732 case BUILT_IN_CABSF:
6733 case BUILT_IN_CABSL:
6734 return fold_builtin_cabs (fndecl, arglist, type);
6736 case BUILT_IN_SQRT:
6737 case BUILT_IN_SQRTF:
6738 case BUILT_IN_SQRTL:
6739 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6741 enum built_in_function fcode;
6742 tree arg = TREE_VALUE (arglist);
6744 /* Optimize sqrt of constant value. */
6745 if (TREE_CODE (arg) == REAL_CST
6746 && ! TREE_CONSTANT_OVERFLOW (arg))
6748 REAL_VALUE_TYPE r, x;
6750 x = TREE_REAL_CST (arg);
6751 if (real_sqrt (&r, TYPE_MODE (type), &x)
6752 || (!flag_trapping_math && !flag_errno_math))
6753 return build_real (type, r);
6756 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
6757 fcode = builtin_mathfn_code (arg);
6758 if (flag_unsafe_math_optimizations
6759 && (fcode == BUILT_IN_EXP
6760 || fcode == BUILT_IN_EXPF
6761 || fcode == BUILT_IN_EXPL))
6763 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6764 arg = fold (build (MULT_EXPR, type,
6765 TREE_VALUE (TREE_OPERAND (arg, 1)),
6766 build_real (type, dconsthalf)));
6767 arglist = build_tree_list (NULL_TREE, arg);
6768 return build_function_call_expr (expfn, arglist);
6771 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6772 if (flag_unsafe_math_optimizations
6773 && (fcode == BUILT_IN_POW
6774 || fcode == BUILT_IN_POWF
6775 || fcode == BUILT_IN_POWL))
6777 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6778 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6779 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6780 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6781 build_real (type, dconsthalf)));
6782 arglist = tree_cons (NULL_TREE, arg0,
6783 build_tree_list (NULL_TREE, narg1));
6784 return build_function_call_expr (powfn, arglist);
6787 break;
6789 case BUILT_IN_SIN:
6790 case BUILT_IN_SINF:
6791 case BUILT_IN_SINL:
6792 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6794 tree arg = TREE_VALUE (arglist);
6796 /* Optimize sin(0.0) = 0.0. */
6797 if (real_zerop (arg))
6798 return arg;
6800 break;
6802 case BUILT_IN_COS:
6803 case BUILT_IN_COSF:
6804 case BUILT_IN_COSL:
6805 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6807 tree arg = TREE_VALUE (arglist);
6809 /* Optimize cos(0.0) = 1.0. */
6810 if (real_zerop (arg))
6811 return build_real (type, dconst1);
6813 /* Optimize cos(-x) into cos(x). */
6814 if (TREE_CODE (arg) == NEGATE_EXPR)
6816 tree arglist = build_tree_list (NULL_TREE,
6817 TREE_OPERAND (arg, 0));
6818 return build_function_call_expr (fndecl, arglist);
6821 break;
6823 case BUILT_IN_EXP:
6824 case BUILT_IN_EXPF:
6825 case BUILT_IN_EXPL:
6826 return fold_builtin_exponent (exp, &dconste);
6827 case BUILT_IN_EXP2:
6828 case BUILT_IN_EXP2F:
6829 case BUILT_IN_EXP2L:
6830 return fold_builtin_exponent (exp, &dconst2);
6831 case BUILT_IN_EXP10:
6832 case BUILT_IN_EXP10F:
6833 case BUILT_IN_EXP10L:
6834 case BUILT_IN_POW10:
6835 case BUILT_IN_POW10F:
6836 case BUILT_IN_POW10L:
6837 return fold_builtin_exponent (exp, &dconst10);
6838 case BUILT_IN_LOG:
6839 case BUILT_IN_LOGF:
6840 case BUILT_IN_LOGL:
6841 return fold_builtin_logarithm (exp, &dconste);
6842 break;
6843 case BUILT_IN_LOG2:
6844 case BUILT_IN_LOG2F:
6845 case BUILT_IN_LOG2L:
6846 return fold_builtin_logarithm (exp, &dconst2);
6847 break;
6848 case BUILT_IN_LOG10:
6849 case BUILT_IN_LOG10F:
6850 case BUILT_IN_LOG10L:
6851 return fold_builtin_logarithm (exp, &dconst10);
6852 break;
6854 case BUILT_IN_TAN:
6855 case BUILT_IN_TANF:
6856 case BUILT_IN_TANL:
6857 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6859 enum built_in_function fcode;
6860 tree arg = TREE_VALUE (arglist);
6862 /* Optimize tan(0.0) = 0.0. */
6863 if (real_zerop (arg))
6864 return arg;
6866 /* Optimize tan(atan(x)) = x. */
6867 fcode = builtin_mathfn_code (arg);
6868 if (flag_unsafe_math_optimizations
6869 && (fcode == BUILT_IN_ATAN
6870 || fcode == BUILT_IN_ATANF
6871 || fcode == BUILT_IN_ATANL))
6872 return TREE_VALUE (TREE_OPERAND (arg, 1));
6874 break;
6876 case BUILT_IN_ATAN:
6877 case BUILT_IN_ATANF:
6878 case BUILT_IN_ATANL:
6879 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6881 tree arg = TREE_VALUE (arglist);
6883 /* Optimize atan(0.0) = 0.0. */
6884 if (real_zerop (arg))
6885 return arg;
6887 /* Optimize atan(1.0) = pi/4. */
6888 if (real_onep (arg))
6890 REAL_VALUE_TYPE cst;
6892 real_convert (&cst, TYPE_MODE (type), &dconstpi);
6893 cst.exp -= 2;
6894 return build_real (type, cst);
6897 break;
6899 case BUILT_IN_POW:
6900 case BUILT_IN_POWF:
6901 case BUILT_IN_POWL:
6902 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6904 enum built_in_function fcode;
6905 tree arg0 = TREE_VALUE (arglist);
6906 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6908 /* Optimize pow(1.0,y) = 1.0. */
6909 if (real_onep (arg0))
6910 return omit_one_operand (type, build_real (type, dconst1), arg1);
6912 if (TREE_CODE (arg1) == REAL_CST
6913 && ! TREE_CONSTANT_OVERFLOW (arg1))
6915 REAL_VALUE_TYPE c;
6916 c = TREE_REAL_CST (arg1);
6918 /* Optimize pow(x,0.0) = 1.0. */
6919 if (REAL_VALUES_EQUAL (c, dconst0))
6920 return omit_one_operand (type, build_real (type, dconst1),
6921 arg0);
6923 /* Optimize pow(x,1.0) = x. */
6924 if (REAL_VALUES_EQUAL (c, dconst1))
6925 return arg0;
6927 /* Optimize pow(x,-1.0) = 1.0/x. */
6928 if (REAL_VALUES_EQUAL (c, dconstm1))
6929 return fold (build (RDIV_EXPR, type,
6930 build_real (type, dconst1),
6931 arg0));
6933 /* Optimize pow(x,0.5) = sqrt(x). */
6934 if (flag_unsafe_math_optimizations
6935 && REAL_VALUES_EQUAL (c, dconsthalf))
6937 tree sqrtfn;
6939 fcode = DECL_FUNCTION_CODE (fndecl);
6940 if (fcode == BUILT_IN_POW)
6941 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6942 else if (fcode == BUILT_IN_POWF)
6943 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6944 else if (fcode == BUILT_IN_POWL)
6945 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6946 else
6947 sqrtfn = NULL_TREE;
6949 if (sqrtfn != NULL_TREE)
6951 tree arglist = build_tree_list (NULL_TREE, arg0);
6952 return build_function_call_expr (sqrtfn, arglist);
6956 /* Attempt to evaluate pow at compile-time. */
6957 if (TREE_CODE (arg0) == REAL_CST
6958 && ! TREE_CONSTANT_OVERFLOW (arg0))
6960 REAL_VALUE_TYPE cint;
6961 HOST_WIDE_INT n;
6963 n = real_to_integer (&c);
6964 real_from_integer (&cint, VOIDmode, n,
6965 n < 0 ? -1 : 0, 0);
6966 if (real_identical (&c, &cint))
6968 REAL_VALUE_TYPE x;
6969 bool inexact;
6971 x = TREE_REAL_CST (arg0);
6972 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6973 if (flag_unsafe_math_optimizations || !inexact)
6974 return build_real (type, x);
6979 /* Optimize pow(exp(x),y) = exp(x*y). */
6980 fcode = builtin_mathfn_code (arg0);
6981 if (flag_unsafe_math_optimizations
6982 && (fcode == BUILT_IN_EXP
6983 || fcode == BUILT_IN_EXPF
6984 || fcode == BUILT_IN_EXPL))
6986 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6987 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6988 arg = fold (build (MULT_EXPR, type, arg, arg1));
6989 arglist = build_tree_list (NULL_TREE, arg);
6990 return build_function_call_expr (expfn, arglist);
6993 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
6994 if (flag_unsafe_math_optimizations
6995 && (fcode == BUILT_IN_SQRT
6996 || fcode == BUILT_IN_SQRTF
6997 || fcode == BUILT_IN_SQRTL))
6999 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7000 tree narg1 = fold (build (MULT_EXPR, type, arg1,
7001 build_real (type, dconsthalf)));
7003 arglist = tree_cons (NULL_TREE, narg0,
7004 build_tree_list (NULL_TREE, narg1));
7005 return build_function_call_expr (fndecl, arglist);
7008 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7009 if (flag_unsafe_math_optimizations
7010 && (fcode == BUILT_IN_POW
7011 || fcode == BUILT_IN_POWF
7012 || fcode == BUILT_IN_POWL))
7014 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7015 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7016 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
7017 arglist = tree_cons (NULL_TREE, arg00,
7018 build_tree_list (NULL_TREE, narg1));
7019 return build_function_call_expr (fndecl, arglist);
7022 break;
7024 case BUILT_IN_INF:
7025 case BUILT_IN_INFF:
7026 case BUILT_IN_INFL:
7027 return fold_builtin_inf (type, true);
7029 case BUILT_IN_HUGE_VAL:
7030 case BUILT_IN_HUGE_VALF:
7031 case BUILT_IN_HUGE_VALL:
7032 return fold_builtin_inf (type, false);
7034 case BUILT_IN_NAN:
7035 case BUILT_IN_NANF:
7036 case BUILT_IN_NANL:
7037 return fold_builtin_nan (arglist, type, true);
7039 case BUILT_IN_NANS:
7040 case BUILT_IN_NANSF:
7041 case BUILT_IN_NANSL:
7042 return fold_builtin_nan (arglist, type, false);
7044 case BUILT_IN_FLOOR:
7045 case BUILT_IN_FLOORF:
7046 case BUILT_IN_FLOORL:
7047 return fold_builtin_floor (exp);
7049 case BUILT_IN_CEIL:
7050 case BUILT_IN_CEILF:
7051 case BUILT_IN_CEILL:
7052 return fold_builtin_ceil (exp);
7054 case BUILT_IN_TRUNC:
7055 case BUILT_IN_TRUNCF:
7056 case BUILT_IN_TRUNCL:
7057 return fold_builtin_trunc (exp);
7059 case BUILT_IN_ROUND:
7060 case BUILT_IN_ROUNDF:
7061 case BUILT_IN_ROUNDL:
7062 return fold_builtin_round (exp);
7064 case BUILT_IN_NEARBYINT:
7065 case BUILT_IN_NEARBYINTF:
7066 case BUILT_IN_NEARBYINTL:
7067 return fold_trunc_transparent_mathfn (exp);
7069 case BUILT_IN_FFS:
7070 case BUILT_IN_FFSL:
7071 case BUILT_IN_FFSLL:
7072 case BUILT_IN_CLZ:
7073 case BUILT_IN_CLZL:
7074 case BUILT_IN_CLZLL:
7075 case BUILT_IN_CTZ:
7076 case BUILT_IN_CTZL:
7077 case BUILT_IN_CTZLL:
7078 case BUILT_IN_POPCOUNT:
7079 case BUILT_IN_POPCOUNTL:
7080 case BUILT_IN_POPCOUNTLL:
7081 case BUILT_IN_PARITY:
7082 case BUILT_IN_PARITYL:
7083 case BUILT_IN_PARITYLL:
7084 return fold_builtin_bitop (exp);
7086 case BUILT_IN_MEMCPY:
7087 return fold_builtin_memcpy (exp);
7089 case BUILT_IN_MEMPCPY:
7090 return fold_builtin_mempcpy (exp);
7092 case BUILT_IN_MEMMOVE:
7093 return fold_builtin_memmove (exp);
7095 case BUILT_IN_STRCPY:
7096 return fold_builtin_strcpy (exp);
7098 case BUILT_IN_STRNCPY:
7099 return fold_builtin_strncpy (exp);
7101 case BUILT_IN_MEMCMP:
7102 return fold_builtin_memcmp (exp);
7104 case BUILT_IN_STRCMP:
7105 return fold_builtin_strcmp (exp);
7107 case BUILT_IN_STRNCMP:
7108 return fold_builtin_strncmp (exp);
7110 case BUILT_IN_SIGNBIT:
7111 case BUILT_IN_SIGNBITF:
7112 case BUILT_IN_SIGNBITL:
7113 return fold_builtin_signbit (exp);
7115 default:
7116 break;
7119 return 0;
7122 /* Conveniently construct a function call expression. */
7124 tree
7125 build_function_call_expr (tree fn, tree arglist)
7127 tree call_expr;
7129 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7130 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7131 call_expr, arglist);
7132 return fold (call_expr);
7135 /* This function validates the types of a function call argument list
7136 represented as a tree chain of parameters against a specified list
7137 of tree_codes. If the last specifier is a 0, that represents an
7138 ellipses, otherwise the last specifier must be a VOID_TYPE. */
7140 static int
7141 validate_arglist (tree arglist, ...)
7143 enum tree_code code;
7144 int res = 0;
7145 va_list ap;
7147 va_start (ap, arglist);
7151 code = va_arg (ap, enum tree_code);
7152 switch (code)
7154 case 0:
7155 /* This signifies an ellipses, any further arguments are all ok. */
7156 res = 1;
7157 goto end;
7158 case VOID_TYPE:
7159 /* This signifies an endlink, if no arguments remain, return
7160 true, otherwise return false. */
7161 res = arglist == 0;
7162 goto end;
7163 default:
7164 /* If no parameters remain or the parameter's code does not
7165 match the specified code, return false. Otherwise continue
7166 checking any remaining arguments. */
7167 if (arglist == 0
7168 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7169 goto end;
7170 break;
7172 arglist = TREE_CHAIN (arglist);
7174 while (1);
7176 /* We need gotos here since we can only have one VA_CLOSE in a
7177 function. */
7178 end: ;
7179 va_end (ap);
7181 return res;
7184 /* Default target-specific builtin expander that does nothing. */
7187 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7188 rtx target ATTRIBUTE_UNUSED,
7189 rtx subtarget ATTRIBUTE_UNUSED,
7190 enum machine_mode mode ATTRIBUTE_UNUSED,
7191 int ignore ATTRIBUTE_UNUSED)
7193 return NULL_RTX;
7196 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
7198 void
7199 purge_builtin_constant_p (void)
7201 rtx insn, set, arg, new, note;
7203 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7204 if (INSN_P (insn)
7205 && (set = single_set (insn)) != NULL_RTX
7206 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
7207 || (GET_CODE (arg) == SUBREG
7208 && (GET_CODE (arg = SUBREG_REG (arg))
7209 == CONSTANT_P_RTX))))
7211 arg = XEXP (arg, 0);
7212 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
7213 validate_change (insn, &SET_SRC (set), new, 0);
7215 /* Remove the REG_EQUAL note from the insn. */
7216 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
7217 remove_note (insn, note);
7221 /* Returns true is EXP represents data that would potentially reside
7222 in a readonly section. */
7224 static bool
7225 readonly_data_expr (tree exp)
7227 STRIP_NOPS (exp);
7229 if (TREE_CODE (exp) == ADDR_EXPR)
7230 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7231 else
7232 return false;