configure.ac: GCC_NO_EXECUTABLES was supposed to be commented in the patch from 3...
[official-gcc.git] / gcc / builtins.c
blob5b975f0f2568bac12801b3d0f493344a5d284ef5
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
51 /* Register mappings for target machines without register windows. */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
54 #endif
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
57 #endif
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
61 #endif
63 /* Define the names of the builtin function types and codes. */
64 const char *const built_in_class_names[4]
65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
68 const char *const built_in_names[(int) END_BUILTINS] =
70 #include "builtins.def"
72 #undef DEF_BUILTIN
74 /* Setup an array of _DECL trees, make sure each element is
75 initialized to NULL_TREE. */
76 tree built_in_decls[(int) END_BUILTINS];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78 It may be NULL_TREE when this is invalid (for instance runtime is not
79 required to implement the function call in all cases. */
80 tree implicit_built_in_decls[(int) END_BUILTINS];
82 /* Trigonometric and mathematical constants used in builtin folding. */
83 static bool builtin_dconsts_init = 0;
84 static REAL_VALUE_TYPE dconstpi;
85 static REAL_VALUE_TYPE dconste;
87 static int get_pointer_alignment (tree, unsigned int);
88 static tree c_strlen (tree, int);
89 static const char *c_getstr (tree);
90 static rtx c_readstr (const char *, enum machine_mode);
91 static int target_char_cast (tree, char *);
92 static rtx get_memory_rtx (tree);
93 static tree build_string_literal (int, const char *);
94 static int apply_args_size (void);
95 static int apply_result_size (void);
96 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
97 static rtx result_vector (int, rtx);
98 #endif
99 static rtx expand_builtin_setjmp (tree, rtx);
100 static void expand_builtin_prefetch (tree);
101 static rtx expand_builtin_apply_args (void);
102 static rtx expand_builtin_apply_args_1 (void);
103 static rtx expand_builtin_apply (rtx, rtx, rtx);
104 static void expand_builtin_return (rtx);
105 static enum type_class type_to_class (tree);
106 static rtx expand_builtin_classify_type (tree);
107 static void expand_errno_check (tree, rtx);
108 static rtx expand_builtin_mathfn (tree, rtx, rtx);
109 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
110 static rtx expand_builtin_constant_p (tree, enum machine_mode);
111 static rtx expand_builtin_args_info (tree);
112 static rtx expand_builtin_next_arg (tree);
113 static rtx expand_builtin_va_start (tree);
114 static rtx expand_builtin_va_end (tree);
115 static rtx expand_builtin_va_copy (tree);
116 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
119 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
121 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
123 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
126 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_bcopy (tree);
128 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
130 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
131 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
132 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
133 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
134 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
135 static rtx expand_builtin_bzero (tree);
136 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
137 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
138 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
139 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
140 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
141 static rtx expand_builtin_alloca (tree, rtx);
142 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
143 static rtx expand_builtin_frame_address (tree, tree);
144 static rtx expand_builtin_fputs (tree, rtx, bool);
145 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
146 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
147 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
148 static tree stabilize_va_list (tree, int);
149 static rtx expand_builtin_expect (tree, rtx);
150 static tree fold_builtin_constant_p (tree);
151 static tree fold_builtin_classify_type (tree);
152 static tree fold_builtin_inf (tree, int);
153 static tree fold_builtin_nan (tree, tree, int);
154 static int validate_arglist (tree, ...);
155 static bool integer_valued_real_p (tree);
156 static tree fold_trunc_transparent_mathfn (tree);
157 static bool readonly_data_expr (tree);
158 static rtx expand_builtin_fabs (tree, rtx, rtx);
159 static rtx expand_builtin_cabs (tree, rtx);
160 static void init_builtin_dconsts (void);
161 static tree fold_builtin_cabs (tree, tree, tree);
162 static tree fold_builtin_trunc (tree);
163 static tree fold_builtin_floor (tree);
164 static tree fold_builtin_ceil (tree);
166 /* Initialize mathematical constants for constant folding builtins.
167 These constants need to be given to at least 160 bits precision. */
169 static void
170 init_builtin_dconsts (void)
172 real_from_string (&dconstpi,
173 "3.1415926535897932384626433832795028841971693993751058209749445923078");
174 real_from_string (&dconste,
175 "2.7182818284590452353602874713526624977572470936999595749669676277241");
177 builtin_dconsts_init = true;
180 /* Return the alignment in bits of EXP, a pointer valued expression.
181 But don't return more than MAX_ALIGN no matter what.
182 The alignment returned is, by default, the alignment of the thing that
183 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
185 Otherwise, look at the expression to see if we can do better, i.e., if the
186 expression is actually pointing at an object whose alignment is tighter. */
188 static int
189 get_pointer_alignment (tree exp, unsigned int max_align)
191 unsigned int align, inner;
193 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
194 return 0;
196 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
197 align = MIN (align, max_align);
199 while (1)
201 switch (TREE_CODE (exp))
203 case NOP_EXPR:
204 case CONVERT_EXPR:
205 case NON_LVALUE_EXPR:
206 exp = TREE_OPERAND (exp, 0);
207 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
208 return align;
210 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
211 align = MIN (inner, max_align);
212 break;
214 case PLUS_EXPR:
215 /* If sum of pointer + int, restrict our maximum alignment to that
216 imposed by the integer. If not, we can't do any better than
217 ALIGN. */
218 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
219 return align;
221 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
222 & (max_align / BITS_PER_UNIT - 1))
223 != 0)
224 max_align >>= 1;
226 exp = TREE_OPERAND (exp, 0);
227 break;
229 case ADDR_EXPR:
230 /* See what we are pointing at and look at its alignment. */
231 exp = TREE_OPERAND (exp, 0);
232 if (TREE_CODE (exp) == FUNCTION_DECL)
233 align = FUNCTION_BOUNDARY;
234 else if (DECL_P (exp))
235 align = DECL_ALIGN (exp);
236 #ifdef CONSTANT_ALIGNMENT
237 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
238 align = CONSTANT_ALIGNMENT (exp, align);
239 #endif
240 return MIN (align, max_align);
242 default:
243 return align;
248 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
249 way, because it could contain a zero byte in the middle.
250 TREE_STRING_LENGTH is the size of the character array, not the string.
252 ONLY_VALUE should be nonzero if the result is not going to be emitted
253 into the instruction stream and zero if it is going to be expanded.
254 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
255 is returned, otherwise NULL, since
256 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
257 evaluate the side-effects.
259 The value returned is of type `ssizetype'.
261 Unfortunately, string_constant can't access the values of const char
262 arrays with initializers, so neither can we do so here. */
264 static tree
265 c_strlen (tree src, int only_value)
267 tree offset_node;
268 HOST_WIDE_INT offset;
269 int max;
270 const char *ptr;
272 STRIP_NOPS (src);
273 if (TREE_CODE (src) == COND_EXPR
274 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
276 tree len1, len2;
278 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
279 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
280 if (tree_int_cst_equal (len1, len2))
281 return len1;
284 if (TREE_CODE (src) == COMPOUND_EXPR
285 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
286 return c_strlen (TREE_OPERAND (src, 1), only_value);
288 src = string_constant (src, &offset_node);
289 if (src == 0)
290 return 0;
292 max = TREE_STRING_LENGTH (src) - 1;
293 ptr = TREE_STRING_POINTER (src);
295 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
297 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
298 compute the offset to the following null if we don't know where to
299 start searching for it. */
300 int i;
302 for (i = 0; i < max; i++)
303 if (ptr[i] == 0)
304 return 0;
306 /* We don't know the starting offset, but we do know that the string
307 has no internal zero bytes. We can assume that the offset falls
308 within the bounds of the string; otherwise, the programmer deserves
309 what he gets. Subtract the offset from the length of the string,
310 and return that. This would perhaps not be valid if we were dealing
311 with named arrays in addition to literal string constants. */
313 return size_diffop (size_int (max), offset_node);
316 /* We have a known offset into the string. Start searching there for
317 a null character if we can represent it as a single HOST_WIDE_INT. */
318 if (offset_node == 0)
319 offset = 0;
320 else if (! host_integerp (offset_node, 0))
321 offset = -1;
322 else
323 offset = tree_low_cst (offset_node, 0);
325 /* If the offset is known to be out of bounds, warn, and call strlen at
326 runtime. */
327 if (offset < 0 || offset > max)
329 warning ("offset outside bounds of constant string");
330 return 0;
333 /* Use strlen to search for the first zero byte. Since any strings
334 constructed with build_string will have nulls appended, we win even
335 if we get handed something like (char[4])"abcd".
337 Since OFFSET is our starting index into the string, no further
338 calculation is needed. */
339 return ssize_int (strlen (ptr + offset));
342 /* Return a char pointer for a C string if it is a string constant
343 or sum of string constant and integer constant. */
345 static const char *
346 c_getstr (tree src)
348 tree offset_node;
350 src = string_constant (src, &offset_node);
351 if (src == 0)
352 return 0;
354 if (offset_node == 0)
355 return TREE_STRING_POINTER (src);
356 else if (!host_integerp (offset_node, 1)
357 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
358 return 0;
360 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
363 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
364 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
366 static rtx
367 c_readstr (const char *str, enum machine_mode mode)
369 HOST_WIDE_INT c[2];
370 HOST_WIDE_INT ch;
371 unsigned int i, j;
373 if (GET_MODE_CLASS (mode) != MODE_INT)
374 abort ();
375 c[0] = 0;
376 c[1] = 0;
377 ch = 1;
378 for (i = 0; i < GET_MODE_SIZE (mode); i++)
380 j = i;
381 if (WORDS_BIG_ENDIAN)
382 j = GET_MODE_SIZE (mode) - i - 1;
383 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
384 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
385 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
386 j *= BITS_PER_UNIT;
387 if (j > 2 * HOST_BITS_PER_WIDE_INT)
388 abort ();
389 if (ch)
390 ch = (unsigned char) str[i];
391 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
393 return immed_double_const (c[0], c[1], mode);
396 /* Cast a target constant CST to target CHAR and if that value fits into
397 host char type, return zero and put that value into variable pointed by
398 P. */
400 static int
401 target_char_cast (tree cst, char *p)
403 unsigned HOST_WIDE_INT val, hostval;
405 if (!host_integerp (cst, 1)
406 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
407 return 1;
409 val = tree_low_cst (cst, 1);
410 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
411 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
413 hostval = val;
414 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
415 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
417 if (val != hostval)
418 return 1;
420 *p = hostval;
421 return 0;
424 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
425 times to get the address of either a higher stack frame, or a return
426 address located within it (depending on FNDECL_CODE). */
429 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
430 rtx tem)
432 int i;
434 /* Some machines need special handling before we can access
435 arbitrary frames. For example, on the sparc, we must first flush
436 all register windows to the stack. */
437 #ifdef SETUP_FRAME_ADDRESSES
438 if (count > 0)
439 SETUP_FRAME_ADDRESSES ();
440 #endif
442 /* On the sparc, the return address is not in the frame, it is in a
443 register. There is no way to access it off of the current frame
444 pointer, but it can be accessed off the previous frame pointer by
445 reading the value from the register window save area. */
446 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
447 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
448 count--;
449 #endif
451 /* Scan back COUNT frames to the specified frame. */
452 for (i = 0; i < count; i++)
454 /* Assume the dynamic chain pointer is in the word that the
455 frame address points to, unless otherwise specified. */
456 #ifdef DYNAMIC_CHAIN_ADDRESS
457 tem = DYNAMIC_CHAIN_ADDRESS (tem);
458 #endif
459 tem = memory_address (Pmode, tem);
460 tem = gen_rtx_MEM (Pmode, tem);
461 set_mem_alias_set (tem, get_frame_alias_set ());
462 tem = copy_to_reg (tem);
465 /* For __builtin_frame_address, return what we've got. */
466 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
467 return tem;
469 /* For __builtin_return_address, Get the return address from that
470 frame. */
471 #ifdef RETURN_ADDR_RTX
472 tem = RETURN_ADDR_RTX (count, tem);
473 #else
474 tem = memory_address (Pmode,
475 plus_constant (tem, GET_MODE_SIZE (Pmode)));
476 tem = gen_rtx_MEM (Pmode, tem);
477 set_mem_alias_set (tem, get_frame_alias_set ());
478 #endif
479 return tem;
482 /* Alias set used for setjmp buffer. */
483 static HOST_WIDE_INT setjmp_alias_set = -1;
485 /* Construct the leading half of a __builtin_setjmp call. Control will
486 return to RECEIVER_LABEL. This is used directly by sjlj exception
487 handling code. */
489 void
490 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
492 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
493 rtx stack_save;
494 rtx mem;
496 if (setjmp_alias_set == -1)
497 setjmp_alias_set = new_alias_set ();
499 #ifdef POINTERS_EXTEND_UNSIGNED
500 if (GET_MODE (buf_addr) != Pmode)
501 buf_addr = convert_memory_address (Pmode, buf_addr);
502 #endif
504 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
506 emit_queue ();
508 /* We store the frame pointer and the address of receiver_label in
509 the buffer and use the rest of it for the stack save area, which
510 is machine-dependent. */
512 #ifndef BUILTIN_SETJMP_FRAME_VALUE
513 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
514 #endif
516 mem = gen_rtx_MEM (Pmode, buf_addr);
517 set_mem_alias_set (mem, setjmp_alias_set);
518 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
520 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
521 set_mem_alias_set (mem, setjmp_alias_set);
523 emit_move_insn (validize_mem (mem),
524 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
526 stack_save = gen_rtx_MEM (sa_mode,
527 plus_constant (buf_addr,
528 2 * GET_MODE_SIZE (Pmode)));
529 set_mem_alias_set (stack_save, setjmp_alias_set);
530 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
532 /* If there is further processing to do, do it. */
533 #ifdef HAVE_builtin_setjmp_setup
534 if (HAVE_builtin_setjmp_setup)
535 emit_insn (gen_builtin_setjmp_setup (buf_addr));
536 #endif
538 /* Tell optimize_save_area_alloca that extra work is going to
539 need to go on during alloca. */
540 current_function_calls_setjmp = 1;
542 /* Set this so all the registers get saved in our frame; we need to be
543 able to copy the saved values for any registers from frames we unwind. */
544 current_function_has_nonlocal_label = 1;
547 /* Construct the trailing part of a __builtin_setjmp call.
548 This is used directly by sjlj exception handling code. */
550 void
551 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
553 /* Clobber the FP when we get here, so we have to make sure it's
554 marked as used by this function. */
555 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
557 /* Mark the static chain as clobbered here so life information
558 doesn't get messed up for it. */
559 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
561 /* Now put in the code to restore the frame pointer, and argument
562 pointer, if needed. The code below is from expand_end_bindings
563 in stmt.c; see detailed documentation there. */
564 #ifdef HAVE_nonlocal_goto
565 if (! HAVE_nonlocal_goto)
566 #endif
567 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
569 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
570 if (fixed_regs[ARG_POINTER_REGNUM])
572 #ifdef ELIMINABLE_REGS
573 size_t i;
574 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
576 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
577 if (elim_regs[i].from == ARG_POINTER_REGNUM
578 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
579 break;
581 if (i == ARRAY_SIZE (elim_regs))
582 #endif
584 /* Now restore our arg pointer from the address at which it
585 was saved in our stack frame. */
586 emit_move_insn (virtual_incoming_args_rtx,
587 copy_to_reg (get_arg_pointer_save_area (cfun)));
590 #endif
592 #ifdef HAVE_builtin_setjmp_receiver
593 if (HAVE_builtin_setjmp_receiver)
594 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
595 else
596 #endif
597 #ifdef HAVE_nonlocal_goto_receiver
598 if (HAVE_nonlocal_goto_receiver)
599 emit_insn (gen_nonlocal_goto_receiver ());
600 else
601 #endif
602 { /* Nothing */ }
604 /* @@@ This is a kludge. Not all machine descriptions define a blockage
605 insn, but we must not allow the code we just generated to be reordered
606 by scheduling. Specifically, the update of the frame pointer must
607 happen immediately, not later. So emit an ASM_INPUT to act as blockage
608 insn. */
609 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
612 /* __builtin_setjmp is passed a pointer to an array of five words (not
613 all will be used on all machines). It operates similarly to the C
614 library function of the same name, but is more efficient. Much of
615 the code below (and for longjmp) is copied from the handling of
616 non-local gotos.
618 NOTE: This is intended for use by GNAT and the exception handling
619 scheme in the compiler and will only work in the method used by
620 them. */
622 static rtx
623 expand_builtin_setjmp (tree arglist, rtx target)
625 rtx buf_addr, next_lab, cont_lab;
627 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
628 return NULL_RTX;
630 if (target == 0 || GET_CODE (target) != REG
631 || REGNO (target) < FIRST_PSEUDO_REGISTER)
632 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
634 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
636 next_lab = gen_label_rtx ();
637 cont_lab = gen_label_rtx ();
639 expand_builtin_setjmp_setup (buf_addr, next_lab);
641 /* Set TARGET to zero and branch to the continue label. */
642 emit_move_insn (target, const0_rtx);
643 emit_jump_insn (gen_jump (cont_lab));
644 emit_barrier ();
645 emit_label (next_lab);
647 expand_builtin_setjmp_receiver (next_lab);
649 /* Set TARGET to one. */
650 emit_move_insn (target, const1_rtx);
651 emit_label (cont_lab);
653 /* Tell flow about the strange goings on. Putting `next_lab' on
654 `nonlocal_goto_handler_labels' to indicates that function
655 calls may traverse the arc back to this label. */
657 current_function_has_nonlocal_label = 1;
658 nonlocal_goto_handler_labels
659 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
661 return target;
664 /* __builtin_longjmp is passed a pointer to an array of five words (not
665 all will be used on all machines). It operates similarly to the C
666 library function of the same name, but is more efficient. Much of
667 the code below is copied from the handling of non-local gotos.
669 NOTE: This is intended for use by GNAT and the exception handling
670 scheme in the compiler and will only work in the method used by
671 them. */
673 void
674 expand_builtin_longjmp (rtx buf_addr, rtx value)
676 rtx fp, lab, stack, insn, last;
677 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
679 if (setjmp_alias_set == -1)
680 setjmp_alias_set = new_alias_set ();
682 #ifdef POINTERS_EXTEND_UNSIGNED
683 if (GET_MODE (buf_addr) != Pmode)
684 buf_addr = convert_memory_address (Pmode, buf_addr);
685 #endif
687 buf_addr = force_reg (Pmode, buf_addr);
689 /* We used to store value in static_chain_rtx, but that fails if pointers
690 are smaller than integers. We instead require that the user must pass
691 a second argument of 1, because that is what builtin_setjmp will
692 return. This also makes EH slightly more efficient, since we are no
693 longer copying around a value that we don't care about. */
694 if (value != const1_rtx)
695 abort ();
697 current_function_calls_longjmp = 1;
699 last = get_last_insn ();
700 #ifdef HAVE_builtin_longjmp
701 if (HAVE_builtin_longjmp)
702 emit_insn (gen_builtin_longjmp (buf_addr));
703 else
704 #endif
706 fp = gen_rtx_MEM (Pmode, buf_addr);
707 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
708 GET_MODE_SIZE (Pmode)));
710 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
711 2 * GET_MODE_SIZE (Pmode)));
712 set_mem_alias_set (fp, setjmp_alias_set);
713 set_mem_alias_set (lab, setjmp_alias_set);
714 set_mem_alias_set (stack, setjmp_alias_set);
716 /* Pick up FP, label, and SP from the block and jump. This code is
717 from expand_goto in stmt.c; see there for detailed comments. */
718 #if HAVE_nonlocal_goto
719 if (HAVE_nonlocal_goto)
720 /* We have to pass a value to the nonlocal_goto pattern that will
721 get copied into the static_chain pointer, but it does not matter
722 what that value is, because builtin_setjmp does not use it. */
723 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
724 else
725 #endif
727 lab = copy_to_reg (lab);
729 emit_move_insn (hard_frame_pointer_rtx, fp);
730 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
732 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
733 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
734 emit_indirect_jump (lab);
738 /* Search backwards and mark the jump insn as a non-local goto.
739 Note that this precludes the use of __builtin_longjmp to a
740 __builtin_setjmp target in the same function. However, we've
741 already cautioned the user that these functions are for
742 internal exception handling use only. */
743 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
745 if (insn == last)
746 abort ();
747 if (GET_CODE (insn) == JUMP_INSN)
749 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
750 REG_NOTES (insn));
751 break;
753 else if (GET_CODE (insn) == CALL_INSN)
754 break;
758 /* Expand a call to __builtin_prefetch. For a target that does not support
759 data prefetch, evaluate the memory address argument in case it has side
760 effects. */
762 static void
763 expand_builtin_prefetch (tree arglist)
765 tree arg0, arg1, arg2;
766 rtx op0, op1, op2;
768 if (!validate_arglist (arglist, POINTER_TYPE, 0))
769 return;
771 arg0 = TREE_VALUE (arglist);
772 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
773 zero (read) and argument 2 (locality) defaults to 3 (high degree of
774 locality). */
775 if (TREE_CHAIN (arglist))
777 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
778 if (TREE_CHAIN (TREE_CHAIN (arglist)))
779 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
780 else
781 arg2 = build_int_2 (3, 0);
783 else
785 arg1 = integer_zero_node;
786 arg2 = build_int_2 (3, 0);
789 /* Argument 0 is an address. */
790 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
792 /* Argument 1 (read/write flag) must be a compile-time constant int. */
793 if (TREE_CODE (arg1) != INTEGER_CST)
795 error ("second arg to `__builtin_prefetch' must be a constant");
796 arg1 = integer_zero_node;
798 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
799 /* Argument 1 must be either zero or one. */
800 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
802 warning ("invalid second arg to __builtin_prefetch; using zero");
803 op1 = const0_rtx;
806 /* Argument 2 (locality) must be a compile-time constant int. */
807 if (TREE_CODE (arg2) != INTEGER_CST)
809 error ("third arg to `__builtin_prefetch' must be a constant");
810 arg2 = integer_zero_node;
812 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
813 /* Argument 2 must be 0, 1, 2, or 3. */
814 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
816 warning ("invalid third arg to __builtin_prefetch; using zero");
817 op2 = const0_rtx;
820 #ifdef HAVE_prefetch
821 if (HAVE_prefetch)
823 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
824 (op0,
825 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
826 || (GET_MODE (op0) != Pmode))
828 #ifdef POINTERS_EXTEND_UNSIGNED
829 if (GET_MODE (op0) != Pmode)
830 op0 = convert_memory_address (Pmode, op0);
831 #endif
832 op0 = force_reg (Pmode, op0);
834 emit_insn (gen_prefetch (op0, op1, op2));
836 else
837 #endif
838 op0 = protect_from_queue (op0, 0);
839 /* Don't do anything with direct references to volatile memory, but
840 generate code to handle other side effects. */
841 if (GET_CODE (op0) != MEM && side_effects_p (op0))
842 emit_insn (op0);
845 /* Get a MEM rtx for expression EXP which is the address of an operand
846 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
848 static rtx
849 get_memory_rtx (tree exp)
851 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
852 rtx mem;
854 #ifdef POINTERS_EXTEND_UNSIGNED
855 if (GET_MODE (addr) != Pmode)
856 addr = convert_memory_address (Pmode, addr);
857 #endif
859 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
861 /* Get an expression we can use to find the attributes to assign to MEM.
862 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
863 we can. First remove any nops. */
864 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
865 || TREE_CODE (exp) == NON_LVALUE_EXPR)
866 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
867 exp = TREE_OPERAND (exp, 0);
869 if (TREE_CODE (exp) == ADDR_EXPR)
871 exp = TREE_OPERAND (exp, 0);
872 set_mem_attributes (mem, exp, 0);
874 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
876 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
877 /* memcpy, memset and other builtin stringops can alias with anything. */
878 set_mem_alias_set (mem, 0);
881 return mem;
884 /* Built-in functions to perform an untyped call and return. */
886 /* For each register that may be used for calling a function, this
887 gives a mode used to copy the register's value. VOIDmode indicates
888 the register is not used for calling a function. If the machine
889 has register windows, this gives only the outbound registers.
890 INCOMING_REGNO gives the corresponding inbound register. */
891 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
893 /* For each register that may be used for returning values, this gives
894 a mode used to copy the register's value. VOIDmode indicates the
895 register is not used for returning values. If the machine has
896 register windows, this gives only the outbound registers.
897 INCOMING_REGNO gives the corresponding inbound register. */
898 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
900 /* For each register that may be used for calling a function, this
901 gives the offset of that register into the block returned by
902 __builtin_apply_args. 0 indicates that the register is not
903 used for calling a function. */
904 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
906 /* Return the offset of register REGNO into the block returned by
907 __builtin_apply_args. This is not declared static, since it is
908 needed in objc-act.c. */
911 apply_args_register_offset (int regno)
913 apply_args_size ();
915 /* Arguments are always put in outgoing registers (in the argument
916 block) if such make sense. */
917 #ifdef OUTGOING_REGNO
918 regno = OUTGOING_REGNO (regno);
919 #endif
920 return apply_args_reg_offset[regno];
923 /* Return the size required for the block returned by __builtin_apply_args,
924 and initialize apply_args_mode. */
926 static int
927 apply_args_size (void)
929 static int size = -1;
930 int align;
931 unsigned int regno;
932 enum machine_mode mode;
934 /* The values computed by this function never change. */
935 if (size < 0)
937 /* The first value is the incoming arg-pointer. */
938 size = GET_MODE_SIZE (Pmode);
940 /* The second value is the structure value address unless this is
941 passed as an "invisible" first argument. */
942 if (struct_value_rtx)
943 size += GET_MODE_SIZE (Pmode);
945 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
946 if (FUNCTION_ARG_REGNO_P (regno))
948 /* Search for the proper mode for copying this register's
949 value. I'm not sure this is right, but it works so far. */
950 enum machine_mode best_mode = VOIDmode;
952 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
953 mode != VOIDmode;
954 mode = GET_MODE_WIDER_MODE (mode))
955 if (HARD_REGNO_MODE_OK (regno, mode)
956 && HARD_REGNO_NREGS (regno, mode) == 1)
957 best_mode = mode;
959 if (best_mode == VOIDmode)
960 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
961 mode != VOIDmode;
962 mode = GET_MODE_WIDER_MODE (mode))
963 if (HARD_REGNO_MODE_OK (regno, mode)
964 && have_insn_for (SET, mode))
965 best_mode = mode;
967 if (best_mode == VOIDmode)
968 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
969 mode != VOIDmode;
970 mode = GET_MODE_WIDER_MODE (mode))
971 if (HARD_REGNO_MODE_OK (regno, mode)
972 && have_insn_for (SET, mode))
973 best_mode = mode;
975 if (best_mode == VOIDmode)
976 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
977 mode != VOIDmode;
978 mode = GET_MODE_WIDER_MODE (mode))
979 if (HARD_REGNO_MODE_OK (regno, mode)
980 && have_insn_for (SET, mode))
981 best_mode = mode;
983 mode = best_mode;
984 if (mode == VOIDmode)
985 abort ();
987 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
988 if (size % align != 0)
989 size = CEIL (size, align) * align;
990 apply_args_reg_offset[regno] = size;
991 size += GET_MODE_SIZE (mode);
992 apply_args_mode[regno] = mode;
994 else
996 apply_args_mode[regno] = VOIDmode;
997 apply_args_reg_offset[regno] = 0;
1000 return size;
1003 /* Return the size required for the block returned by __builtin_apply,
1004 and initialize apply_result_mode. */
1006 static int
1007 apply_result_size (void)
1009 static int size = -1;
1010 int align, regno;
1011 enum machine_mode mode;
1013 /* The values computed by this function never change. */
1014 if (size < 0)
1016 size = 0;
1018 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1019 if (FUNCTION_VALUE_REGNO_P (regno))
1021 /* Search for the proper mode for copying this register's
1022 value. I'm not sure this is right, but it works so far. */
1023 enum machine_mode best_mode = VOIDmode;
1025 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1026 mode != TImode;
1027 mode = GET_MODE_WIDER_MODE (mode))
1028 if (HARD_REGNO_MODE_OK (regno, mode))
1029 best_mode = mode;
1031 if (best_mode == VOIDmode)
1032 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1033 mode != VOIDmode;
1034 mode = GET_MODE_WIDER_MODE (mode))
1035 if (HARD_REGNO_MODE_OK (regno, mode)
1036 && have_insn_for (SET, mode))
1037 best_mode = mode;
1039 if (best_mode == VOIDmode)
1040 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1041 mode != VOIDmode;
1042 mode = GET_MODE_WIDER_MODE (mode))
1043 if (HARD_REGNO_MODE_OK (regno, mode)
1044 && have_insn_for (SET, mode))
1045 best_mode = mode;
1047 if (best_mode == VOIDmode)
1048 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1049 mode != VOIDmode;
1050 mode = GET_MODE_WIDER_MODE (mode))
1051 if (HARD_REGNO_MODE_OK (regno, mode)
1052 && have_insn_for (SET, mode))
1053 best_mode = mode;
1055 mode = best_mode;
1056 if (mode == VOIDmode)
1057 abort ();
1059 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1060 if (size % align != 0)
1061 size = CEIL (size, align) * align;
1062 size += GET_MODE_SIZE (mode);
1063 apply_result_mode[regno] = mode;
1065 else
1066 apply_result_mode[regno] = VOIDmode;
1068 /* Allow targets that use untyped_call and untyped_return to override
1069 the size so that machine-specific information can be stored here. */
1070 #ifdef APPLY_RESULT_SIZE
1071 size = APPLY_RESULT_SIZE;
1072 #endif
1074 return size;
1077 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1078 /* Create a vector describing the result block RESULT. If SAVEP is true,
1079 the result block is used to save the values; otherwise it is used to
1080 restore the values. */
1082 static rtx
1083 result_vector (int savep, rtx result)
1085 int regno, size, align, nelts;
1086 enum machine_mode mode;
1087 rtx reg, mem;
1088 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1090 size = nelts = 0;
1091 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1092 if ((mode = apply_result_mode[regno]) != VOIDmode)
1094 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1095 if (size % align != 0)
1096 size = CEIL (size, align) * align;
1097 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1098 mem = adjust_address (result, mode, size);
1099 savevec[nelts++] = (savep
1100 ? gen_rtx_SET (VOIDmode, mem, reg)
1101 : gen_rtx_SET (VOIDmode, reg, mem));
1102 size += GET_MODE_SIZE (mode);
1104 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1106 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1108 /* Save the state required to perform an untyped call with the same
1109 arguments as were passed to the current function. */
1111 static rtx
1112 expand_builtin_apply_args_1 (void)
1114 rtx registers;
1115 int size, align, regno;
1116 enum machine_mode mode;
1118 /* Create a block where the arg-pointer, structure value address,
1119 and argument registers can be saved. */
1120 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1122 /* Walk past the arg-pointer and structure value address. */
1123 size = GET_MODE_SIZE (Pmode);
1124 if (struct_value_rtx)
1125 size += GET_MODE_SIZE (Pmode);
1127 /* Save each register used in calling a function to the block. */
1128 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1129 if ((mode = apply_args_mode[regno]) != VOIDmode)
1131 rtx tem;
1133 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1134 if (size % align != 0)
1135 size = CEIL (size, align) * align;
1137 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1139 emit_move_insn (adjust_address (registers, mode, size), tem);
1140 size += GET_MODE_SIZE (mode);
1143 /* Save the arg pointer to the block. */
1144 emit_move_insn (adjust_address (registers, Pmode, 0),
1145 copy_to_reg (virtual_incoming_args_rtx));
1146 size = GET_MODE_SIZE (Pmode);
1148 /* Save the structure value address unless this is passed as an
1149 "invisible" first argument. */
1150 if (struct_value_incoming_rtx)
1152 emit_move_insn (adjust_address (registers, Pmode, size),
1153 copy_to_reg (struct_value_incoming_rtx));
1154 size += GET_MODE_SIZE (Pmode);
1157 /* Return the address of the block. */
1158 return copy_addr_to_reg (XEXP (registers, 0));
1161 /* __builtin_apply_args returns block of memory allocated on
1162 the stack into which is stored the arg pointer, structure
1163 value address, static chain, and all the registers that might
1164 possibly be used in performing a function call. The code is
1165 moved to the start of the function so the incoming values are
1166 saved. */
1168 static rtx
1169 expand_builtin_apply_args (void)
1171 /* Don't do __builtin_apply_args more than once in a function.
1172 Save the result of the first call and reuse it. */
1173 if (apply_args_value != 0)
1174 return apply_args_value;
1176 /* When this function is called, it means that registers must be
1177 saved on entry to this function. So we migrate the
1178 call to the first insn of this function. */
1179 rtx temp;
1180 rtx seq;
1182 start_sequence ();
1183 temp = expand_builtin_apply_args_1 ();
1184 seq = get_insns ();
1185 end_sequence ();
1187 apply_args_value = temp;
1189 /* Put the insns after the NOTE that starts the function.
1190 If this is inside a start_sequence, make the outer-level insn
1191 chain current, so the code is placed at the start of the
1192 function. */
1193 push_topmost_sequence ();
1194 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1195 pop_topmost_sequence ();
1196 return temp;
1200 /* Perform an untyped call and save the state required to perform an
1201 untyped return of whatever value was returned by the given function. */
1203 static rtx
1204 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1206 int size, align, regno;
1207 enum machine_mode mode;
1208 rtx incoming_args, result, reg, dest, src, call_insn;
1209 rtx old_stack_level = 0;
1210 rtx call_fusage = 0;
1212 #ifdef POINTERS_EXTEND_UNSIGNED
1213 if (GET_MODE (arguments) != Pmode)
1214 arguments = convert_memory_address (Pmode, arguments);
1215 #endif
1217 /* Create a block where the return registers can be saved. */
1218 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1220 /* Fetch the arg pointer from the ARGUMENTS block. */
1221 incoming_args = gen_reg_rtx (Pmode);
1222 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1223 #ifndef STACK_GROWS_DOWNWARD
1224 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1225 incoming_args, 0, OPTAB_LIB_WIDEN);
1226 #endif
1228 /* Perform postincrements before actually calling the function. */
1229 emit_queue ();
1231 /* Push a new argument block and copy the arguments. Do not allow
1232 the (potential) memcpy call below to interfere with our stack
1233 manipulations. */
1234 do_pending_stack_adjust ();
1235 NO_DEFER_POP;
1237 /* Save the stack with nonlocal if available. */
1238 #ifdef HAVE_save_stack_nonlocal
1239 if (HAVE_save_stack_nonlocal)
1240 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1241 else
1242 #endif
1243 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1245 /* Push a block of memory onto the stack to store the memory arguments.
1246 Save the address in a register, and copy the memory arguments. ??? I
1247 haven't figured out how the calling convention macros effect this,
1248 but it's likely that the source and/or destination addresses in
1249 the block copy will need updating in machine specific ways. */
1250 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1251 dest = gen_rtx_MEM (BLKmode, dest);
1252 set_mem_align (dest, PARM_BOUNDARY);
1253 src = gen_rtx_MEM (BLKmode, incoming_args);
1254 set_mem_align (src, PARM_BOUNDARY);
1255 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1257 /* Refer to the argument block. */
1258 apply_args_size ();
1259 arguments = gen_rtx_MEM (BLKmode, arguments);
1260 set_mem_align (arguments, PARM_BOUNDARY);
1262 /* Walk past the arg-pointer and structure value address. */
1263 size = GET_MODE_SIZE (Pmode);
1264 if (struct_value_rtx)
1265 size += GET_MODE_SIZE (Pmode);
1267 /* Restore each of the registers previously saved. Make USE insns
1268 for each of these registers for use in making the call. */
1269 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1270 if ((mode = apply_args_mode[regno]) != VOIDmode)
1272 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1273 if (size % align != 0)
1274 size = CEIL (size, align) * align;
1275 reg = gen_rtx_REG (mode, regno);
1276 emit_move_insn (reg, adjust_address (arguments, mode, size));
1277 use_reg (&call_fusage, reg);
1278 size += GET_MODE_SIZE (mode);
1281 /* Restore the structure value address unless this is passed as an
1282 "invisible" first argument. */
1283 size = GET_MODE_SIZE (Pmode);
1284 if (struct_value_rtx)
1286 rtx value = gen_reg_rtx (Pmode);
1287 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1288 emit_move_insn (struct_value_rtx, value);
1289 if (GET_CODE (struct_value_rtx) == REG)
1290 use_reg (&call_fusage, struct_value_rtx);
1291 size += GET_MODE_SIZE (Pmode);
1294 /* All arguments and registers used for the call are set up by now! */
1295 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1297 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1298 and we don't want to load it into a register as an optimization,
1299 because prepare_call_address already did it if it should be done. */
1300 if (GET_CODE (function) != SYMBOL_REF)
1301 function = memory_address (FUNCTION_MODE, function);
1303 /* Generate the actual call instruction and save the return value. */
1304 #ifdef HAVE_untyped_call
1305 if (HAVE_untyped_call)
1306 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1307 result, result_vector (1, result)));
1308 else
1309 #endif
1310 #ifdef HAVE_call_value
1311 if (HAVE_call_value)
1313 rtx valreg = 0;
1315 /* Locate the unique return register. It is not possible to
1316 express a call that sets more than one return register using
1317 call_value; use untyped_call for that. In fact, untyped_call
1318 only needs to save the return registers in the given block. */
1319 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1320 if ((mode = apply_result_mode[regno]) != VOIDmode)
1322 if (valreg)
1323 abort (); /* HAVE_untyped_call required. */
1324 valreg = gen_rtx_REG (mode, regno);
1327 emit_call_insn (GEN_CALL_VALUE (valreg,
1328 gen_rtx_MEM (FUNCTION_MODE, function),
1329 const0_rtx, NULL_RTX, const0_rtx));
1331 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1333 else
1334 #endif
1335 abort ();
1337 /* Find the CALL insn we just emitted, and attach the register usage
1338 information. */
1339 call_insn = last_call_insn ();
1340 add_function_usage_to (call_insn, call_fusage);
1342 /* Restore the stack. */
1343 #ifdef HAVE_save_stack_nonlocal
1344 if (HAVE_save_stack_nonlocal)
1345 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1346 else
1347 #endif
1348 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1350 OK_DEFER_POP;
1352 /* Return the address of the result block. */
1353 return copy_addr_to_reg (XEXP (result, 0));
1356 /* Perform an untyped return. */
1358 static void
1359 expand_builtin_return (rtx result)
1361 int size, align, regno;
1362 enum machine_mode mode;
1363 rtx reg;
1364 rtx call_fusage = 0;
1366 #ifdef POINTERS_EXTEND_UNSIGNED
1367 if (GET_MODE (result) != Pmode)
1368 result = convert_memory_address (Pmode, result);
1369 #endif
1371 apply_result_size ();
1372 result = gen_rtx_MEM (BLKmode, result);
1374 #ifdef HAVE_untyped_return
1375 if (HAVE_untyped_return)
1377 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1378 emit_barrier ();
1379 return;
1381 #endif
1383 /* Restore the return value and note that each value is used. */
1384 size = 0;
1385 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1386 if ((mode = apply_result_mode[regno]) != VOIDmode)
1388 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1389 if (size % align != 0)
1390 size = CEIL (size, align) * align;
1391 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1392 emit_move_insn (reg, adjust_address (result, mode, size));
1394 push_to_sequence (call_fusage);
1395 emit_insn (gen_rtx_USE (VOIDmode, reg));
1396 call_fusage = get_insns ();
1397 end_sequence ();
1398 size += GET_MODE_SIZE (mode);
1401 /* Put the USE insns before the return. */
1402 emit_insn (call_fusage);
1404 /* Return whatever values was restored by jumping directly to the end
1405 of the function. */
1406 expand_null_return ();
1409 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1411 static enum type_class
1412 type_to_class (tree type)
1414 switch (TREE_CODE (type))
1416 case VOID_TYPE: return void_type_class;
1417 case INTEGER_TYPE: return integer_type_class;
1418 case CHAR_TYPE: return char_type_class;
1419 case ENUMERAL_TYPE: return enumeral_type_class;
1420 case BOOLEAN_TYPE: return boolean_type_class;
1421 case POINTER_TYPE: return pointer_type_class;
1422 case REFERENCE_TYPE: return reference_type_class;
1423 case OFFSET_TYPE: return offset_type_class;
1424 case REAL_TYPE: return real_type_class;
1425 case COMPLEX_TYPE: return complex_type_class;
1426 case FUNCTION_TYPE: return function_type_class;
1427 case METHOD_TYPE: return method_type_class;
1428 case RECORD_TYPE: return record_type_class;
1429 case UNION_TYPE:
1430 case QUAL_UNION_TYPE: return union_type_class;
1431 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1432 ? string_type_class : array_type_class);
1433 case SET_TYPE: return set_type_class;
1434 case FILE_TYPE: return file_type_class;
1435 case LANG_TYPE: return lang_type_class;
1436 default: return no_type_class;
1440 /* Expand a call to __builtin_classify_type with arguments found in
1441 ARGLIST. */
1443 static rtx
1444 expand_builtin_classify_type (tree arglist)
1446 if (arglist != 0)
1447 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1448 return GEN_INT (no_type_class);
1451 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1453 static rtx
1454 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1456 rtx tmp;
1458 if (arglist == 0)
1459 return const0_rtx;
1460 arglist = TREE_VALUE (arglist);
1462 /* We have taken care of the easy cases during constant folding. This
1463 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1464 get a chance to see if it can deduce whether ARGLIST is constant. */
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_ATAN)
1493 CASE_MATHFN (BUILT_IN_CEIL)
1494 CASE_MATHFN (BUILT_IN_COS)
1495 CASE_MATHFN (BUILT_IN_EXP)
1496 CASE_MATHFN (BUILT_IN_FLOOR)
1497 CASE_MATHFN (BUILT_IN_LOG)
1498 CASE_MATHFN (BUILT_IN_NEARBYINT)
1499 CASE_MATHFN (BUILT_IN_ROUND)
1500 CASE_MATHFN (BUILT_IN_SIN)
1501 CASE_MATHFN (BUILT_IN_SQRT)
1502 CASE_MATHFN (BUILT_IN_TAN)
1503 CASE_MATHFN (BUILT_IN_TRUNC)
1505 default:
1506 return 0;
1509 if (type_mode == TYPE_MODE (double_type_node))
1510 return implicit_built_in_decls[fcode];
1511 else if (type_mode == TYPE_MODE (float_type_node))
1512 return implicit_built_in_decls[fcodef];
1513 else if (type_mode == TYPE_MODE (long_double_type_node))
1514 return implicit_built_in_decls[fcodel];
1515 else
1516 return 0;
1519 /* If errno must be maintained, expand the RTL to check if the result,
1520 TARGET, of a built-in function call, EXP, is NaN, and if so set
1521 errno to EDOM. */
1523 static void
1524 expand_errno_check (tree exp, rtx target)
1526 rtx lab = gen_label_rtx ();
1528 /* Test the result; if it is NaN, set errno=EDOM because
1529 the argument was not in the domain. */
1530 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1531 0, lab);
1533 #ifdef TARGET_EDOM
1534 /* If this built-in doesn't throw an exception, set errno directly. */
1535 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1537 #ifdef GEN_ERRNO_RTX
1538 rtx errno_rtx = GEN_ERRNO_RTX;
1539 #else
1540 rtx errno_rtx
1541 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1542 #endif
1543 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1544 emit_label (lab);
1545 return;
1547 #endif
1549 /* We can't set errno=EDOM directly; let the library call do it.
1550 Pop the arguments right away in case the call gets deleted. */
1551 NO_DEFER_POP;
1552 expand_call (exp, target, 0);
1553 OK_DEFER_POP;
1554 emit_label (lab);
1558 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1559 Return 0 if a normal call should be emitted rather than expanding the
1560 function in-line. EXP is the expression that is a call to the builtin
1561 function; if convenient, the result should be placed in TARGET.
1562 SUBTARGET may be used as the target for computing one of EXP's operands. */
1564 static rtx
1565 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1567 optab builtin_optab;
1568 rtx op0, insns;
1569 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1570 tree arglist = TREE_OPERAND (exp, 1);
1571 enum machine_mode mode;
1572 bool errno_set = false;
1573 tree arg, narg;
1575 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1576 return 0;
1578 arg = TREE_VALUE (arglist);
1580 switch (DECL_FUNCTION_CODE (fndecl))
1582 case BUILT_IN_SIN:
1583 case BUILT_IN_SINF:
1584 case BUILT_IN_SINL:
1585 builtin_optab = sin_optab; break;
1586 case BUILT_IN_COS:
1587 case BUILT_IN_COSF:
1588 case BUILT_IN_COSL:
1589 builtin_optab = cos_optab; break;
1590 case BUILT_IN_SQRT:
1591 case BUILT_IN_SQRTF:
1592 case BUILT_IN_SQRTL:
1593 errno_set = ! tree_expr_nonnegative_p (arg);
1594 builtin_optab = sqrt_optab;
1595 break;
1596 case BUILT_IN_EXP:
1597 case BUILT_IN_EXPF:
1598 case BUILT_IN_EXPL:
1599 errno_set = true; builtin_optab = exp_optab; break;
1600 case BUILT_IN_LOG:
1601 case BUILT_IN_LOGF:
1602 case BUILT_IN_LOGL:
1603 errno_set = true; builtin_optab = log_optab; break;
1604 case BUILT_IN_TAN:
1605 case BUILT_IN_TANF:
1606 case BUILT_IN_TANL:
1607 builtin_optab = tan_optab; break;
1608 case BUILT_IN_ATAN:
1609 case BUILT_IN_ATANF:
1610 case BUILT_IN_ATANL:
1611 builtin_optab = atan_optab; break;
1612 case BUILT_IN_FLOOR:
1613 case BUILT_IN_FLOORF:
1614 case BUILT_IN_FLOORL:
1615 builtin_optab = floor_optab; break;
1616 case BUILT_IN_CEIL:
1617 case BUILT_IN_CEILF:
1618 case BUILT_IN_CEILL:
1619 builtin_optab = ceil_optab; break;
1620 case BUILT_IN_TRUNC:
1621 case BUILT_IN_TRUNCF:
1622 case BUILT_IN_TRUNCL:
1623 builtin_optab = trunc_optab; break;
1624 case BUILT_IN_ROUND:
1625 case BUILT_IN_ROUNDF:
1626 case BUILT_IN_ROUNDL:
1627 builtin_optab = round_optab; break;
1628 case BUILT_IN_NEARBYINT:
1629 case BUILT_IN_NEARBYINTF:
1630 case BUILT_IN_NEARBYINTL:
1631 builtin_optab = nearbyint_optab; break;
1632 default:
1633 abort ();
1636 /* Make a suitable register to place result in. */
1637 mode = TYPE_MODE (TREE_TYPE (exp));
1639 /* Before working hard, check whether the instruction is available. */
1640 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1641 return 0;
1642 target = gen_reg_rtx (mode);
1644 if (! flag_errno_math || ! HONOR_NANS (mode))
1645 errno_set = false;
1647 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1648 need to expand the argument again. This way, we will not perform
1649 side-effects more the once. */
1650 narg = save_expr (arg);
1651 if (narg != arg)
1653 arglist = build_tree_list (NULL_TREE, arg);
1654 exp = build_function_call_expr (fndecl, arglist);
1657 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1659 emit_queue ();
1660 start_sequence ();
1662 /* Compute into TARGET.
1663 Set TARGET to wherever the result comes back. */
1664 target = expand_unop (mode, builtin_optab, op0, target, 0);
1666 /* If we were unable to expand via the builtin, stop the sequence
1667 (without outputting the insns) and call to the library function
1668 with the stabilized argument list. */
1669 if (target == 0)
1671 end_sequence ();
1672 return expand_call (exp, target, target == const0_rtx);
1675 if (errno_set)
1676 expand_errno_check (exp, target);
1678 /* Output the entire sequence. */
1679 insns = get_insns ();
1680 end_sequence ();
1681 emit_insn (insns);
1683 return target;
1686 /* Expand a call to the builtin binary math functions (pow and atan2).
1687 Return 0 if a normal call should be emitted rather than expanding the
1688 function in-line. EXP is the expression that is a call to the builtin
1689 function; if convenient, the result should be placed in TARGET.
1690 SUBTARGET may be used as the target for computing one of EXP's
1691 operands. */
1693 static rtx
1694 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1696 optab builtin_optab;
1697 rtx op0, op1, insns;
1698 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1699 tree arglist = TREE_OPERAND (exp, 1);
1700 tree arg0, arg1, temp, narg;
1701 enum machine_mode mode;
1702 bool errno_set = true;
1703 bool stable = true;
1705 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1706 return 0;
1708 arg0 = TREE_VALUE (arglist);
1709 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1711 switch (DECL_FUNCTION_CODE (fndecl))
1713 case BUILT_IN_POW:
1714 case BUILT_IN_POWF:
1715 case BUILT_IN_POWL:
1716 builtin_optab = pow_optab; break;
1717 case BUILT_IN_ATAN2:
1718 case BUILT_IN_ATAN2F:
1719 case BUILT_IN_ATAN2L:
1720 builtin_optab = atan2_optab; break;
1721 default:
1722 abort ();
1725 /* Make a suitable register to place result in. */
1726 mode = TYPE_MODE (TREE_TYPE (exp));
1728 /* Before working hard, check whether the instruction is available. */
1729 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1730 return 0;
1732 target = gen_reg_rtx (mode);
1734 if (! flag_errno_math || ! HONOR_NANS (mode))
1735 errno_set = false;
1737 /* Alway stabilize the argument list. */
1738 narg = save_expr (arg1);
1739 if (narg != arg1)
1741 temp = build_tree_list (NULL_TREE, narg);
1742 stable = false;
1744 else
1745 temp = TREE_CHAIN (arglist);
1747 narg = save_expr (arg0);
1748 if (narg != arg0)
1750 arglist = tree_cons (NULL_TREE, narg, temp);
1751 stable = false;
1753 else if (! stable)
1754 arglist = tree_cons (NULL_TREE, arg0, temp);
1756 if (! stable)
1757 exp = build_function_call_expr (fndecl, arglist);
1759 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1760 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1762 emit_queue ();
1763 start_sequence ();
1765 /* Compute into TARGET.
1766 Set TARGET to wherever the result comes back. */
1767 target = expand_binop (mode, builtin_optab, op0, op1,
1768 target, 0, OPTAB_DIRECT);
1770 /* If we were unable to expand via the builtin, stop the sequence
1771 (without outputting the insns) and call to the library function
1772 with the stabilized argument list. */
1773 if (target == 0)
1775 end_sequence ();
1776 return expand_call (exp, target, target == const0_rtx);
1779 if (errno_set)
1780 expand_errno_check (exp, target);
1782 /* Output the entire sequence. */
1783 insns = get_insns ();
1784 end_sequence ();
1785 emit_insn (insns);
1787 return target;
1790 /* To evaluate powi(x,n), the floating point value x raised to the
1791 constant integer exponent n, we use a hybrid algorithm that
1792 combines the "window method" with look-up tables. For an
1793 introduction to exponentiation algorithms and "addition chains",
1794 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1795 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1796 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1797 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1799 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1800 multiplications to inline before calling the system library's pow
1801 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1802 so this default never requires calling pow, powf or powl. */
1804 #ifndef POWI_MAX_MULTS
1805 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1806 #endif
1808 /* The size of the "optimal power tree" lookup table. All
1809 exponents less than this value are simply looked up in the
1810 powi_table below. This threshold is also used to size the
1811 cache of pseudo registers that hold intermediate results. */
1812 #define POWI_TABLE_SIZE 256
1814 /* The size, in bits of the window, used in the "window method"
1815 exponentiation algorithm. This is equivalent to a radix of
1816 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1817 #define POWI_WINDOW_SIZE 3
1819 /* The following table is an efficient representation of an
1820 "optimal power tree". For each value, i, the corresponding
1821 value, j, in the table states than an optimal evaluation
1822 sequence for calculating pow(x,i) can be found by evaluating
1823 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1824 100 integers is given in Knuth's "Seminumerical algorithms". */
1826 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1828 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1829 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1830 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1831 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1832 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1833 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1834 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1835 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1836 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1837 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1838 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1839 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1840 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1841 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1842 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1843 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1844 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1845 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1846 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1847 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1848 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1849 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1850 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1851 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1852 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1853 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1854 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1855 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1856 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1857 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1858 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1859 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1863 /* Return the number of multiplications required to calculate
1864 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
1865 subroutine of powi_cost. CACHE is an array indicating
1866 which exponents have already been calculated. */
1868 static int
1869 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1871 /* If we've already calculated this exponent, then this evaluation
1872 doesn't require any additional multiplications. */
1873 if (cache[n])
1874 return 0;
1876 cache[n] = true;
1877 return powi_lookup_cost (n - powi_table[n], cache)
1878 + powi_lookup_cost (powi_table[n], cache) + 1;
1881 /* Return the number of multiplications required to calculate
1882 powi(x,n) for an arbitrary x, given the exponent N. This
1883 function needs to be kept in sync with expand_powi below. */
1885 static int
1886 powi_cost (HOST_WIDE_INT n)
1888 bool cache[POWI_TABLE_SIZE];
1889 unsigned HOST_WIDE_INT digit;
1890 unsigned HOST_WIDE_INT val;
1891 int result;
1893 if (n == 0)
1894 return 0;
1896 /* Ignore the reciprocal when calculating the cost. */
1897 val = (n < 0) ? -n : n;
1899 /* Initialize the exponent cache. */
1900 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
1901 cache[1] = true;
1903 result = 0;
1905 while (val >= POWI_TABLE_SIZE)
1907 if (val & 1)
1909 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
1910 result += powi_lookup_cost (digit, cache)
1911 + POWI_WINDOW_SIZE + 1;
1912 val >>= POWI_WINDOW_SIZE;
1914 else
1916 val >>= 1;
1917 result++;
1921 return result + powi_lookup_cost (val, cache);
1924 /* Recursive subroutine of expand_powi. This function takes the array,
1925 CACHE, of already calculated exponents and an exponent N and returns
1926 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
1928 static rtx
1929 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
1931 unsigned HOST_WIDE_INT digit;
1932 rtx target, result;
1933 rtx op0, op1;
1935 if (n < POWI_TABLE_SIZE)
1937 if (cache[n])
1938 return cache[n];
1940 target = gen_reg_rtx (mode);
1941 cache[n] = target;
1943 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
1944 op1 = expand_powi_1 (mode, powi_table[n], cache);
1946 else if (n & 1)
1948 target = gen_reg_rtx (mode);
1949 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1950 op0 = expand_powi_1 (mode, n - digit, cache);
1951 op1 = expand_powi_1 (mode, digit, cache);
1953 else
1955 target = gen_reg_rtx (mode);
1956 op0 = expand_powi_1 (mode, n >> 1, cache);
1957 op1 = op0;
1960 result = expand_mult (mode, op0, op1, target, 0);
1961 if (result != target)
1962 emit_move_insn (target, result);
1963 return target;
1966 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
1967 floating point operand in mode MODE, and N is the exponent. This
1968 function needs to be kept in sync with powi_cost above. */
1970 static rtx
1971 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
1973 unsigned HOST_WIDE_INT val;
1974 rtx cache[POWI_TABLE_SIZE];
1975 rtx result;
1977 if (n == 0)
1978 return CONST1_RTX (mode);
1980 val = (n < 0) ? -n : n;
1982 memset (cache, 0, sizeof (cache));
1983 cache[1] = x;
1985 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
1987 /* If the original exponent was negative, reciprocate the result. */
1988 if (n < 0)
1989 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
1990 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
1992 return result;
1995 /* Expand a call to the pow built-in mathematical function. Return 0 if
1996 a normal call should be emitted rather than expanding the function
1997 in-line. EXP is the expression that is a call to the builtin
1998 function; if convenient, the result should be placed in TARGET. */
2000 static rtx
2001 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2003 tree arglist = TREE_OPERAND (exp, 1);
2004 tree arg0, arg1;
2006 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2007 return 0;
2009 arg0 = TREE_VALUE (arglist);
2010 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2012 if (TREE_CODE (arg1) == REAL_CST
2013 && ! TREE_CONSTANT_OVERFLOW (arg1))
2015 REAL_VALUE_TYPE cint;
2016 REAL_VALUE_TYPE c;
2017 HOST_WIDE_INT n;
2019 c = TREE_REAL_CST (arg1);
2020 n = real_to_integer (&c);
2021 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2022 if (real_identical (&c, &cint))
2024 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2025 Otherwise, check the number of multiplications required.
2026 Note that pow never sets errno for an integer exponent. */
2027 if ((n >= -1 && n <= 2)
2028 || (flag_unsafe_math_optimizations
2029 && ! optimize_size
2030 && powi_cost (n) <= POWI_MAX_MULTS))
2032 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2033 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2034 op = force_reg (mode, op);
2035 return expand_powi (op, mode, n);
2039 return expand_builtin_mathfn_2 (exp, target, NULL_RTX);
2042 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2043 if we failed the caller should emit a normal call, otherwise
2044 try to get the result in TARGET, if convenient. */
2046 static rtx
2047 expand_builtin_strlen (tree arglist, rtx target,
2048 enum machine_mode target_mode)
2050 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2051 return 0;
2052 else
2054 rtx pat;
2055 tree len, src = TREE_VALUE (arglist);
2056 rtx result, src_reg, char_rtx, before_strlen;
2057 enum machine_mode insn_mode = target_mode, char_mode;
2058 enum insn_code icode = CODE_FOR_nothing;
2059 int align;
2061 /* If the length can be computed at compile-time, return it. */
2062 len = c_strlen (src, 0);
2063 if (len)
2064 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2066 /* If the length can be computed at compile-time and is constant
2067 integer, but there are side-effects in src, evaluate
2068 src for side-effects, then return len.
2069 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2070 can be optimized into: i++; x = 3; */
2071 len = c_strlen (src, 1);
2072 if (len && TREE_CODE (len) == INTEGER_CST)
2074 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2075 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2078 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2080 /* If SRC is not a pointer type, don't do this operation inline. */
2081 if (align == 0)
2082 return 0;
2084 /* Bail out if we can't compute strlen in the right mode. */
2085 while (insn_mode != VOIDmode)
2087 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2088 if (icode != CODE_FOR_nothing)
2089 break;
2091 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2093 if (insn_mode == VOIDmode)
2094 return 0;
2096 /* Make a place to write the result of the instruction. */
2097 result = target;
2098 if (! (result != 0
2099 && GET_CODE (result) == REG
2100 && GET_MODE (result) == insn_mode
2101 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2102 result = gen_reg_rtx (insn_mode);
2104 /* Make a place to hold the source address. We will not expand
2105 the actual source until we are sure that the expansion will
2106 not fail -- there are trees that cannot be expanded twice. */
2107 src_reg = gen_reg_rtx (Pmode);
2109 /* Mark the beginning of the strlen sequence so we can emit the
2110 source operand later. */
2111 before_strlen = get_last_insn ();
2113 char_rtx = const0_rtx;
2114 char_mode = insn_data[(int) icode].operand[2].mode;
2115 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2116 char_mode))
2117 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2119 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2120 char_rtx, GEN_INT (align));
2121 if (! pat)
2122 return 0;
2123 emit_insn (pat);
2125 /* Now that we are assured of success, expand the source. */
2126 start_sequence ();
2127 pat = memory_address (BLKmode,
2128 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2129 if (pat != src_reg)
2130 emit_move_insn (src_reg, pat);
2131 pat = get_insns ();
2132 end_sequence ();
2134 if (before_strlen)
2135 emit_insn_after (pat, before_strlen);
2136 else
2137 emit_insn_before (pat, get_insns ());
2139 /* Return the value in the proper mode for this function. */
2140 if (GET_MODE (result) == target_mode)
2141 target = result;
2142 else if (target != 0)
2143 convert_move (target, result, 0);
2144 else
2145 target = convert_to_mode (target_mode, result, 0);
2147 return target;
2151 /* Expand a call to the strstr builtin. Return 0 if we failed the
2152 caller should emit a normal call, otherwise try to get the result
2153 in TARGET, if convenient (and in mode MODE if that's convenient). */
2155 static rtx
2156 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2158 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2159 return 0;
2160 else
2162 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2163 tree fn;
2164 const char *p1, *p2;
2166 p2 = c_getstr (s2);
2167 if (p2 == NULL)
2168 return 0;
2170 p1 = c_getstr (s1);
2171 if (p1 != NULL)
2173 const char *r = strstr (p1, p2);
2175 if (r == NULL)
2176 return const0_rtx;
2178 /* Return an offset into the constant string argument. */
2179 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2180 s1, ssize_int (r - p1))),
2181 target, mode, EXPAND_NORMAL);
2184 if (p2[0] == '\0')
2185 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2187 if (p2[1] != '\0')
2188 return 0;
2190 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2191 if (!fn)
2192 return 0;
2194 /* New argument list transforming strstr(s1, s2) to
2195 strchr(s1, s2[0]). */
2196 arglist =
2197 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2198 arglist = tree_cons (NULL_TREE, s1, arglist);
2199 return expand_expr (build_function_call_expr (fn, arglist),
2200 target, mode, EXPAND_NORMAL);
2204 /* Expand a call to the strchr builtin. Return 0 if we failed the
2205 caller should emit a normal call, otherwise try to get the result
2206 in TARGET, if convenient (and in mode MODE if that's convenient). */
2208 static rtx
2209 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2211 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2212 return 0;
2213 else
2215 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2216 const char *p1;
2218 if (TREE_CODE (s2) != INTEGER_CST)
2219 return 0;
2221 p1 = c_getstr (s1);
2222 if (p1 != NULL)
2224 char c;
2225 const char *r;
2227 if (target_char_cast (s2, &c))
2228 return 0;
2230 r = strchr (p1, c);
2232 if (r == NULL)
2233 return const0_rtx;
2235 /* Return an offset into the constant string argument. */
2236 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2237 s1, ssize_int (r - p1))),
2238 target, mode, EXPAND_NORMAL);
2241 /* FIXME: Should use here strchrM optab so that ports can optimize
2242 this. */
2243 return 0;
2247 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2248 caller should emit a normal call, otherwise try to get the result
2249 in TARGET, if convenient (and in mode MODE if that's convenient). */
2251 static rtx
2252 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2254 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2255 return 0;
2256 else
2258 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2259 tree fn;
2260 const char *p1;
2262 if (TREE_CODE (s2) != INTEGER_CST)
2263 return 0;
2265 p1 = c_getstr (s1);
2266 if (p1 != NULL)
2268 char c;
2269 const char *r;
2271 if (target_char_cast (s2, &c))
2272 return 0;
2274 r = strrchr (p1, c);
2276 if (r == NULL)
2277 return const0_rtx;
2279 /* Return an offset into the constant string argument. */
2280 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2281 s1, ssize_int (r - p1))),
2282 target, mode, EXPAND_NORMAL);
2285 if (! integer_zerop (s2))
2286 return 0;
2288 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2289 if (!fn)
2290 return 0;
2292 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2293 return expand_expr (build_function_call_expr (fn, arglist),
2294 target, mode, EXPAND_NORMAL);
2298 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2299 caller should emit a normal call, otherwise try to get the result
2300 in TARGET, if convenient (and in mode MODE if that's convenient). */
2302 static rtx
2303 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2305 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2306 return 0;
2307 else
2309 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2310 tree fn;
2311 const char *p1, *p2;
2313 p2 = c_getstr (s2);
2314 if (p2 == NULL)
2315 return 0;
2317 p1 = c_getstr (s1);
2318 if (p1 != NULL)
2320 const char *r = strpbrk (p1, p2);
2322 if (r == NULL)
2323 return const0_rtx;
2325 /* Return an offset into the constant string argument. */
2326 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2327 s1, ssize_int (r - p1))),
2328 target, mode, EXPAND_NORMAL);
2331 if (p2[0] == '\0')
2333 /* strpbrk(x, "") == NULL.
2334 Evaluate and ignore the arguments in case they had
2335 side-effects. */
2336 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2337 return const0_rtx;
2340 if (p2[1] != '\0')
2341 return 0; /* Really call strpbrk. */
2343 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2344 if (!fn)
2345 return 0;
2347 /* New argument list transforming strpbrk(s1, s2) to
2348 strchr(s1, s2[0]). */
2349 arglist =
2350 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2351 arglist = tree_cons (NULL_TREE, s1, arglist);
2352 return expand_expr (build_function_call_expr (fn, arglist),
2353 target, mode, EXPAND_NORMAL);
2357 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2358 bytes from constant string DATA + OFFSET and return it as target
2359 constant. */
2361 static rtx
2362 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2363 enum machine_mode mode)
2365 const char *str = (const char *) data;
2367 if (offset < 0
2368 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2369 > strlen (str) + 1))
2370 abort (); /* Attempt to read past the end of constant string. */
2372 return c_readstr (str + offset, mode);
2375 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2376 Return 0 if we failed, the caller should emit a normal call,
2377 otherwise try to get the result in TARGET, if convenient (and in
2378 mode MODE if that's convenient). */
2379 static rtx
2380 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2382 if (!validate_arglist (arglist,
2383 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2384 return 0;
2385 else
2387 tree dest = TREE_VALUE (arglist);
2388 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2389 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2390 const char *src_str;
2391 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2392 unsigned int dest_align
2393 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2394 rtx dest_mem, src_mem, dest_addr, len_rtx;
2396 /* If DEST is not a pointer type, call the normal function. */
2397 if (dest_align == 0)
2398 return 0;
2400 /* If the LEN parameter is zero, return DEST. */
2401 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2403 /* Evaluate and ignore SRC in case it has side-effects. */
2404 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2405 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2408 /* If either SRC is not a pointer type, don't do this
2409 operation in-line. */
2410 if (src_align == 0)
2411 return 0;
2413 dest_mem = get_memory_rtx (dest);
2414 set_mem_align (dest_mem, dest_align);
2415 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2416 src_str = c_getstr (src);
2418 /* If SRC is a string constant and block move would be done
2419 by pieces, we can avoid loading the string from memory
2420 and only stored the computed constants. */
2421 if (src_str
2422 && GET_CODE (len_rtx) == CONST_INT
2423 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2424 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2425 (void *) src_str, dest_align))
2427 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2428 builtin_memcpy_read_str,
2429 (void *) src_str, dest_align, 0);
2430 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2431 #ifdef POINTERS_EXTEND_UNSIGNED
2432 if (GET_MODE (dest_mem) != ptr_mode)
2433 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2434 #endif
2435 return dest_mem;
2438 src_mem = get_memory_rtx (src);
2439 set_mem_align (src_mem, src_align);
2441 /* Copy word part most expediently. */
2442 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2443 BLOCK_OP_NORMAL);
2445 if (dest_addr == 0)
2447 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2448 #ifdef POINTERS_EXTEND_UNSIGNED
2449 if (GET_MODE (dest_addr) != ptr_mode)
2450 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2451 #endif
2453 return dest_addr;
2457 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2458 Return 0 if we failed the caller should emit a normal call,
2459 otherwise try to get the result in TARGET, if convenient (and in
2460 mode MODE if that's convenient). If ENDP is 0 return the
2461 destination pointer, if ENDP is 1 return the end pointer ala
2462 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2463 stpcpy. */
2465 static rtx
2466 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2467 int endp)
2469 if (!validate_arglist (arglist,
2470 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2471 return 0;
2472 /* If return value is ignored, transform mempcpy into memcpy. */
2473 else if (target == const0_rtx)
2475 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2477 if (!fn)
2478 return 0;
2480 return expand_expr (build_function_call_expr (fn, arglist),
2481 target, mode, EXPAND_NORMAL);
2483 else
2485 tree dest = TREE_VALUE (arglist);
2486 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2487 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2488 const char *src_str;
2489 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2490 unsigned int dest_align
2491 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2492 rtx dest_mem, src_mem, len_rtx;
2494 /* If DEST is not a pointer type or LEN is not constant,
2495 call the normal function. */
2496 if (dest_align == 0 || !host_integerp (len, 1))
2497 return 0;
2499 /* If the LEN parameter is zero, return DEST. */
2500 if (tree_low_cst (len, 1) == 0)
2502 /* Evaluate and ignore SRC in case it has side-effects. */
2503 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2504 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2507 /* If either SRC is not a pointer type, don't do this
2508 operation in-line. */
2509 if (src_align == 0)
2510 return 0;
2512 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2513 src_str = c_getstr (src);
2515 /* If SRC is a string constant and block move would be done
2516 by pieces, we can avoid loading the string from memory
2517 and only stored the computed constants. */
2518 if (src_str
2519 && GET_CODE (len_rtx) == CONST_INT
2520 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2521 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2522 (void *) src_str, dest_align))
2524 dest_mem = get_memory_rtx (dest);
2525 set_mem_align (dest_mem, dest_align);
2526 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2527 builtin_memcpy_read_str,
2528 (void *) src_str, dest_align, endp);
2529 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2530 #ifdef POINTERS_EXTEND_UNSIGNED
2531 if (GET_MODE (dest_mem) != ptr_mode)
2532 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2533 #endif
2534 return dest_mem;
2537 if (GET_CODE (len_rtx) == CONST_INT
2538 && can_move_by_pieces (INTVAL (len_rtx),
2539 MIN (dest_align, src_align)))
2541 dest_mem = get_memory_rtx (dest);
2542 set_mem_align (dest_mem, dest_align);
2543 src_mem = get_memory_rtx (src);
2544 set_mem_align (src_mem, src_align);
2545 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2546 MIN (dest_align, src_align), endp);
2547 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2548 #ifdef POINTERS_EXTEND_UNSIGNED
2549 if (GET_MODE (dest_mem) != ptr_mode)
2550 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2551 #endif
2552 return dest_mem;
2555 return 0;
2559 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2560 if we failed the caller should emit a normal call. */
2562 static rtx
2563 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2565 if (!validate_arglist (arglist,
2566 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2567 return 0;
2568 else
2570 tree dest = TREE_VALUE (arglist);
2571 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2572 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2574 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2575 unsigned int dest_align
2576 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2578 /* If DEST is not a pointer type, call the normal function. */
2579 if (dest_align == 0)
2580 return 0;
2582 /* If the LEN parameter is zero, return DEST. */
2583 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2585 /* Evaluate and ignore SRC in case it has side-effects. */
2586 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2587 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2590 /* If either SRC is not a pointer type, don't do this
2591 operation in-line. */
2592 if (src_align == 0)
2593 return 0;
2595 /* If src is categorized for a readonly section we can use
2596 normal memcpy. */
2597 if (readonly_data_expr (src))
2599 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2600 if (!fn)
2601 return 0;
2602 return expand_expr (build_function_call_expr (fn, arglist),
2603 target, mode, EXPAND_NORMAL);
2606 /* Otherwise, call the normal function. */
2607 return 0;
2611 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2612 if we failed the caller should emit a normal call. */
2614 static rtx
2615 expand_builtin_bcopy (tree arglist)
2617 tree src, dest, size, newarglist;
2619 if (!validate_arglist (arglist,
2620 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2621 return NULL_RTX;
2623 src = TREE_VALUE (arglist);
2624 dest = TREE_VALUE (TREE_CHAIN (arglist));
2625 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2627 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2628 memmove(ptr y, ptr x, size_t z). This is done this way
2629 so that if it isn't expanded inline, we fallback to
2630 calling bcopy instead of memmove. */
2632 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2633 newarglist = tree_cons (NULL_TREE, src, newarglist);
2634 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2636 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2639 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2640 if we failed the caller should emit a normal call, otherwise try to get
2641 the result in TARGET, if convenient (and in mode MODE if that's
2642 convenient). */
2644 static rtx
2645 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2647 tree fn, len, src, dst;
2649 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2650 return 0;
2652 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2653 if (!fn)
2654 return 0;
2656 src = TREE_VALUE (TREE_CHAIN (arglist));
2657 len = c_strlen (src, 1);
2658 if (len == 0 || TREE_SIDE_EFFECTS (len))
2659 return 0;
2661 dst = TREE_VALUE (arglist);
2662 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2663 arglist = build_tree_list (NULL_TREE, len);
2664 arglist = tree_cons (NULL_TREE, src, arglist);
2665 arglist = tree_cons (NULL_TREE, dst, arglist);
2666 return expand_expr (build_function_call_expr (fn, arglist),
2667 target, mode, EXPAND_NORMAL);
2670 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2671 Return 0 if we failed the caller should emit a normal call,
2672 otherwise try to get the result in TARGET, if convenient (and in
2673 mode MODE if that's convenient). */
2675 static rtx
2676 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2678 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2679 return 0;
2680 else
2682 tree dst, src, len;
2684 /* If return value is ignored, transform stpcpy into strcpy. */
2685 if (target == const0_rtx)
2687 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2688 if (!fn)
2689 return 0;
2691 return expand_expr (build_function_call_expr (fn, arglist),
2692 target, mode, EXPAND_NORMAL);
2695 /* Ensure we get an actual string whose length can be evaluated at
2696 compile-time, not an expression containing a string. This is
2697 because the latter will potentially produce pessimized code
2698 when used to produce the return value. */
2699 src = TREE_VALUE (TREE_CHAIN (arglist));
2700 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2701 return 0;
2703 dst = TREE_VALUE (arglist);
2704 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2705 arglist = build_tree_list (NULL_TREE, len);
2706 arglist = tree_cons (NULL_TREE, src, arglist);
2707 arglist = tree_cons (NULL_TREE, dst, arglist);
2708 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2712 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2713 bytes from constant string DATA + OFFSET and return it as target
2714 constant. */
2716 static rtx
2717 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2718 enum machine_mode mode)
2720 const char *str = (const char *) data;
2722 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2723 return const0_rtx;
2725 return c_readstr (str + offset, mode);
2728 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2729 if we failed the caller should emit a normal call. */
2731 static rtx
2732 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2734 if (!validate_arglist (arglist,
2735 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2736 return 0;
2737 else
2739 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2740 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2741 tree fn;
2743 /* We must be passed a constant len parameter. */
2744 if (TREE_CODE (len) != INTEGER_CST)
2745 return 0;
2747 /* If the len parameter is zero, return the dst parameter. */
2748 if (integer_zerop (len))
2750 /* Evaluate and ignore the src argument in case it has
2751 side-effects. */
2752 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2753 VOIDmode, EXPAND_NORMAL);
2754 /* Return the dst parameter. */
2755 return expand_expr (TREE_VALUE (arglist), target, mode,
2756 EXPAND_NORMAL);
2759 /* Now, we must be passed a constant src ptr parameter. */
2760 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2761 return 0;
2763 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2765 /* We're required to pad with trailing zeros if the requested
2766 len is greater than strlen(s2)+1. In that case try to
2767 use store_by_pieces, if it fails, punt. */
2768 if (tree_int_cst_lt (slen, len))
2770 tree dest = TREE_VALUE (arglist);
2771 unsigned int dest_align
2772 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2773 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2774 rtx dest_mem;
2776 if (!p || dest_align == 0 || !host_integerp (len, 1)
2777 || !can_store_by_pieces (tree_low_cst (len, 1),
2778 builtin_strncpy_read_str,
2779 (void *) p, dest_align))
2780 return 0;
2782 dest_mem = get_memory_rtx (dest);
2783 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2784 builtin_strncpy_read_str,
2785 (void *) p, dest_align, 0);
2786 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2787 #ifdef POINTERS_EXTEND_UNSIGNED
2788 if (GET_MODE (dest_mem) != ptr_mode)
2789 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2790 #endif
2791 return dest_mem;
2794 /* OK transform into builtin memcpy. */
2795 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2796 if (!fn)
2797 return 0;
2798 return expand_expr (build_function_call_expr (fn, arglist),
2799 target, mode, EXPAND_NORMAL);
2803 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2804 bytes from constant string DATA + OFFSET and return it as target
2805 constant. */
2807 static rtx
2808 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2809 enum machine_mode mode)
2811 const char *c = (const char *) data;
2812 char *p = alloca (GET_MODE_SIZE (mode));
2814 memset (p, *c, GET_MODE_SIZE (mode));
2816 return c_readstr (p, mode);
2819 /* Callback routine for store_by_pieces. Return the RTL of a register
2820 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2821 char value given in the RTL register data. For example, if mode is
2822 4 bytes wide, return the RTL for 0x01010101*data. */
2824 static rtx
2825 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2826 enum machine_mode mode)
2828 rtx target, coeff;
2829 size_t size;
2830 char *p;
2832 size = GET_MODE_SIZE (mode);
2833 if (size == 1)
2834 return (rtx) data;
2836 p = alloca (size);
2837 memset (p, 1, size);
2838 coeff = c_readstr (p, mode);
2840 target = convert_to_mode (mode, (rtx) data, 1);
2841 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2842 return force_reg (mode, target);
2845 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2846 if we failed the caller should emit a normal call, otherwise try to get
2847 the result in TARGET, if convenient (and in mode MODE if that's
2848 convenient). */
2850 static rtx
2851 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2853 if (!validate_arglist (arglist,
2854 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2855 return 0;
2856 else
2858 tree dest = TREE_VALUE (arglist);
2859 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2860 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2861 char c;
2863 unsigned int dest_align
2864 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2865 rtx dest_mem, dest_addr, len_rtx;
2867 /* If DEST is not a pointer type, don't do this
2868 operation in-line. */
2869 if (dest_align == 0)
2870 return 0;
2872 /* If the LEN parameter is zero, return DEST. */
2873 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2875 /* Evaluate and ignore VAL in case it has side-effects. */
2876 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2877 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2880 if (TREE_CODE (val) != INTEGER_CST)
2882 rtx val_rtx;
2884 if (!host_integerp (len, 1))
2885 return 0;
2887 if (optimize_size && tree_low_cst (len, 1) > 1)
2888 return 0;
2890 /* Assume that we can memset by pieces if we can store the
2891 * the coefficients by pieces (in the required modes).
2892 * We can't pass builtin_memset_gen_str as that emits RTL. */
2893 c = 1;
2894 if (!can_store_by_pieces (tree_low_cst (len, 1),
2895 builtin_memset_read_str,
2896 &c, dest_align))
2897 return 0;
2899 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
2900 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
2901 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
2902 val_rtx);
2903 dest_mem = get_memory_rtx (dest);
2904 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2905 builtin_memset_gen_str,
2906 val_rtx, dest_align, 0);
2907 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2908 #ifdef POINTERS_EXTEND_UNSIGNED
2909 if (GET_MODE (dest_mem) != ptr_mode)
2910 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2911 #endif
2912 return dest_mem;
2915 if (target_char_cast (val, &c))
2916 return 0;
2918 if (c)
2920 if (!host_integerp (len, 1))
2921 return 0;
2922 if (!can_store_by_pieces (tree_low_cst (len, 1),
2923 builtin_memset_read_str, &c,
2924 dest_align))
2925 return 0;
2927 dest_mem = get_memory_rtx (dest);
2928 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2929 builtin_memset_read_str,
2930 &c, dest_align, 0);
2931 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2932 #ifdef POINTERS_EXTEND_UNSIGNED
2933 if (GET_MODE (dest_mem) != ptr_mode)
2934 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2935 #endif
2936 return dest_mem;
2939 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2941 dest_mem = get_memory_rtx (dest);
2942 set_mem_align (dest_mem, dest_align);
2943 dest_addr = clear_storage (dest_mem, len_rtx);
2945 if (dest_addr == 0)
2947 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2948 #ifdef POINTERS_EXTEND_UNSIGNED
2949 if (GET_MODE (dest_addr) != ptr_mode)
2950 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2951 #endif
2954 return dest_addr;
2958 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2959 if we failed the caller should emit a normal call. */
2961 static rtx
2962 expand_builtin_bzero (tree arglist)
2964 tree dest, size, newarglist;
2966 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2967 return NULL_RTX;
2969 dest = TREE_VALUE (arglist);
2970 size = TREE_VALUE (TREE_CHAIN (arglist));
2972 /* New argument list transforming bzero(ptr x, int y) to
2973 memset(ptr x, int 0, size_t y). This is done this way
2974 so that if it isn't expanded inline, we fallback to
2975 calling bzero instead of memset. */
2977 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2978 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2979 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2981 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
2984 /* Expand expression EXP, which is a call to the memcmp built-in function.
2985 ARGLIST is the argument list for this call. Return 0 if we failed and the
2986 caller should emit a normal call, otherwise try to get the result in
2987 TARGET, if convenient (and in mode MODE, if that's convenient). */
2989 static rtx
2990 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
2991 enum machine_mode mode)
2993 tree arg1, arg2, len;
2994 const char *p1, *p2;
2996 if (!validate_arglist (arglist,
2997 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2998 return 0;
3000 arg1 = TREE_VALUE (arglist);
3001 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3002 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3004 /* If the len parameter is zero, return zero. */
3005 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
3007 /* Evaluate and ignore arg1 and arg2 in case they have
3008 side-effects. */
3009 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3010 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3011 return const0_rtx;
3014 p1 = c_getstr (arg1);
3015 p2 = c_getstr (arg2);
3017 /* If all arguments are constant, and the value of len is not greater
3018 than the lengths of arg1 and arg2, evaluate at compile-time. */
3019 if (host_integerp (len, 1) && p1 && p2
3020 && compare_tree_int (len, strlen (p1) + 1) <= 0
3021 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3023 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3025 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3028 /* If len parameter is one, return an expression corresponding to
3029 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3030 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
3032 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3033 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3034 tree ind1 =
3035 fold (build1 (CONVERT_EXPR, integer_type_node,
3036 build1 (INDIRECT_REF, cst_uchar_node,
3037 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3038 tree ind2 =
3039 fold (build1 (CONVERT_EXPR, integer_type_node,
3040 build1 (INDIRECT_REF, cst_uchar_node,
3041 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3042 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3043 return expand_expr (result, target, mode, EXPAND_NORMAL);
3046 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3048 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3049 rtx result;
3050 rtx insn;
3052 int arg1_align
3053 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3054 int arg2_align
3055 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3056 enum machine_mode insn_mode;
3058 #ifdef HAVE_cmpmemsi
3059 if (HAVE_cmpmemsi)
3060 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3061 else
3062 #endif
3063 #ifdef HAVE_cmpstrsi
3064 if (HAVE_cmpstrsi)
3065 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3066 else
3067 #endif
3068 return 0;
3070 /* If we don't have POINTER_TYPE, call the function. */
3071 if (arg1_align == 0 || arg2_align == 0)
3072 return 0;
3074 /* Make a place to write the result of the instruction. */
3075 result = target;
3076 if (! (result != 0
3077 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3078 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3079 result = gen_reg_rtx (insn_mode);
3081 arg1_rtx = get_memory_rtx (arg1);
3082 arg2_rtx = get_memory_rtx (arg2);
3083 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3084 #ifdef HAVE_cmpmemsi
3085 if (HAVE_cmpmemsi)
3086 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3087 GEN_INT (MIN (arg1_align, arg2_align)));
3088 else
3089 #endif
3090 #ifdef HAVE_cmpstrsi
3091 if (HAVE_cmpstrsi)
3092 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3093 GEN_INT (MIN (arg1_align, arg2_align)));
3094 else
3095 #endif
3096 abort ();
3098 if (insn)
3099 emit_insn (insn);
3100 else
3101 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3102 TYPE_MODE (integer_type_node), 3,
3103 XEXP (arg1_rtx, 0), Pmode,
3104 XEXP (arg2_rtx, 0), Pmode,
3105 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3106 TREE_UNSIGNED (sizetype)),
3107 TYPE_MODE (sizetype));
3109 /* Return the value in the proper mode for this function. */
3110 mode = TYPE_MODE (TREE_TYPE (exp));
3111 if (GET_MODE (result) == mode)
3112 return result;
3113 else if (target != 0)
3115 convert_move (target, result, 0);
3116 return target;
3118 else
3119 return convert_to_mode (mode, result, 0);
3121 #endif
3123 return 0;
3126 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3127 if we failed the caller should emit a normal call, otherwise try to get
3128 the result in TARGET, if convenient. */
3130 static rtx
3131 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3133 tree arglist = TREE_OPERAND (exp, 1);
3134 tree arg1, arg2;
3135 const char *p1, *p2;
3137 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3138 return 0;
3140 arg1 = TREE_VALUE (arglist);
3141 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3143 p1 = c_getstr (arg1);
3144 p2 = c_getstr (arg2);
3146 if (p1 && p2)
3148 const int i = strcmp (p1, p2);
3149 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3152 /* If either arg is "", return an expression corresponding to
3153 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3154 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3156 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3157 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3158 tree ind1 =
3159 fold (build1 (CONVERT_EXPR, integer_type_node,
3160 build1 (INDIRECT_REF, cst_uchar_node,
3161 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3162 tree ind2 =
3163 fold (build1 (CONVERT_EXPR, integer_type_node,
3164 build1 (INDIRECT_REF, cst_uchar_node,
3165 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3166 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3167 return expand_expr (result, target, mode, EXPAND_NORMAL);
3170 #ifdef HAVE_cmpstrsi
3171 if (HAVE_cmpstrsi)
3173 tree len, len1, len2;
3174 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3175 rtx result, insn;
3177 int arg1_align
3178 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3179 int arg2_align
3180 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3181 enum machine_mode insn_mode
3182 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3184 len1 = c_strlen (arg1, 1);
3185 len2 = c_strlen (arg2, 1);
3187 if (len1)
3188 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3189 if (len2)
3190 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3192 /* If we don't have a constant length for the first, use the length
3193 of the second, if we know it. We don't require a constant for
3194 this case; some cost analysis could be done if both are available
3195 but neither is constant. For now, assume they're equally cheap,
3196 unless one has side effects. If both strings have constant lengths,
3197 use the smaller. */
3199 if (!len1)
3200 len = len2;
3201 else if (!len2)
3202 len = len1;
3203 else if (TREE_SIDE_EFFECTS (len1))
3204 len = len2;
3205 else if (TREE_SIDE_EFFECTS (len2))
3206 len = len1;
3207 else if (TREE_CODE (len1) != INTEGER_CST)
3208 len = len2;
3209 else if (TREE_CODE (len2) != INTEGER_CST)
3210 len = len1;
3211 else if (tree_int_cst_lt (len1, len2))
3212 len = len1;
3213 else
3214 len = len2;
3216 /* If both arguments have side effects, we cannot optimize. */
3217 if (!len || TREE_SIDE_EFFECTS (len))
3218 return 0;
3220 /* If we don't have POINTER_TYPE, call the function. */
3221 if (arg1_align == 0 || arg2_align == 0)
3222 return 0;
3224 /* Make a place to write the result of the instruction. */
3225 result = target;
3226 if (! (result != 0
3227 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3228 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3229 result = gen_reg_rtx (insn_mode);
3231 arg1_rtx = get_memory_rtx (arg1);
3232 arg2_rtx = get_memory_rtx (arg2);
3233 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3234 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3235 GEN_INT (MIN (arg1_align, arg2_align)));
3236 if (!insn)
3237 return 0;
3239 emit_insn (insn);
3241 /* Return the value in the proper mode for this function. */
3242 mode = TYPE_MODE (TREE_TYPE (exp));
3243 if (GET_MODE (result) == mode)
3244 return result;
3245 if (target == 0)
3246 return convert_to_mode (mode, result, 0);
3247 convert_move (target, result, 0);
3248 return target;
3250 #endif
3251 return 0;
3254 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3255 if we failed the caller should emit a normal call, otherwise try to get
3256 the result in TARGET, if convenient. */
3258 static rtx
3259 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3261 tree arglist = TREE_OPERAND (exp, 1);
3262 tree arg1, arg2, arg3;
3263 const char *p1, *p2;
3265 if (!validate_arglist (arglist,
3266 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3267 return 0;
3269 arg1 = TREE_VALUE (arglist);
3270 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3271 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3273 /* If the len parameter is zero, return zero. */
3274 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
3276 /* Evaluate and ignore arg1 and arg2 in case they have
3277 side-effects. */
3278 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3279 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3280 return const0_rtx;
3283 p1 = c_getstr (arg1);
3284 p2 = c_getstr (arg2);
3286 /* If all arguments are constant, evaluate at compile-time. */
3287 if (host_integerp (arg3, 1) && p1 && p2)
3289 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3290 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3293 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3294 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3295 if (host_integerp (arg3, 1)
3296 && (tree_low_cst (arg3, 1) == 1
3297 || (tree_low_cst (arg3, 1) > 1
3298 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3300 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3301 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3302 tree ind1 =
3303 fold (build1 (CONVERT_EXPR, integer_type_node,
3304 build1 (INDIRECT_REF, cst_uchar_node,
3305 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3306 tree ind2 =
3307 fold (build1 (CONVERT_EXPR, integer_type_node,
3308 build1 (INDIRECT_REF, cst_uchar_node,
3309 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3310 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3311 return expand_expr (result, target, mode, EXPAND_NORMAL);
3314 /* If c_strlen can determine an expression for one of the string
3315 lengths, and it doesn't have side effects, then emit cmpstrsi
3316 using length MIN(strlen(string)+1, arg3). */
3317 #ifdef HAVE_cmpstrsi
3318 if (HAVE_cmpstrsi)
3320 tree len, len1, len2;
3321 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3322 rtx result, insn;
3324 int arg1_align
3325 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3326 int arg2_align
3327 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3328 enum machine_mode insn_mode
3329 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3331 len1 = c_strlen (arg1, 1);
3332 len2 = c_strlen (arg2, 1);
3334 if (len1)
3335 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3336 if (len2)
3337 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3339 /* If we don't have a constant length for the first, use the length
3340 of the second, if we know it. We don't require a constant for
3341 this case; some cost analysis could be done if both are available
3342 but neither is constant. For now, assume they're equally cheap,
3343 unless one has side effects. If both strings have constant lengths,
3344 use the smaller. */
3346 if (!len1)
3347 len = len2;
3348 else if (!len2)
3349 len = len1;
3350 else if (TREE_SIDE_EFFECTS (len1))
3351 len = len2;
3352 else if (TREE_SIDE_EFFECTS (len2))
3353 len = len1;
3354 else if (TREE_CODE (len1) != INTEGER_CST)
3355 len = len2;
3356 else if (TREE_CODE (len2) != INTEGER_CST)
3357 len = len1;
3358 else if (tree_int_cst_lt (len1, len2))
3359 len = len1;
3360 else
3361 len = len2;
3363 /* If both arguments have side effects, we cannot optimize. */
3364 if (!len || TREE_SIDE_EFFECTS (len))
3365 return 0;
3367 /* The actual new length parameter is MIN(len,arg3). */
3368 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3370 /* If we don't have POINTER_TYPE, call the function. */
3371 if (arg1_align == 0 || arg2_align == 0)
3372 return 0;
3374 /* Make a place to write the result of the instruction. */
3375 result = target;
3376 if (! (result != 0
3377 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3378 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3379 result = gen_reg_rtx (insn_mode);
3381 arg1_rtx = get_memory_rtx (arg1);
3382 arg2_rtx = get_memory_rtx (arg2);
3383 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3384 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3385 GEN_INT (MIN (arg1_align, arg2_align)));
3386 if (!insn)
3387 return 0;
3389 emit_insn (insn);
3391 /* Return the value in the proper mode for this function. */
3392 mode = TYPE_MODE (TREE_TYPE (exp));
3393 if (GET_MODE (result) == mode)
3394 return result;
3395 if (target == 0)
3396 return convert_to_mode (mode, result, 0);
3397 convert_move (target, result, 0);
3398 return target;
3400 #endif
3401 return 0;
3404 /* Expand expression EXP, which is a call to the strcat builtin.
3405 Return 0 if we failed the caller should emit a normal call,
3406 otherwise try to get the result in TARGET, if convenient. */
3408 static rtx
3409 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3411 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3412 return 0;
3413 else
3415 tree dst = TREE_VALUE (arglist),
3416 src = TREE_VALUE (TREE_CHAIN (arglist));
3417 const char *p = c_getstr (src);
3419 if (p)
3421 /* If the string length is zero, return the dst parameter. */
3422 if (*p == '\0')
3423 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3424 else if (!optimize_size)
3426 /* Otherwise if !optimize_size, see if we can store by
3427 pieces into (dst + strlen(dst)). */
3428 tree newdst, arglist,
3429 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3431 /* This is the length argument. */
3432 arglist = build_tree_list (NULL_TREE,
3433 fold (size_binop (PLUS_EXPR,
3434 c_strlen (src, 0),
3435 ssize_int (1))));
3436 /* Prepend src argument. */
3437 arglist = tree_cons (NULL_TREE, src, arglist);
3439 /* We're going to use dst more than once. */
3440 dst = save_expr (dst);
3442 /* Create strlen (dst). */
3443 newdst =
3444 fold (build_function_call_expr (strlen_fn,
3445 build_tree_list (NULL_TREE,
3446 dst)));
3447 /* Create (dst + strlen (dst)). */
3448 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3450 /* Prepend the new dst argument. */
3451 arglist = tree_cons (NULL_TREE, newdst, arglist);
3453 /* We don't want to get turned into a memcpy if the
3454 target is const0_rtx, i.e. when the return value
3455 isn't used. That would produce pessimized code so
3456 pass in a target of zero, it should never actually be
3457 used. If this was successful return the original
3458 dst, not the result of mempcpy. */
3459 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3460 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3461 else
3462 return 0;
3466 return 0;
3470 /* Expand expression EXP, which is a call to the strncat builtin.
3471 Return 0 if we failed the caller should emit a normal call,
3472 otherwise try to get the result in TARGET, if convenient. */
3474 static rtx
3475 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3477 if (!validate_arglist (arglist,
3478 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3479 return 0;
3480 else
3482 tree dst = TREE_VALUE (arglist),
3483 src = TREE_VALUE (TREE_CHAIN (arglist)),
3484 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3485 const char *p = c_getstr (src);
3487 /* If the requested length is zero, or the src parameter string
3488 length is zero, return the dst parameter. */
3489 if (integer_zerop (len) || (p && *p == '\0'))
3491 /* Evaluate and ignore the src and len parameters in case
3492 they have side-effects. */
3493 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3494 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3495 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3498 /* If the requested len is greater than or equal to the string
3499 length, call strcat. */
3500 if (TREE_CODE (len) == INTEGER_CST && p
3501 && compare_tree_int (len, strlen (p)) >= 0)
3503 tree newarglist
3504 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3505 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3507 /* If the replacement _DECL isn't initialized, don't do the
3508 transformation. */
3509 if (!fn)
3510 return 0;
3512 return expand_expr (build_function_call_expr (fn, newarglist),
3513 target, mode, EXPAND_NORMAL);
3515 return 0;
3519 /* Expand expression EXP, which is a call to the strspn builtin.
3520 Return 0 if we failed the caller should emit a normal call,
3521 otherwise try to get the result in TARGET, if convenient. */
3523 static rtx
3524 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3526 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3527 return 0;
3528 else
3530 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3531 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3533 /* If both arguments are constants, evaluate at compile-time. */
3534 if (p1 && p2)
3536 const size_t r = strspn (p1, p2);
3537 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3540 /* If either argument is "", return 0. */
3541 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3543 /* Evaluate and ignore both arguments in case either one has
3544 side-effects. */
3545 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3546 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3547 return const0_rtx;
3549 return 0;
3553 /* Expand expression EXP, which is a call to the strcspn builtin.
3554 Return 0 if we failed the caller should emit a normal call,
3555 otherwise try to get the result in TARGET, if convenient. */
3557 static rtx
3558 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3560 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3561 return 0;
3562 else
3564 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3565 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3567 /* If both arguments are constants, evaluate at compile-time. */
3568 if (p1 && p2)
3570 const size_t r = strcspn (p1, p2);
3571 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3574 /* If the first argument is "", return 0. */
3575 if (p1 && *p1 == '\0')
3577 /* Evaluate and ignore argument s2 in case it has
3578 side-effects. */
3579 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3580 return const0_rtx;
3583 /* If the second argument is "", return __builtin_strlen(s1). */
3584 if (p2 && *p2 == '\0')
3586 tree newarglist = build_tree_list (NULL_TREE, s1),
3587 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3589 /* If the replacement _DECL isn't initialized, don't do the
3590 transformation. */
3591 if (!fn)
3592 return 0;
3594 return expand_expr (build_function_call_expr (fn, newarglist),
3595 target, mode, EXPAND_NORMAL);
3597 return 0;
3601 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3602 if that's convenient. */
3605 expand_builtin_saveregs (void)
3607 rtx val, seq;
3609 /* Don't do __builtin_saveregs more than once in a function.
3610 Save the result of the first call and reuse it. */
3611 if (saveregs_value != 0)
3612 return saveregs_value;
3614 /* When this function is called, it means that registers must be
3615 saved on entry to this function. So we migrate the call to the
3616 first insn of this function. */
3618 start_sequence ();
3620 #ifdef EXPAND_BUILTIN_SAVEREGS
3621 /* Do whatever the machine needs done in this case. */
3622 val = EXPAND_BUILTIN_SAVEREGS ();
3623 #else
3624 /* ??? We used to try and build up a call to the out of line function,
3625 guessing about what registers needed saving etc. This became much
3626 harder with __builtin_va_start, since we don't have a tree for a
3627 call to __builtin_saveregs to fall back on. There was exactly one
3628 port (i860) that used this code, and I'm unconvinced it could actually
3629 handle the general case. So we no longer try to handle anything
3630 weird and make the backend absorb the evil. */
3632 error ("__builtin_saveregs not supported by this target");
3633 val = const0_rtx;
3634 #endif
3636 seq = get_insns ();
3637 end_sequence ();
3639 saveregs_value = val;
3641 /* Put the insns after the NOTE that starts the function. If this
3642 is inside a start_sequence, make the outer-level insn chain current, so
3643 the code is placed at the start of the function. */
3644 push_topmost_sequence ();
3645 emit_insn_after (seq, get_insns ());
3646 pop_topmost_sequence ();
3648 return val;
3651 /* __builtin_args_info (N) returns word N of the arg space info
3652 for the current function. The number and meanings of words
3653 is controlled by the definition of CUMULATIVE_ARGS. */
3655 static rtx
3656 expand_builtin_args_info (tree arglist)
3658 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3659 int *word_ptr = (int *) &current_function_args_info;
3661 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3662 abort ();
3664 if (arglist != 0)
3666 if (!host_integerp (TREE_VALUE (arglist), 0))
3667 error ("argument of `__builtin_args_info' must be constant");
3668 else
3670 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3672 if (wordnum < 0 || wordnum >= nwords)
3673 error ("argument of `__builtin_args_info' out of range");
3674 else
3675 return GEN_INT (word_ptr[wordnum]);
3678 else
3679 error ("missing argument in `__builtin_args_info'");
3681 return const0_rtx;
3684 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3686 static rtx
3687 expand_builtin_next_arg (tree arglist)
3689 tree fntype = TREE_TYPE (current_function_decl);
3691 if (TYPE_ARG_TYPES (fntype) == 0
3692 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3693 == void_type_node))
3695 error ("`va_start' used in function with fixed args");
3696 return const0_rtx;
3699 if (arglist)
3701 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3702 tree arg = TREE_VALUE (arglist);
3704 /* Strip off all nops for the sake of the comparison. This
3705 is not quite the same as STRIP_NOPS. It does more.
3706 We must also strip off INDIRECT_EXPR for C++ reference
3707 parameters. */
3708 while (TREE_CODE (arg) == NOP_EXPR
3709 || TREE_CODE (arg) == CONVERT_EXPR
3710 || TREE_CODE (arg) == NON_LVALUE_EXPR
3711 || TREE_CODE (arg) == INDIRECT_REF)
3712 arg = TREE_OPERAND (arg, 0);
3713 if (arg != last_parm)
3714 warning ("second parameter of `va_start' not last named argument");
3716 else
3717 /* Evidently an out of date version of <stdarg.h>; can't validate
3718 va_start's second argument, but can still work as intended. */
3719 warning ("`__builtin_next_arg' called without an argument");
3721 return expand_binop (Pmode, add_optab,
3722 current_function_internal_arg_pointer,
3723 current_function_arg_offset_rtx,
3724 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3727 /* Make it easier for the backends by protecting the valist argument
3728 from multiple evaluations. */
3730 static tree
3731 stabilize_va_list (tree valist, int needs_lvalue)
3733 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3735 if (TREE_SIDE_EFFECTS (valist))
3736 valist = save_expr (valist);
3738 /* For this case, the backends will be expecting a pointer to
3739 TREE_TYPE (va_list_type_node), but it's possible we've
3740 actually been given an array (an actual va_list_type_node).
3741 So fix it. */
3742 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3744 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3745 tree p2 = build_pointer_type (va_list_type_node);
3747 valist = build1 (ADDR_EXPR, p2, valist);
3748 valist = fold (build1 (NOP_EXPR, p1, valist));
3751 else
3753 tree pt;
3755 if (! needs_lvalue)
3757 if (! TREE_SIDE_EFFECTS (valist))
3758 return valist;
3760 pt = build_pointer_type (va_list_type_node);
3761 valist = fold (build1 (ADDR_EXPR, pt, valist));
3762 TREE_SIDE_EFFECTS (valist) = 1;
3765 if (TREE_SIDE_EFFECTS (valist))
3766 valist = save_expr (valist);
3767 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3768 valist));
3771 return valist;
3774 /* The "standard" implementation of va_start: just assign `nextarg' to
3775 the variable. */
3777 void
3778 std_expand_builtin_va_start (tree valist, rtx nextarg)
3780 tree t;
3782 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3783 make_tree (ptr_type_node, nextarg));
3784 TREE_SIDE_EFFECTS (t) = 1;
3786 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3789 /* Expand ARGLIST, from a call to __builtin_va_start. */
3791 static rtx
3792 expand_builtin_va_start (tree arglist)
3794 rtx nextarg;
3795 tree chain, valist;
3797 chain = TREE_CHAIN (arglist);
3799 if (TREE_CHAIN (chain))
3800 error ("too many arguments to function `va_start'");
3802 nextarg = expand_builtin_next_arg (chain);
3803 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3805 #ifdef EXPAND_BUILTIN_VA_START
3806 EXPAND_BUILTIN_VA_START (valist, nextarg);
3807 #else
3808 std_expand_builtin_va_start (valist, nextarg);
3809 #endif
3811 return const0_rtx;
3814 /* The "standard" implementation of va_arg: read the value from the
3815 current (padded) address and increment by the (padded) size. */
3818 std_expand_builtin_va_arg (tree valist, tree type)
3820 tree addr_tree, t, type_size = NULL;
3821 tree align, alignm1;
3822 tree rounded_size;
3823 rtx addr;
3825 /* Compute the rounded size of the type. */
3826 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3827 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3828 if (type == error_mark_node
3829 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3830 || TREE_OVERFLOW (type_size))
3831 rounded_size = size_zero_node;
3832 else
3833 rounded_size = fold (build (MULT_EXPR, sizetype,
3834 fold (build (TRUNC_DIV_EXPR, sizetype,
3835 fold (build (PLUS_EXPR, sizetype,
3836 type_size, alignm1)),
3837 align)),
3838 align));
3840 /* Get AP. */
3841 addr_tree = valist;
3842 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3844 /* Small args are padded downward. */
3845 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3846 fold (build (COND_EXPR, sizetype,
3847 fold (build (GT_EXPR, sizetype,
3848 rounded_size,
3849 align)),
3850 size_zero_node,
3851 fold (build (MINUS_EXPR, sizetype,
3852 rounded_size,
3853 type_size))))));
3856 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3857 addr = copy_to_reg (addr);
3859 /* Compute new value for AP. */
3860 if (! integer_zerop (rounded_size))
3862 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3863 build (PLUS_EXPR, TREE_TYPE (valist), valist,
3864 rounded_size));
3865 TREE_SIDE_EFFECTS (t) = 1;
3866 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3869 return addr;
3872 /* Expand __builtin_va_arg, which is not really a builtin function, but
3873 a very special sort of operator. */
3876 expand_builtin_va_arg (tree valist, tree type)
3878 rtx addr, result;
3879 tree promoted_type, want_va_type, have_va_type;
3881 /* Verify that valist is of the proper type. */
3883 want_va_type = va_list_type_node;
3884 have_va_type = TREE_TYPE (valist);
3885 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3887 /* If va_list is an array type, the argument may have decayed
3888 to a pointer type, e.g. by being passed to another function.
3889 In that case, unwrap both types so that we can compare the
3890 underlying records. */
3891 if (TREE_CODE (have_va_type) == ARRAY_TYPE
3892 || TREE_CODE (have_va_type) == POINTER_TYPE)
3894 want_va_type = TREE_TYPE (want_va_type);
3895 have_va_type = TREE_TYPE (have_va_type);
3898 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3900 error ("first argument to `va_arg' not of type `va_list'");
3901 addr = const0_rtx;
3904 /* Generate a diagnostic for requesting data of a type that cannot
3905 be passed through `...' due to type promotion at the call site. */
3906 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3907 != type)
3909 const char *name = "<anonymous type>", *pname = 0;
3910 static bool gave_help;
3912 if (TYPE_NAME (type))
3914 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3915 name = IDENTIFIER_POINTER (TYPE_NAME (type));
3916 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3917 && DECL_NAME (TYPE_NAME (type)))
3918 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3920 if (TYPE_NAME (promoted_type))
3922 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3923 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3924 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3925 && DECL_NAME (TYPE_NAME (promoted_type)))
3926 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3929 /* Unfortunately, this is merely undefined, rather than a constraint
3930 violation, so we cannot make this an error. If this call is never
3931 executed, the program is still strictly conforming. */
3932 warning ("`%s' is promoted to `%s' when passed through `...'",
3933 name, pname);
3934 if (! gave_help)
3936 gave_help = true;
3937 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3938 pname, name);
3941 /* We can, however, treat "undefined" any way we please.
3942 Call abort to encourage the user to fix the program. */
3943 expand_builtin_trap ();
3945 /* This is dead code, but go ahead and finish so that the
3946 mode of the result comes out right. */
3947 addr = const0_rtx;
3949 else
3951 /* Make it easier for the backends by protecting the valist argument
3952 from multiple evaluations. */
3953 valist = stabilize_va_list (valist, 0);
3955 #ifdef EXPAND_BUILTIN_VA_ARG
3956 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
3957 #else
3958 addr = std_expand_builtin_va_arg (valist, type);
3959 #endif
3962 #ifdef POINTERS_EXTEND_UNSIGNED
3963 if (GET_MODE (addr) != Pmode)
3964 addr = convert_memory_address (Pmode, addr);
3965 #endif
3967 result = gen_rtx_MEM (TYPE_MODE (type), addr);
3968 set_mem_alias_set (result, get_varargs_alias_set ());
3970 return result;
3973 /* Expand ARGLIST, from a call to __builtin_va_end. */
3975 static rtx
3976 expand_builtin_va_end (tree arglist)
3978 tree valist = TREE_VALUE (arglist);
3980 #ifdef EXPAND_BUILTIN_VA_END
3981 valist = stabilize_va_list (valist, 0);
3982 EXPAND_BUILTIN_VA_END (arglist);
3983 #else
3984 /* Evaluate for side effects, if needed. I hate macros that don't
3985 do that. */
3986 if (TREE_SIDE_EFFECTS (valist))
3987 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
3988 #endif
3990 return const0_rtx;
3993 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3994 builtin rather than just as an assignment in stdarg.h because of the
3995 nastiness of array-type va_list types. */
3997 static rtx
3998 expand_builtin_va_copy (tree arglist)
4000 tree dst, src, t;
4002 dst = TREE_VALUE (arglist);
4003 src = TREE_VALUE (TREE_CHAIN (arglist));
4005 dst = stabilize_va_list (dst, 1);
4006 src = stabilize_va_list (src, 0);
4008 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4010 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4011 TREE_SIDE_EFFECTS (t) = 1;
4012 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4014 else
4016 rtx dstb, srcb, size;
4018 /* Evaluate to pointers. */
4019 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4020 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4021 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4022 VOIDmode, EXPAND_NORMAL);
4024 #ifdef POINTERS_EXTEND_UNSIGNED
4025 if (GET_MODE (dstb) != Pmode)
4026 dstb = convert_memory_address (Pmode, dstb);
4028 if (GET_MODE (srcb) != Pmode)
4029 srcb = convert_memory_address (Pmode, srcb);
4030 #endif
4032 /* "Dereference" to BLKmode memories. */
4033 dstb = gen_rtx_MEM (BLKmode, dstb);
4034 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4035 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4036 srcb = gen_rtx_MEM (BLKmode, srcb);
4037 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4038 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4040 /* Copy. */
4041 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4044 return const0_rtx;
4047 /* Expand a call to one of the builtin functions __builtin_frame_address or
4048 __builtin_return_address. */
4050 static rtx
4051 expand_builtin_frame_address (tree fndecl, tree arglist)
4053 /* The argument must be a nonnegative integer constant.
4054 It counts the number of frames to scan up the stack.
4055 The value is the return address saved in that frame. */
4056 if (arglist == 0)
4057 /* Warning about missing arg was already issued. */
4058 return const0_rtx;
4059 else if (! host_integerp (TREE_VALUE (arglist), 1))
4061 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4062 error ("invalid arg to `__builtin_frame_address'");
4063 else
4064 error ("invalid arg to `__builtin_return_address'");
4065 return const0_rtx;
4067 else
4069 rtx tem
4070 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4071 tree_low_cst (TREE_VALUE (arglist), 1),
4072 hard_frame_pointer_rtx);
4074 /* Some ports cannot access arbitrary stack frames. */
4075 if (tem == NULL)
4077 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4078 warning ("unsupported arg to `__builtin_frame_address'");
4079 else
4080 warning ("unsupported arg to `__builtin_return_address'");
4081 return const0_rtx;
4084 /* For __builtin_frame_address, return what we've got. */
4085 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4086 return tem;
4088 if (GET_CODE (tem) != REG
4089 && ! CONSTANT_P (tem))
4090 tem = copy_to_mode_reg (Pmode, tem);
4091 return tem;
4095 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4096 we failed and the caller should emit a normal call, otherwise try to get
4097 the result in TARGET, if convenient. */
4099 static rtx
4100 expand_builtin_alloca (tree arglist, rtx target)
4102 rtx op0;
4103 rtx result;
4105 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4106 return 0;
4108 /* Compute the argument. */
4109 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4111 /* Allocate the desired space. */
4112 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4114 #ifdef POINTERS_EXTEND_UNSIGNED
4115 if (GET_MODE (result) != ptr_mode)
4116 result = convert_memory_address (ptr_mode, result);
4117 #endif
4119 return result;
4122 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4123 Return 0 if a normal call should be emitted rather than expanding the
4124 function in-line. If convenient, the result should be placed in TARGET.
4125 SUBTARGET may be used as the target for computing one of EXP's operands. */
4127 static rtx
4128 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4129 rtx subtarget, optab op_optab)
4131 rtx op0;
4132 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4133 return 0;
4135 /* Compute the argument. */
4136 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4137 /* Compute op, into TARGET if possible.
4138 Set TARGET to wherever the result comes back. */
4139 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4140 op_optab, op0, target, 1);
4141 if (target == 0)
4142 abort ();
4144 return convert_to_mode (target_mode, target, 0);
4147 /* If the string passed to fputs is a constant and is one character
4148 long, we attempt to transform this call into __builtin_fputc(). */
4150 static rtx
4151 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4153 tree len, fn;
4154 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4155 : implicit_built_in_decls[BUILT_IN_FPUTC];
4156 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4157 : implicit_built_in_decls[BUILT_IN_FWRITE];
4159 /* If the return value is used, or the replacement _DECL isn't
4160 initialized, don't do the transformation. */
4161 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4162 return 0;
4164 /* Verify the arguments in the original call. */
4165 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4166 return 0;
4168 /* Get the length of the string passed to fputs. If the length
4169 can't be determined, punt. */
4170 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4171 || TREE_CODE (len) != INTEGER_CST)
4172 return 0;
4174 switch (compare_tree_int (len, 1))
4176 case -1: /* length is 0, delete the call entirely . */
4178 /* Evaluate and ignore the argument in case it has
4179 side-effects. */
4180 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4181 VOIDmode, EXPAND_NORMAL);
4182 return const0_rtx;
4184 case 0: /* length is 1, call fputc. */
4186 const char *p = c_getstr (TREE_VALUE (arglist));
4188 if (p != NULL)
4190 /* New argument list transforming fputs(string, stream) to
4191 fputc(string[0], stream). */
4192 arglist =
4193 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4194 arglist =
4195 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4196 fn = fn_fputc;
4197 break;
4200 /* FALLTHROUGH */
4201 case 1: /* length is greater than 1, call fwrite. */
4203 tree string_arg;
4205 /* If optimizing for size keep fputs. */
4206 if (optimize_size)
4207 return 0;
4208 string_arg = TREE_VALUE (arglist);
4209 /* New argument list transforming fputs(string, stream) to
4210 fwrite(string, 1, len, stream). */
4211 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4212 arglist = tree_cons (NULL_TREE, len, arglist);
4213 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4214 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4215 fn = fn_fwrite;
4216 break;
4218 default:
4219 abort ();
4222 return expand_expr (build_function_call_expr (fn, arglist),
4223 const0_rtx, VOIDmode, EXPAND_NORMAL);
4226 /* Expand a call to __builtin_expect. We return our argument and emit a
4227 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4228 a non-jump context. */
4230 static rtx
4231 expand_builtin_expect (tree arglist, rtx target)
4233 tree exp, c;
4234 rtx note, rtx_c;
4236 if (arglist == NULL_TREE
4237 || TREE_CHAIN (arglist) == NULL_TREE)
4238 return const0_rtx;
4239 exp = TREE_VALUE (arglist);
4240 c = TREE_VALUE (TREE_CHAIN (arglist));
4242 if (TREE_CODE (c) != INTEGER_CST)
4244 error ("second arg to `__builtin_expect' must be a constant");
4245 c = integer_zero_node;
4248 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4250 /* Don't bother with expected value notes for integral constants. */
4251 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4253 /* We do need to force this into a register so that we can be
4254 moderately sure to be able to correctly interpret the branch
4255 condition later. */
4256 target = force_reg (GET_MODE (target), target);
4258 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4260 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4261 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4264 return target;
4267 /* Like expand_builtin_expect, except do this in a jump context. This is
4268 called from do_jump if the conditional is a __builtin_expect. Return either
4269 a list of insns to emit the jump or NULL if we cannot optimize
4270 __builtin_expect. We need to optimize this at jump time so that machines
4271 like the PowerPC don't turn the test into a SCC operation, and then jump
4272 based on the test being 0/1. */
4275 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4277 tree arglist = TREE_OPERAND (exp, 1);
4278 tree arg0 = TREE_VALUE (arglist);
4279 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4280 rtx ret = NULL_RTX;
4282 /* Only handle __builtin_expect (test, 0) and
4283 __builtin_expect (test, 1). */
4284 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4285 && (integer_zerop (arg1) || integer_onep (arg1)))
4287 int num_jumps = 0;
4288 rtx insn;
4290 /* If we fail to locate an appropriate conditional jump, we'll
4291 fall back to normal evaluation. Ensure that the expression
4292 can be re-evaluated. */
4293 switch (unsafe_for_reeval (arg0))
4295 case 0: /* Safe. */
4296 break;
4298 case 1: /* Mildly unsafe. */
4299 arg0 = unsave_expr (arg0);
4300 break;
4302 case 2: /* Wildly unsafe. */
4303 return NULL_RTX;
4306 /* Expand the jump insns. */
4307 start_sequence ();
4308 do_jump (arg0, if_false_label, if_true_label);
4309 ret = get_insns ();
4310 end_sequence ();
4312 /* Now that the __builtin_expect has been validated, go through and add
4313 the expect's to each of the conditional jumps. If we run into an
4314 error, just give up and generate the 'safe' code of doing a SCC
4315 operation and then doing a branch on that. */
4316 insn = ret;
4317 while (insn != NULL_RTX)
4319 rtx next = NEXT_INSN (insn);
4321 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4323 rtx ifelse = SET_SRC (pc_set (insn));
4324 rtx label;
4325 int taken;
4327 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4329 taken = 1;
4330 label = XEXP (XEXP (ifelse, 1), 0);
4332 /* An inverted jump reverses the probabilities. */
4333 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4335 taken = 0;
4336 label = XEXP (XEXP (ifelse, 2), 0);
4338 /* We shouldn't have to worry about conditional returns during
4339 the expansion stage, but handle it gracefully anyway. */
4340 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4342 taken = 1;
4343 label = NULL_RTX;
4345 /* An inverted return reverses the probabilities. */
4346 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4348 taken = 0;
4349 label = NULL_RTX;
4351 else
4352 goto do_next_insn;
4354 /* If the test is expected to fail, reverse the
4355 probabilities. */
4356 if (integer_zerop (arg1))
4357 taken = 1 - taken;
4359 /* If we are jumping to the false label, reverse the
4360 probabilities. */
4361 if (label == NULL_RTX)
4362 ; /* conditional return */
4363 else if (label == if_false_label)
4364 taken = 1 - taken;
4365 else if (label != if_true_label)
4366 goto do_next_insn;
4368 num_jumps++;
4369 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4372 do_next_insn:
4373 insn = next;
4376 /* If no jumps were modified, fail and do __builtin_expect the normal
4377 way. */
4378 if (num_jumps == 0)
4379 ret = NULL_RTX;
4382 return ret;
4385 void
4386 expand_builtin_trap (void)
4388 #ifdef HAVE_trap
4389 if (HAVE_trap)
4390 emit_insn (gen_trap ());
4391 else
4392 #endif
4393 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4394 emit_barrier ();
4397 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4398 Return 0 if a normal call should be emitted rather than expanding
4399 the function inline. If convenient, the result should be placed
4400 in TARGET. SUBTARGET may be used as the target for computing
4401 the operand. */
4403 static rtx
4404 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4406 enum machine_mode mode;
4407 tree arg;
4408 rtx op0;
4410 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4411 return 0;
4413 arg = TREE_VALUE (arglist);
4414 mode = TYPE_MODE (TREE_TYPE (arg));
4415 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4416 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4419 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4420 Return 0 if a normal call should be emitted rather than expanding
4421 the function inline. If convenient, the result should be placed
4422 in target. */
4424 static rtx
4425 expand_builtin_cabs (tree arglist, rtx target)
4427 enum machine_mode mode;
4428 tree arg;
4429 rtx op0;
4431 if (arglist == 0 || TREE_CHAIN (arglist))
4432 return 0;
4433 arg = TREE_VALUE (arglist);
4434 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4435 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4436 return 0;
4438 mode = TYPE_MODE (TREE_TYPE (arg));
4439 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4440 return expand_complex_abs (mode, op0, target, 0);
4443 /* Create a new constant string literal and return a char* pointer to it.
4444 The STRING_CST value is the LEN characters at STR. */
4445 static tree
4446 build_string_literal (int len, const char *str)
4448 tree t, elem, index, type;
4450 t = build_string (len, str);
4451 elem = build_type_variant (char_type_node, 1, 0);
4452 index = build_index_type (build_int_2 (len - 1, 0));
4453 type = build_array_type (elem, index);
4454 TREE_TYPE (t) = type;
4455 TREE_CONSTANT (t) = 1;
4456 TREE_READONLY (t) = 1;
4457 TREE_STATIC (t) = 1;
4459 type = build_pointer_type (type);
4460 t = build1 (ADDR_EXPR, type, t);
4462 type = build_pointer_type (elem);
4463 t = build1 (NOP_EXPR, type, t);
4464 return t;
4467 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4468 Return 0 if a normal call should be emitted rather than transforming
4469 the function inline. If convenient, the result should be placed in
4470 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4471 call. */
4472 static rtx
4473 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4474 bool unlocked)
4476 tree fn_putchar = unlocked
4477 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4478 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4479 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4480 : implicit_built_in_decls[BUILT_IN_PUTS];
4481 const char *fmt_str;
4482 tree fn, fmt, arg;
4484 /* If the return value is used, don't do the transformation. */
4485 if (target != const0_rtx)
4486 return 0;
4488 /* Verify the required arguments in the original call. */
4489 if (! arglist)
4490 return 0;
4491 fmt = TREE_VALUE (arglist);
4492 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4493 return 0;
4494 arglist = TREE_CHAIN (arglist);
4496 /* Check whether the format is a literal string constant. */
4497 fmt_str = c_getstr (fmt);
4498 if (fmt_str == NULL)
4499 return 0;
4501 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4502 if (strcmp (fmt_str, "%s\n") == 0)
4504 if (! arglist
4505 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4506 || TREE_CHAIN (arglist))
4507 return 0;
4508 fn = fn_puts;
4510 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4511 else if (strcmp (fmt_str, "%c") == 0)
4513 if (! arglist
4514 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4515 || TREE_CHAIN (arglist))
4516 return 0;
4517 fn = fn_putchar;
4519 else
4521 /* We can't handle anything else with % args or %% ... yet. */
4522 if (strchr (fmt_str, '%'))
4523 return 0;
4525 if (arglist)
4526 return 0;
4528 /* If the format specifier was "", printf does nothing. */
4529 if (fmt_str[0] == '\0')
4530 return const0_rtx;
4531 /* If the format specifier has length of 1, call putchar. */
4532 if (fmt_str[1] == '\0')
4534 /* Given printf("c"), (where c is any one character,)
4535 convert "c"[0] to an int and pass that to the replacement
4536 function. */
4537 arg = build_int_2 (fmt_str[0], 0);
4538 arglist = build_tree_list (NULL_TREE, arg);
4539 fn = fn_putchar;
4541 else
4543 /* If the format specifier was "string\n", call puts("string"). */
4544 size_t len = strlen (fmt_str);
4545 if (fmt_str[len - 1] == '\n')
4547 /* Create a NUL-terminalted string that's one char shorter
4548 than the original, stripping off the trailing '\n'. */
4549 char *newstr = (char *) alloca (len);
4550 memcpy (newstr, fmt_str, len - 1);
4551 newstr[len - 1] = 0;
4553 arg = build_string_literal (len, newstr);
4554 arglist = build_tree_list (NULL_TREE, arg);
4555 fn = fn_puts;
4557 else
4558 /* We'd like to arrange to call fputs(string,stdout) here,
4559 but we need stdout and don't have a way to get it yet. */
4560 return 0;
4564 if (!fn)
4565 return 0;
4566 return expand_expr (build_function_call_expr (fn, arglist),
4567 target, mode, EXPAND_NORMAL);
4570 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4571 Return 0 if a normal call should be emitted rather than transforming
4572 the function inline. If convenient, the result should be placed in
4573 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4574 call. */
4575 static rtx
4576 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4577 bool unlocked)
4579 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4580 : implicit_built_in_decls[BUILT_IN_FPUTC];
4581 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4582 : implicit_built_in_decls[BUILT_IN_FPUTS];
4583 const char *fmt_str;
4584 tree fn, fmt, fp, arg;
4586 /* If the return value is used, don't do the transformation. */
4587 if (target != const0_rtx)
4588 return 0;
4590 /* Verify the required arguments in the original call. */
4591 if (! arglist)
4592 return 0;
4593 fp = TREE_VALUE (arglist);
4594 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4595 return 0;
4596 arglist = TREE_CHAIN (arglist);
4597 if (! arglist)
4598 return 0;
4599 fmt = TREE_VALUE (arglist);
4600 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4601 return 0;
4602 arglist = TREE_CHAIN (arglist);
4604 /* Check whether the format is a literal string constant. */
4605 fmt_str = c_getstr (fmt);
4606 if (fmt_str == NULL)
4607 return 0;
4609 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4610 if (strcmp (fmt_str, "%s") == 0)
4612 if (! arglist
4613 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4614 || TREE_CHAIN (arglist))
4615 return 0;
4616 arg = TREE_VALUE (arglist);
4617 arglist = build_tree_list (NULL_TREE, fp);
4618 arglist = tree_cons (NULL_TREE, arg, arglist);
4619 fn = fn_fputs;
4621 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4622 else if (strcmp (fmt_str, "%c") == 0)
4624 if (! arglist
4625 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4626 || TREE_CHAIN (arglist))
4627 return 0;
4628 arg = TREE_VALUE (arglist);
4629 arglist = build_tree_list (NULL_TREE, fp);
4630 arglist = tree_cons (NULL_TREE, arg, arglist);
4631 fn = fn_fputc;
4633 else
4635 /* We can't handle anything else with % args or %% ... yet. */
4636 if (strchr (fmt_str, '%'))
4637 return 0;
4639 if (arglist)
4640 return 0;
4642 /* If the format specifier was "", fprintf does nothing. */
4643 if (fmt_str[0] == '\0')
4645 /* Evaluate and ignore FILE* argument for side-effects. */
4646 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4647 return const0_rtx;
4650 /* When "string" doesn't contain %, replace all cases of
4651 fprintf(stream,string) with fputs(string,stream). The fputs
4652 builtin will take care of special cases like length == 1. */
4653 arglist = build_tree_list (NULL_TREE, fp);
4654 arglist = tree_cons (NULL_TREE, fmt, arglist);
4655 fn = fn_fputs;
4658 if (!fn)
4659 return 0;
4660 return expand_expr (build_function_call_expr (fn, arglist),
4661 target, mode, EXPAND_NORMAL);
4664 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4665 a normal call should be emitted rather than expanding the function
4666 inline. If convenient, the result should be placed in TARGET with
4667 mode MODE. */
4669 static rtx
4670 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4672 tree orig_arglist, dest, fmt;
4673 const char *fmt_str;
4675 orig_arglist = arglist;
4677 /* Verify the required arguments in the original call. */
4678 if (! arglist)
4679 return 0;
4680 dest = TREE_VALUE (arglist);
4681 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4682 return 0;
4683 arglist = TREE_CHAIN (arglist);
4684 if (! arglist)
4685 return 0;
4686 fmt = TREE_VALUE (arglist);
4687 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4688 return 0;
4689 arglist = TREE_CHAIN (arglist);
4691 /* Check whether the format is a literal string constant. */
4692 fmt_str = c_getstr (fmt);
4693 if (fmt_str == NULL)
4694 return 0;
4696 /* If the format doesn't contain % args or %%, use strcpy. */
4697 if (strchr (fmt_str, '%') == 0)
4699 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4700 tree exp;
4702 if (arglist || ! fn)
4703 return 0;
4704 expand_expr (build_function_call_expr (fn, orig_arglist),
4705 const0_rtx, VOIDmode, EXPAND_NORMAL);
4706 if (target == const0_rtx)
4707 return const0_rtx;
4708 exp = build_int_2 (strlen (fmt_str), 0);
4709 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4710 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4712 /* If the format is "%s", use strcpy if the result isn't used. */
4713 else if (strcmp (fmt_str, "%s") == 0)
4715 tree fn, arg, len;
4716 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4718 if (! fn)
4719 return 0;
4721 if (! arglist || TREE_CHAIN (arglist))
4722 return 0;
4723 arg = TREE_VALUE (arglist);
4724 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4725 return 0;
4727 if (target != const0_rtx)
4729 len = c_strlen (arg, 1);
4730 if (! len || TREE_CODE (len) != INTEGER_CST)
4731 return 0;
4733 else
4734 len = NULL_TREE;
4736 arglist = build_tree_list (NULL_TREE, arg);
4737 arglist = tree_cons (NULL_TREE, dest, arglist);
4738 expand_expr (build_function_call_expr (fn, arglist),
4739 const0_rtx, VOIDmode, EXPAND_NORMAL);
4741 if (target == const0_rtx)
4742 return const0_rtx;
4743 return expand_expr (len, target, mode, EXPAND_NORMAL);
4746 return 0;
4749 /* Expand an expression EXP that calls a built-in function,
4750 with result going to TARGET if that's convenient
4751 (and in mode MODE if that's convenient).
4752 SUBTARGET may be used as the target for computing one of EXP's operands.
4753 IGNORE is nonzero if the value is to be ignored. */
4756 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4757 int ignore)
4759 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4760 tree arglist = TREE_OPERAND (exp, 1);
4761 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4762 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4764 /* Perform postincrements before expanding builtin functions. */
4765 emit_queue ();
4767 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4768 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4770 /* When not optimizing, generate calls to library functions for a certain
4771 set of builtins. */
4772 if (!optimize
4773 && !CALLED_AS_BUILT_IN (fndecl)
4774 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
4775 && fcode != BUILT_IN_ALLOCA)
4776 return expand_call (exp, target, ignore);
4778 /* The built-in function expanders test for target == const0_rtx
4779 to determine whether the function's result will be ignored. */
4780 if (ignore)
4781 target = const0_rtx;
4783 /* If the result of a pure or const built-in function is ignored, and
4784 none of its arguments are volatile, we can avoid expanding the
4785 built-in call and just evaluate the arguments for side-effects. */
4786 if (target == const0_rtx
4787 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4789 bool volatilep = false;
4790 tree arg;
4792 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4793 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4795 volatilep = true;
4796 break;
4799 if (! volatilep)
4801 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4802 expand_expr (TREE_VALUE (arg), const0_rtx,
4803 VOIDmode, EXPAND_NORMAL);
4804 return const0_rtx;
4808 switch (fcode)
4810 case BUILT_IN_ABS:
4811 case BUILT_IN_LABS:
4812 case BUILT_IN_LLABS:
4813 case BUILT_IN_IMAXABS:
4814 /* build_function_call changes these into ABS_EXPR. */
4815 abort ();
4817 case BUILT_IN_FABS:
4818 case BUILT_IN_FABSF:
4819 case BUILT_IN_FABSL:
4820 target = expand_builtin_fabs (arglist, target, subtarget);
4821 if (target)
4822 return target;
4823 break;
4825 case BUILT_IN_CABS:
4826 case BUILT_IN_CABSF:
4827 case BUILT_IN_CABSL:
4828 if (flag_unsafe_math_optimizations)
4830 target = expand_builtin_cabs (arglist, target);
4831 if (target)
4832 return target;
4834 break;
4836 case BUILT_IN_CONJ:
4837 case BUILT_IN_CONJF:
4838 case BUILT_IN_CONJL:
4839 case BUILT_IN_CREAL:
4840 case BUILT_IN_CREALF:
4841 case BUILT_IN_CREALL:
4842 case BUILT_IN_CIMAG:
4843 case BUILT_IN_CIMAGF:
4844 case BUILT_IN_CIMAGL:
4845 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4846 and IMAGPART_EXPR. */
4847 abort ();
4849 case BUILT_IN_SIN:
4850 case BUILT_IN_SINF:
4851 case BUILT_IN_SINL:
4852 case BUILT_IN_COS:
4853 case BUILT_IN_COSF:
4854 case BUILT_IN_COSL:
4855 case BUILT_IN_EXP:
4856 case BUILT_IN_EXPF:
4857 case BUILT_IN_EXPL:
4858 case BUILT_IN_LOG:
4859 case BUILT_IN_LOGF:
4860 case BUILT_IN_LOGL:
4861 case BUILT_IN_TAN:
4862 case BUILT_IN_TANF:
4863 case BUILT_IN_TANL:
4864 case BUILT_IN_ATAN:
4865 case BUILT_IN_ATANF:
4866 case BUILT_IN_ATANL:
4867 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4868 because of possible accuracy problems. */
4869 if (! flag_unsafe_math_optimizations)
4870 break;
4871 case BUILT_IN_SQRT:
4872 case BUILT_IN_SQRTF:
4873 case BUILT_IN_SQRTL:
4874 case BUILT_IN_FLOOR:
4875 case BUILT_IN_FLOORF:
4876 case BUILT_IN_FLOORL:
4877 case BUILT_IN_CEIL:
4878 case BUILT_IN_CEILF:
4879 case BUILT_IN_CEILL:
4880 case BUILT_IN_TRUNC:
4881 case BUILT_IN_TRUNCF:
4882 case BUILT_IN_TRUNCL:
4883 case BUILT_IN_ROUND:
4884 case BUILT_IN_ROUNDF:
4885 case BUILT_IN_ROUNDL:
4886 case BUILT_IN_NEARBYINT:
4887 case BUILT_IN_NEARBYINTF:
4888 case BUILT_IN_NEARBYINTL:
4889 target = expand_builtin_mathfn (exp, target, subtarget);
4890 if (target)
4891 return target;
4892 break;
4894 case BUILT_IN_POW:
4895 case BUILT_IN_POWF:
4896 case BUILT_IN_POWL:
4897 if (! flag_unsafe_math_optimizations)
4898 break;
4899 target = expand_builtin_pow (exp, target, subtarget);
4900 if (target)
4901 return target;
4902 break;
4904 case BUILT_IN_ATAN2:
4905 case BUILT_IN_ATAN2F:
4906 case BUILT_IN_ATAN2L:
4907 if (! flag_unsafe_math_optimizations)
4908 break;
4909 target = expand_builtin_mathfn_2 (exp, target, subtarget);
4910 if (target)
4911 return target;
4912 break;
4914 case BUILT_IN_APPLY_ARGS:
4915 return expand_builtin_apply_args ();
4917 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4918 FUNCTION with a copy of the parameters described by
4919 ARGUMENTS, and ARGSIZE. It returns a block of memory
4920 allocated on the stack into which is stored all the registers
4921 that might possibly be used for returning the result of a
4922 function. ARGUMENTS is the value returned by
4923 __builtin_apply_args. ARGSIZE is the number of bytes of
4924 arguments that must be copied. ??? How should this value be
4925 computed? We'll also need a safe worst case value for varargs
4926 functions. */
4927 case BUILT_IN_APPLY:
4928 if (!validate_arglist (arglist, POINTER_TYPE,
4929 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4930 && !validate_arglist (arglist, REFERENCE_TYPE,
4931 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4932 return const0_rtx;
4933 else
4935 int i;
4936 tree t;
4937 rtx ops[3];
4939 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4940 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4942 return expand_builtin_apply (ops[0], ops[1], ops[2]);
4945 /* __builtin_return (RESULT) causes the function to return the
4946 value described by RESULT. RESULT is address of the block of
4947 memory returned by __builtin_apply. */
4948 case BUILT_IN_RETURN:
4949 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4950 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4951 NULL_RTX, VOIDmode, 0));
4952 return const0_rtx;
4954 case BUILT_IN_SAVEREGS:
4955 return expand_builtin_saveregs ();
4957 case BUILT_IN_ARGS_INFO:
4958 return expand_builtin_args_info (arglist);
4960 /* Return the address of the first anonymous stack arg. */
4961 case BUILT_IN_NEXT_ARG:
4962 return expand_builtin_next_arg (arglist);
4964 case BUILT_IN_CLASSIFY_TYPE:
4965 return expand_builtin_classify_type (arglist);
4967 case BUILT_IN_CONSTANT_P:
4968 return expand_builtin_constant_p (arglist, target_mode);
4970 case BUILT_IN_FRAME_ADDRESS:
4971 case BUILT_IN_RETURN_ADDRESS:
4972 return expand_builtin_frame_address (fndecl, arglist);
4974 /* Returns the address of the area where the structure is returned.
4975 0 otherwise. */
4976 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
4977 if (arglist != 0
4978 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
4979 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
4980 return const0_rtx;
4981 else
4982 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
4984 case BUILT_IN_ALLOCA:
4985 target = expand_builtin_alloca (arglist, target);
4986 if (target)
4987 return target;
4988 break;
4990 case BUILT_IN_FFS:
4991 case BUILT_IN_FFSL:
4992 case BUILT_IN_FFSLL:
4993 target = expand_builtin_unop (target_mode, arglist, target,
4994 subtarget, ffs_optab);
4995 if (target)
4996 return target;
4997 break;
4999 case BUILT_IN_CLZ:
5000 case BUILT_IN_CLZL:
5001 case BUILT_IN_CLZLL:
5002 target = expand_builtin_unop (target_mode, arglist, target,
5003 subtarget, clz_optab);
5004 if (target)
5005 return target;
5006 break;
5008 case BUILT_IN_CTZ:
5009 case BUILT_IN_CTZL:
5010 case BUILT_IN_CTZLL:
5011 target = expand_builtin_unop (target_mode, arglist, target,
5012 subtarget, ctz_optab);
5013 if (target)
5014 return target;
5015 break;
5017 case BUILT_IN_POPCOUNT:
5018 case BUILT_IN_POPCOUNTL:
5019 case BUILT_IN_POPCOUNTLL:
5020 target = expand_builtin_unop (target_mode, arglist, target,
5021 subtarget, popcount_optab);
5022 if (target)
5023 return target;
5024 break;
5026 case BUILT_IN_PARITY:
5027 case BUILT_IN_PARITYL:
5028 case BUILT_IN_PARITYLL:
5029 target = expand_builtin_unop (target_mode, arglist, target,
5030 subtarget, parity_optab);
5031 if (target)
5032 return target;
5033 break;
5035 case BUILT_IN_STRLEN:
5036 target = expand_builtin_strlen (arglist, target, target_mode);
5037 if (target)
5038 return target;
5039 break;
5041 case BUILT_IN_STRCPY:
5042 target = expand_builtin_strcpy (arglist, target, mode);
5043 if (target)
5044 return target;
5045 break;
5047 case BUILT_IN_STRNCPY:
5048 target = expand_builtin_strncpy (arglist, target, mode);
5049 if (target)
5050 return target;
5051 break;
5053 case BUILT_IN_STPCPY:
5054 target = expand_builtin_stpcpy (arglist, target, mode);
5055 if (target)
5056 return target;
5057 break;
5059 case BUILT_IN_STRCAT:
5060 target = expand_builtin_strcat (arglist, target, mode);
5061 if (target)
5062 return target;
5063 break;
5065 case BUILT_IN_STRNCAT:
5066 target = expand_builtin_strncat (arglist, target, mode);
5067 if (target)
5068 return target;
5069 break;
5071 case BUILT_IN_STRSPN:
5072 target = expand_builtin_strspn (arglist, target, mode);
5073 if (target)
5074 return target;
5075 break;
5077 case BUILT_IN_STRCSPN:
5078 target = expand_builtin_strcspn (arglist, target, mode);
5079 if (target)
5080 return target;
5081 break;
5083 case BUILT_IN_STRSTR:
5084 target = expand_builtin_strstr (arglist, target, mode);
5085 if (target)
5086 return target;
5087 break;
5089 case BUILT_IN_STRPBRK:
5090 target = expand_builtin_strpbrk (arglist, target, mode);
5091 if (target)
5092 return target;
5093 break;
5095 case BUILT_IN_INDEX:
5096 case BUILT_IN_STRCHR:
5097 target = expand_builtin_strchr (arglist, target, mode);
5098 if (target)
5099 return target;
5100 break;
5102 case BUILT_IN_RINDEX:
5103 case BUILT_IN_STRRCHR:
5104 target = expand_builtin_strrchr (arglist, target, mode);
5105 if (target)
5106 return target;
5107 break;
5109 case BUILT_IN_MEMCPY:
5110 target = expand_builtin_memcpy (arglist, target, mode);
5111 if (target)
5112 return target;
5113 break;
5115 case BUILT_IN_MEMPCPY:
5116 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5117 if (target)
5118 return target;
5119 break;
5121 case BUILT_IN_MEMMOVE:
5122 target = expand_builtin_memmove (arglist, target, mode);
5123 if (target)
5124 return target;
5125 break;
5127 case BUILT_IN_BCOPY:
5128 target = expand_builtin_bcopy (arglist);
5129 if (target)
5130 return target;
5131 break;
5133 case BUILT_IN_MEMSET:
5134 target = expand_builtin_memset (arglist, target, mode);
5135 if (target)
5136 return target;
5137 break;
5139 case BUILT_IN_BZERO:
5140 target = expand_builtin_bzero (arglist);
5141 if (target)
5142 return target;
5143 break;
5145 case BUILT_IN_STRCMP:
5146 target = expand_builtin_strcmp (exp, target, mode);
5147 if (target)
5148 return target;
5149 break;
5151 case BUILT_IN_STRNCMP:
5152 target = expand_builtin_strncmp (exp, target, mode);
5153 if (target)
5154 return target;
5155 break;
5157 case BUILT_IN_BCMP:
5158 case BUILT_IN_MEMCMP:
5159 target = expand_builtin_memcmp (exp, arglist, target, mode);
5160 if (target)
5161 return target;
5162 break;
5164 case BUILT_IN_SETJMP:
5165 target = expand_builtin_setjmp (arglist, target);
5166 if (target)
5167 return target;
5168 break;
5170 /* __builtin_longjmp is passed a pointer to an array of five words.
5171 It's similar to the C library longjmp function but works with
5172 __builtin_setjmp above. */
5173 case BUILT_IN_LONGJMP:
5174 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5175 break;
5176 else
5178 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5179 VOIDmode, 0);
5180 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5181 NULL_RTX, VOIDmode, 0);
5183 if (value != const1_rtx)
5185 error ("__builtin_longjmp second argument must be 1");
5186 return const0_rtx;
5189 expand_builtin_longjmp (buf_addr, value);
5190 return const0_rtx;
5193 case BUILT_IN_TRAP:
5194 expand_builtin_trap ();
5195 return const0_rtx;
5197 case BUILT_IN_PRINTF:
5198 target = expand_builtin_printf (arglist, target, mode, false);
5199 if (target)
5200 return target;
5201 break;
5203 case BUILT_IN_PRINTF_UNLOCKED:
5204 target = expand_builtin_printf (arglist, target, mode, true);
5205 if (target)
5206 return target;
5207 break;
5209 case BUILT_IN_FPUTS:
5210 target = expand_builtin_fputs (arglist, target, false);
5211 if (target)
5212 return target;
5213 break;
5215 case BUILT_IN_FPUTS_UNLOCKED:
5216 target = expand_builtin_fputs (arglist, target, true);
5217 if (target)
5218 return target;
5219 break;
5221 case BUILT_IN_FPRINTF:
5222 target = expand_builtin_fprintf (arglist, target, mode, false);
5223 if (target)
5224 return target;
5225 break;
5227 case BUILT_IN_FPRINTF_UNLOCKED:
5228 target = expand_builtin_fprintf (arglist, target, mode, true);
5229 if (target)
5230 return target;
5231 break;
5233 case BUILT_IN_SPRINTF:
5234 target = expand_builtin_sprintf (arglist, target, mode);
5235 if (target)
5236 return target;
5237 break;
5239 /* Various hooks for the DWARF 2 __throw routine. */
5240 case BUILT_IN_UNWIND_INIT:
5241 expand_builtin_unwind_init ();
5242 return const0_rtx;
5243 case BUILT_IN_DWARF_CFA:
5244 return virtual_cfa_rtx;
5245 #ifdef DWARF2_UNWIND_INFO
5246 case BUILT_IN_DWARF_SP_COLUMN:
5247 return expand_builtin_dwarf_sp_column ();
5248 case BUILT_IN_INIT_DWARF_REG_SIZES:
5249 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5250 return const0_rtx;
5251 #endif
5252 case BUILT_IN_FROB_RETURN_ADDR:
5253 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5254 case BUILT_IN_EXTRACT_RETURN_ADDR:
5255 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5256 case BUILT_IN_EH_RETURN:
5257 expand_builtin_eh_return (TREE_VALUE (arglist),
5258 TREE_VALUE (TREE_CHAIN (arglist)));
5259 return const0_rtx;
5260 #ifdef EH_RETURN_DATA_REGNO
5261 case BUILT_IN_EH_RETURN_DATA_REGNO:
5262 return expand_builtin_eh_return_data_regno (arglist);
5263 #endif
5264 case BUILT_IN_VA_START:
5265 case BUILT_IN_STDARG_START:
5266 return expand_builtin_va_start (arglist);
5267 case BUILT_IN_VA_END:
5268 return expand_builtin_va_end (arglist);
5269 case BUILT_IN_VA_COPY:
5270 return expand_builtin_va_copy (arglist);
5271 case BUILT_IN_EXPECT:
5272 return expand_builtin_expect (arglist, target);
5273 case BUILT_IN_PREFETCH:
5274 expand_builtin_prefetch (arglist);
5275 return const0_rtx;
5278 default: /* just do library call, if unknown builtin */
5279 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5280 error ("built-in function `%s' not currently supported",
5281 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5284 /* The switch statement above can drop through to cause the function
5285 to be called normally. */
5286 return expand_call (exp, target, ignore);
5289 /* Determine whether a tree node represents a call to a built-in
5290 math function. If the tree T is a call to a built-in function
5291 taking a single real argument, then the return value is the
5292 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
5293 the return value is END_BUILTINS. */
5295 enum built_in_function
5296 builtin_mathfn_code (tree t)
5298 tree fndecl, arglist;
5300 if (TREE_CODE (t) != CALL_EXPR
5301 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5302 return END_BUILTINS;
5304 fndecl = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
5305 if (TREE_CODE (fndecl) != FUNCTION_DECL
5306 || ! DECL_BUILT_IN (fndecl)
5307 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5308 return END_BUILTINS;
5310 arglist = TREE_OPERAND (t, 1);
5311 if (! arglist
5312 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
5313 return END_BUILTINS;
5315 arglist = TREE_CHAIN (arglist);
5316 switch (DECL_FUNCTION_CODE (fndecl))
5318 case BUILT_IN_POW:
5319 case BUILT_IN_POWF:
5320 case BUILT_IN_POWL:
5321 case BUILT_IN_ATAN2:
5322 case BUILT_IN_ATAN2F:
5323 case BUILT_IN_ATAN2L:
5324 if (! arglist
5325 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
5326 || TREE_CHAIN (arglist))
5327 return END_BUILTINS;
5328 break;
5330 default:
5331 if (arglist)
5332 return END_BUILTINS;
5333 break;
5336 return DECL_FUNCTION_CODE (fndecl);
5339 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5340 constant. ARGLIST is the argument list of the call. */
5342 static tree
5343 fold_builtin_constant_p (tree arglist)
5345 if (arglist == 0)
5346 return 0;
5348 arglist = TREE_VALUE (arglist);
5350 /* We return 1 for a numeric type that's known to be a constant
5351 value at compile-time or for an aggregate type that's a
5352 literal constant. */
5353 STRIP_NOPS (arglist);
5355 /* If we know this is a constant, emit the constant of one. */
5356 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5357 || (TREE_CODE (arglist) == CONSTRUCTOR
5358 && TREE_CONSTANT (arglist))
5359 || (TREE_CODE (arglist) == ADDR_EXPR
5360 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5361 return integer_one_node;
5363 /* If we aren't going to be running CSE or this expression
5364 has side effects, show we don't know it to be a constant.
5365 Likewise if it's a pointer or aggregate type since in those
5366 case we only want literals, since those are only optimized
5367 when generating RTL, not later.
5368 And finally, if we are compiling an initializer, not code, we
5369 need to return a definite result now; there's not going to be any
5370 more optimization done. */
5371 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
5372 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5373 || POINTER_TYPE_P (TREE_TYPE (arglist))
5374 || cfun == 0)
5375 return integer_zero_node;
5377 return 0;
5380 /* Fold a call to __builtin_classify_type. */
5382 static tree
5383 fold_builtin_classify_type (tree arglist)
5385 if (arglist == 0)
5386 return build_int_2 (no_type_class, 0);
5388 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5391 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5393 static tree
5394 fold_builtin_inf (tree type, int warn)
5396 REAL_VALUE_TYPE real;
5398 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5399 warning ("target format does not support infinity");
5401 real_inf (&real);
5402 return build_real (type, real);
5405 /* Fold a call to __builtin_nan or __builtin_nans. */
5407 static tree
5408 fold_builtin_nan (tree arglist, tree type, int quiet)
5410 REAL_VALUE_TYPE real;
5411 const char *str;
5413 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5414 return 0;
5415 str = c_getstr (TREE_VALUE (arglist));
5416 if (!str)
5417 return 0;
5419 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5420 return 0;
5422 return build_real (type, real);
5425 /* Return true if the floating point expression T has an integer value.
5426 We also allow +Inf, -Inf and NaN to be considered integer values. */
5428 static bool
5429 integer_valued_real_p (tree t)
5431 switch (TREE_CODE (t))
5433 case FLOAT_EXPR:
5434 return true;
5436 case ABS_EXPR:
5437 case SAVE_EXPR:
5438 case NON_LVALUE_EXPR:
5439 return integer_valued_real_p (TREE_OPERAND (t, 0));
5441 case COMPOUND_EXPR:
5442 case MODIFY_EXPR:
5443 case BIND_EXPR:
5444 return integer_valued_real_p (TREE_OPERAND (t, 1));
5446 case PLUS_EXPR:
5447 case MINUS_EXPR:
5448 case MULT_EXPR:
5449 case MIN_EXPR:
5450 case MAX_EXPR:
5451 return integer_valued_real_p (TREE_OPERAND (t, 0))
5452 && integer_valued_real_p (TREE_OPERAND (t, 1));
5454 case COND_EXPR:
5455 return integer_valued_real_p (TREE_OPERAND (t, 1))
5456 && integer_valued_real_p (TREE_OPERAND (t, 2));
5458 case REAL_CST:
5459 if (! TREE_CONSTANT_OVERFLOW (t))
5461 REAL_VALUE_TYPE c, cint;
5463 c = TREE_REAL_CST (t);
5464 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5465 return real_identical (&c, &cint);
5468 case NOP_EXPR:
5470 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5471 if (TREE_CODE (type) == INTEGER_TYPE)
5472 return true;
5473 if (TREE_CODE (type) == REAL_TYPE)
5474 return integer_valued_real_p (TREE_OPERAND (t, 0));
5475 break;
5478 case CALL_EXPR:
5479 switch (builtin_mathfn_code (t))
5481 case BUILT_IN_CEIL:
5482 case BUILT_IN_CEILF:
5483 case BUILT_IN_CEILL:
5484 case BUILT_IN_FLOOR:
5485 case BUILT_IN_FLOORF:
5486 case BUILT_IN_FLOORL:
5487 case BUILT_IN_NEARBYINT:
5488 case BUILT_IN_NEARBYINTF:
5489 case BUILT_IN_NEARBYINTL:
5490 case BUILT_IN_ROUND:
5491 case BUILT_IN_ROUNDF:
5492 case BUILT_IN_ROUNDL:
5493 case BUILT_IN_TRUNC:
5494 case BUILT_IN_TRUNCF:
5495 case BUILT_IN_TRUNCL:
5496 return true;
5498 default:
5499 break;
5501 break;
5503 default:
5504 break;
5506 return false;
5509 /* EXP is assumed to be builtin call where truncation can be propagated
5510 across (for instance floor((double)f) == (double)floorf (f).
5511 Do the transformation. */
5513 static tree
5514 fold_trunc_transparent_mathfn (tree exp)
5516 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5517 tree arglist = TREE_OPERAND (exp, 1);
5518 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5519 tree arg;
5521 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5522 return 0;
5524 arg = TREE_VALUE (arglist);
5525 /* Integer rounding functions are idempotent. */
5526 if (fcode == builtin_mathfn_code (arg))
5527 return arg;
5529 /* If argument is already integer valued, and we don't need to worry
5530 about setting errno, there's no need to perform rounding. */
5531 if (! flag_errno_math && integer_valued_real_p (arg))
5532 return arg;
5534 if (optimize)
5536 tree arg0 = strip_float_extensions (arg);
5537 tree ftype = TREE_TYPE (exp);
5538 tree newtype = TREE_TYPE (arg0);
5539 tree decl;
5541 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5542 && (decl = mathfn_built_in (newtype, fcode)))
5544 arglist =
5545 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5546 return convert (ftype,
5547 build_function_call_expr (decl, arglist));
5550 return 0;
5553 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5554 function's DECL, ARGLIST is the argument list and TYPE is the return
5555 type. Return NULL_TREE if no simplification can be made. */
5557 static tree
5558 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5560 tree arg;
5562 if (!arglist || TREE_CHAIN (arglist))
5563 return NULL_TREE;
5565 arg = TREE_VALUE (arglist);
5566 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5567 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5568 return NULL_TREE;
5570 /* Evaluate cabs of a constant at compile-time. */
5571 if (flag_unsafe_math_optimizations
5572 && TREE_CODE (arg) == COMPLEX_CST
5573 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5574 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5575 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5576 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5578 REAL_VALUE_TYPE r, i;
5580 r = TREE_REAL_CST (TREE_REALPART (arg));
5581 i = TREE_REAL_CST (TREE_IMAGPART (arg));
5583 real_arithmetic (&r, MULT_EXPR, &r, &r);
5584 real_arithmetic (&i, MULT_EXPR, &i, &i);
5585 real_arithmetic (&r, PLUS_EXPR, &r, &i);
5586 if (real_sqrt (&r, TYPE_MODE (type), &r)
5587 || ! flag_trapping_math)
5588 return build_real (type, r);
5591 /* If either part is zero, cabs is fabs of the other. */
5592 if (TREE_CODE (arg) == COMPLEX_EXPR
5593 && real_zerop (TREE_OPERAND (arg, 0)))
5594 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5595 if (TREE_CODE (arg) == COMPLEX_EXPR
5596 && real_zerop (TREE_OPERAND (arg, 1)))
5597 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5599 if (flag_unsafe_math_optimizations)
5601 enum built_in_function fcode;
5602 tree sqrtfn;
5604 fcode = DECL_FUNCTION_CODE (fndecl);
5605 if (fcode == BUILT_IN_CABS)
5606 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5607 else if (fcode == BUILT_IN_CABSF)
5608 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5609 else if (fcode == BUILT_IN_CABSL)
5610 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5611 else
5612 sqrtfn = NULL_TREE;
5614 if (sqrtfn != NULL_TREE)
5616 tree rpart, ipart, result, arglist;
5618 rpart = fold (build1 (REALPART_EXPR, type, arg));
5619 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5621 rpart = save_expr (rpart);
5622 ipart = save_expr (ipart);
5624 result = fold (build (PLUS_EXPR, type,
5625 fold (build (MULT_EXPR, type,
5626 rpart, rpart)),
5627 fold (build (MULT_EXPR, type,
5628 ipart, ipart))));
5630 arglist = build_tree_list (NULL_TREE, result);
5631 return build_function_call_expr (sqrtfn, arglist);
5635 return NULL_TREE;
5638 /* Fold function call to builtin trunc, truncf or truncl. Return
5639 NULL_TREE if no simplification can be made. */
5641 static tree
5642 fold_builtin_trunc (tree exp)
5644 tree arglist = TREE_OPERAND (exp, 1);
5645 tree arg;
5647 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5648 return 0;
5650 /* Optimize trunc of constant value. */
5651 arg = TREE_VALUE (arglist);
5652 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5654 REAL_VALUE_TYPE r, x;
5655 tree type = TREE_TYPE (exp);
5657 x = TREE_REAL_CST (arg);
5658 real_trunc (&r, TYPE_MODE (type), &x);
5659 return build_real (type, r);
5662 return fold_trunc_transparent_mathfn (exp);
5665 /* Fold function call to builtin floor, floorf or floorl. Return
5666 NULL_TREE if no simplification can be made. */
5668 static tree
5669 fold_builtin_floor (tree exp)
5671 tree arglist = TREE_OPERAND (exp, 1);
5672 tree arg;
5674 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5675 return 0;
5677 /* Optimize floor of constant value. */
5678 arg = TREE_VALUE (arglist);
5679 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5681 REAL_VALUE_TYPE x;
5683 x = TREE_REAL_CST (arg);
5684 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5686 tree type = TREE_TYPE (exp);
5687 REAL_VALUE_TYPE r;
5689 real_floor (&r, TYPE_MODE (type), &x);
5690 return build_real (type, r);
5694 return fold_trunc_transparent_mathfn (exp);
5697 /* Fold function call to builtin ceil, ceilf or ceill. Return
5698 NULL_TREE if no simplification can be made. */
5700 static tree
5701 fold_builtin_ceil (tree exp)
5703 tree arglist = TREE_OPERAND (exp, 1);
5704 tree arg;
5706 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5707 return 0;
5709 /* Optimize ceil of constant value. */
5710 arg = TREE_VALUE (arglist);
5711 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5713 REAL_VALUE_TYPE x;
5715 x = TREE_REAL_CST (arg);
5716 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5718 tree type = TREE_TYPE (exp);
5719 REAL_VALUE_TYPE r;
5721 real_ceil (&r, TYPE_MODE (type), &x);
5722 return build_real (type, r);
5726 return fold_trunc_transparent_mathfn (exp);
5729 /* Used by constant folding to eliminate some builtin calls early. EXP is
5730 the CALL_EXPR of a call to a builtin function. */
5732 tree
5733 fold_builtin (tree exp)
5735 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5736 tree arglist = TREE_OPERAND (exp, 1);
5737 tree type = TREE_TYPE (TREE_TYPE (fndecl));
5739 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5740 return 0;
5742 switch (DECL_FUNCTION_CODE (fndecl))
5744 case BUILT_IN_CONSTANT_P:
5745 return fold_builtin_constant_p (arglist);
5747 case BUILT_IN_CLASSIFY_TYPE:
5748 return fold_builtin_classify_type (arglist);
5750 case BUILT_IN_STRLEN:
5751 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5753 tree len = c_strlen (TREE_VALUE (arglist), 0);
5754 if (len)
5756 /* Convert from the internal "sizetype" type to "size_t". */
5757 if (size_type_node)
5758 len = convert (size_type_node, len);
5759 return len;
5762 break;
5764 case BUILT_IN_FABS:
5765 case BUILT_IN_FABSF:
5766 case BUILT_IN_FABSL:
5767 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5768 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
5769 break;
5771 case BUILT_IN_CABS:
5772 case BUILT_IN_CABSF:
5773 case BUILT_IN_CABSL:
5774 return fold_builtin_cabs (fndecl, arglist, type);
5776 case BUILT_IN_SQRT:
5777 case BUILT_IN_SQRTF:
5778 case BUILT_IN_SQRTL:
5779 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5781 enum built_in_function fcode;
5782 tree arg = TREE_VALUE (arglist);
5784 /* Optimize sqrt of constant value. */
5785 if (TREE_CODE (arg) == REAL_CST
5786 && ! TREE_CONSTANT_OVERFLOW (arg))
5788 REAL_VALUE_TYPE r, x;
5790 x = TREE_REAL_CST (arg);
5791 if (real_sqrt (&r, TYPE_MODE (type), &x)
5792 || (!flag_trapping_math && !flag_errno_math))
5793 return build_real (type, r);
5796 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
5797 fcode = builtin_mathfn_code (arg);
5798 if (flag_unsafe_math_optimizations
5799 && (fcode == BUILT_IN_EXP
5800 || fcode == BUILT_IN_EXPF
5801 || fcode == BUILT_IN_EXPL))
5803 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
5804 arg = fold (build (MULT_EXPR, type,
5805 TREE_VALUE (TREE_OPERAND (arg, 1)),
5806 build_real (type, dconsthalf)));
5807 arglist = build_tree_list (NULL_TREE, arg);
5808 return build_function_call_expr (expfn, arglist);
5811 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
5812 if (flag_unsafe_math_optimizations
5813 && (fcode == BUILT_IN_POW
5814 || fcode == BUILT_IN_POWF
5815 || fcode == BUILT_IN_POWL))
5817 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
5818 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
5819 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
5820 tree narg1 = fold (build (MULT_EXPR, type, arg1,
5821 build_real (type, dconsthalf)));
5822 arglist = tree_cons (NULL_TREE, arg0,
5823 build_tree_list (NULL_TREE, narg1));
5824 return build_function_call_expr (powfn, arglist);
5827 break;
5829 case BUILT_IN_SIN:
5830 case BUILT_IN_SINF:
5831 case BUILT_IN_SINL:
5832 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5834 tree arg = TREE_VALUE (arglist);
5836 /* Optimize sin(0.0) = 0.0. */
5837 if (real_zerop (arg))
5838 return arg;
5840 break;
5842 case BUILT_IN_COS:
5843 case BUILT_IN_COSF:
5844 case BUILT_IN_COSL:
5845 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5847 tree arg = TREE_VALUE (arglist);
5849 /* Optimize cos(0.0) = 1.0. */
5850 if (real_zerop (arg))
5851 return build_real (type, dconst1);
5853 /* Optimize cos(-x) into cos(x). */
5854 if (TREE_CODE (arg) == NEGATE_EXPR)
5856 tree arglist = build_tree_list (NULL_TREE,
5857 TREE_OPERAND (arg, 0));
5858 return build_function_call_expr (fndecl, arglist);
5861 break;
5863 case BUILT_IN_EXP:
5864 case BUILT_IN_EXPF:
5865 case BUILT_IN_EXPL:
5866 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5868 enum built_in_function fcode;
5869 tree arg = TREE_VALUE (arglist);
5871 /* Optimize exp(0.0) = 1.0. */
5872 if (real_zerop (arg))
5873 return build_real (type, dconst1);
5875 /* Optimize exp(1.0) = e. */
5876 if (real_onep (arg))
5878 REAL_VALUE_TYPE cst;
5880 if (! builtin_dconsts_init)
5881 init_builtin_dconsts ();
5882 real_convert (&cst, TYPE_MODE (type), &dconste);
5883 return build_real (type, cst);
5886 /* Attempt to evaluate exp at compile-time. */
5887 if (flag_unsafe_math_optimizations
5888 && TREE_CODE (arg) == REAL_CST
5889 && ! TREE_CONSTANT_OVERFLOW (arg))
5891 REAL_VALUE_TYPE cint;
5892 REAL_VALUE_TYPE c;
5893 HOST_WIDE_INT n;
5895 c = TREE_REAL_CST (arg);
5896 n = real_to_integer (&c);
5897 real_from_integer (&cint, VOIDmode, n,
5898 n < 0 ? -1 : 0, 0);
5899 if (real_identical (&c, &cint))
5901 REAL_VALUE_TYPE x;
5903 if (! builtin_dconsts_init)
5904 init_builtin_dconsts ();
5905 real_powi (&x, TYPE_MODE (type), &dconste, n);
5906 return build_real (type, x);
5910 /* Optimize exp(log(x)) = x. */
5911 fcode = builtin_mathfn_code (arg);
5912 if (flag_unsafe_math_optimizations
5913 && (fcode == BUILT_IN_LOG
5914 || fcode == BUILT_IN_LOGF
5915 || fcode == BUILT_IN_LOGL))
5916 return TREE_VALUE (TREE_OPERAND (arg, 1));
5918 break;
5920 case BUILT_IN_LOG:
5921 case BUILT_IN_LOGF:
5922 case BUILT_IN_LOGL:
5923 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5925 enum built_in_function fcode;
5926 tree arg = TREE_VALUE (arglist);
5928 /* Optimize log(1.0) = 0.0. */
5929 if (real_onep (arg))
5930 return build_real (type, dconst0);
5932 /* Optimize log(exp(x)) = x. */
5933 fcode = builtin_mathfn_code (arg);
5934 if (flag_unsafe_math_optimizations
5935 && (fcode == BUILT_IN_EXP
5936 || fcode == BUILT_IN_EXPF
5937 || fcode == BUILT_IN_EXPL))
5938 return TREE_VALUE (TREE_OPERAND (arg, 1));
5940 /* Optimize log(sqrt(x)) = log(x)*0.5. */
5941 if (flag_unsafe_math_optimizations
5942 && (fcode == BUILT_IN_SQRT
5943 || fcode == BUILT_IN_SQRTF
5944 || fcode == BUILT_IN_SQRTL))
5946 tree logfn = build_function_call_expr (fndecl,
5947 TREE_OPERAND (arg, 1));
5948 return fold (build (MULT_EXPR, type, logfn,
5949 build_real (type, dconsthalf)));
5952 /* Optimize log(pow(x,y)) = y*log(x). */
5953 if (flag_unsafe_math_optimizations
5954 && (fcode == BUILT_IN_POW
5955 || fcode == BUILT_IN_POWF
5956 || fcode == BUILT_IN_POWL))
5958 tree arg0, arg1, logfn;
5960 arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
5961 arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
5962 arglist = build_tree_list (NULL_TREE, arg0);
5963 logfn = build_function_call_expr (fndecl, arglist);
5964 return fold (build (MULT_EXPR, type, arg1, logfn));
5967 break;
5969 case BUILT_IN_TAN:
5970 case BUILT_IN_TANF:
5971 case BUILT_IN_TANL:
5972 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5974 enum built_in_function fcode;
5975 tree arg = TREE_VALUE (arglist);
5977 /* Optimize tan(0.0) = 0.0. */
5978 if (real_zerop (arg))
5979 return arg;
5981 /* Optimize tan(atan(x)) = x. */
5982 fcode = builtin_mathfn_code (arg);
5983 if (flag_unsafe_math_optimizations
5984 && (fcode == BUILT_IN_ATAN
5985 || fcode == BUILT_IN_ATANF
5986 || fcode == BUILT_IN_ATANL))
5987 return TREE_VALUE (TREE_OPERAND (arg, 1));
5989 break;
5991 case BUILT_IN_ATAN:
5992 case BUILT_IN_ATANF:
5993 case BUILT_IN_ATANL:
5994 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5996 tree arg = TREE_VALUE (arglist);
5998 /* Optimize atan(0.0) = 0.0. */
5999 if (real_zerop (arg))
6000 return arg;
6002 /* Optimize atan(1.0) = pi/4. */
6003 if (real_onep (arg))
6005 REAL_VALUE_TYPE cst;
6007 if (! builtin_dconsts_init)
6008 init_builtin_dconsts ();
6009 real_convert (&cst, TYPE_MODE (type), &dconstpi);
6010 cst.exp -= 2;
6011 return build_real (type, cst);
6014 break;
6016 case BUILT_IN_POW:
6017 case BUILT_IN_POWF:
6018 case BUILT_IN_POWL:
6019 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6021 enum built_in_function fcode;
6022 tree arg0 = TREE_VALUE (arglist);
6023 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6025 /* Optimize pow(1.0,y) = 1.0. */
6026 if (real_onep (arg0))
6027 return omit_one_operand (type, build_real (type, dconst1), arg1);
6029 if (TREE_CODE (arg1) == REAL_CST
6030 && ! TREE_CONSTANT_OVERFLOW (arg1))
6032 REAL_VALUE_TYPE c;
6033 c = TREE_REAL_CST (arg1);
6035 /* Optimize pow(x,0.0) = 1.0. */
6036 if (REAL_VALUES_EQUAL (c, dconst0))
6037 return omit_one_operand (type, build_real (type, dconst1),
6038 arg0);
6040 /* Optimize pow(x,1.0) = x. */
6041 if (REAL_VALUES_EQUAL (c, dconst1))
6042 return arg0;
6044 /* Optimize pow(x,-1.0) = 1.0/x. */
6045 if (REAL_VALUES_EQUAL (c, dconstm1))
6046 return fold (build (RDIV_EXPR, type,
6047 build_real (type, dconst1),
6048 arg0));
6050 /* Optimize pow(x,0.5) = sqrt(x). */
6051 if (flag_unsafe_math_optimizations
6052 && REAL_VALUES_EQUAL (c, dconsthalf))
6054 tree sqrtfn;
6056 fcode = DECL_FUNCTION_CODE (fndecl);
6057 if (fcode == BUILT_IN_POW)
6058 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6059 else if (fcode == BUILT_IN_POWF)
6060 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6061 else if (fcode == BUILT_IN_POWL)
6062 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6063 else
6064 sqrtfn = NULL_TREE;
6066 if (sqrtfn != NULL_TREE)
6068 tree arglist = build_tree_list (NULL_TREE, arg0);
6069 return build_function_call_expr (sqrtfn, arglist);
6073 /* Attempt to evaluate pow at compile-time. */
6074 if (TREE_CODE (arg0) == REAL_CST
6075 && ! TREE_CONSTANT_OVERFLOW (arg0))
6077 REAL_VALUE_TYPE cint;
6078 HOST_WIDE_INT n;
6080 n = real_to_integer (&c);
6081 real_from_integer (&cint, VOIDmode, n,
6082 n < 0 ? -1 : 0, 0);
6083 if (real_identical (&c, &cint))
6085 REAL_VALUE_TYPE x;
6086 bool inexact;
6088 x = TREE_REAL_CST (arg0);
6089 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6090 if (flag_unsafe_math_optimizations || !inexact)
6091 return build_real (type, x);
6096 /* Optimize pow(exp(x),y) = exp(x*y). */
6097 fcode = builtin_mathfn_code (arg0);
6098 if (flag_unsafe_math_optimizations
6099 && (fcode == BUILT_IN_EXP
6100 || fcode == BUILT_IN_EXPF
6101 || fcode == BUILT_IN_EXPL))
6103 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6104 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6105 arg = fold (build (MULT_EXPR, type, arg, arg1));
6106 arglist = build_tree_list (NULL_TREE, arg);
6107 return build_function_call_expr (expfn, arglist);
6110 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
6111 if (flag_unsafe_math_optimizations
6112 && (fcode == BUILT_IN_SQRT
6113 || fcode == BUILT_IN_SQRTF
6114 || fcode == BUILT_IN_SQRTL))
6116 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6117 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6118 build_real (type, dconsthalf)));
6120 arglist = tree_cons (NULL_TREE, narg0,
6121 build_tree_list (NULL_TREE, narg1));
6122 return build_function_call_expr (fndecl, arglist);
6125 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
6126 if (flag_unsafe_math_optimizations
6127 && (fcode == BUILT_IN_POW
6128 || fcode == BUILT_IN_POWF
6129 || fcode == BUILT_IN_POWL))
6131 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6132 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6133 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6134 arglist = tree_cons (NULL_TREE, arg00,
6135 build_tree_list (NULL_TREE, narg1));
6136 return build_function_call_expr (fndecl, arglist);
6139 break;
6141 case BUILT_IN_INF:
6142 case BUILT_IN_INFF:
6143 case BUILT_IN_INFL:
6144 return fold_builtin_inf (type, true);
6146 case BUILT_IN_HUGE_VAL:
6147 case BUILT_IN_HUGE_VALF:
6148 case BUILT_IN_HUGE_VALL:
6149 return fold_builtin_inf (type, false);
6151 case BUILT_IN_NAN:
6152 case BUILT_IN_NANF:
6153 case BUILT_IN_NANL:
6154 return fold_builtin_nan (arglist, type, true);
6156 case BUILT_IN_NANS:
6157 case BUILT_IN_NANSF:
6158 case BUILT_IN_NANSL:
6159 return fold_builtin_nan (arglist, type, false);
6161 case BUILT_IN_FLOOR:
6162 case BUILT_IN_FLOORF:
6163 case BUILT_IN_FLOORL:
6164 return fold_builtin_floor (exp);
6166 case BUILT_IN_CEIL:
6167 case BUILT_IN_CEILF:
6168 case BUILT_IN_CEILL:
6169 return fold_builtin_ceil (exp);
6171 case BUILT_IN_TRUNC:
6172 case BUILT_IN_TRUNCF:
6173 case BUILT_IN_TRUNCL:
6174 return fold_builtin_trunc (exp);
6176 case BUILT_IN_ROUND:
6177 case BUILT_IN_ROUNDF:
6178 case BUILT_IN_ROUNDL:
6179 case BUILT_IN_NEARBYINT:
6180 case BUILT_IN_NEARBYINTF:
6181 case BUILT_IN_NEARBYINTL:
6182 return fold_trunc_transparent_mathfn (exp);
6184 default:
6185 break;
6188 return 0;
6191 /* Conveniently construct a function call expression. */
6193 tree
6194 build_function_call_expr (tree fn, tree arglist)
6196 tree call_expr;
6198 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
6199 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
6200 call_expr, arglist);
6201 TREE_SIDE_EFFECTS (call_expr) = 1;
6202 return fold (call_expr);
6205 /* This function validates the types of a function call argument list
6206 represented as a tree chain of parameters against a specified list
6207 of tree_codes. If the last specifier is a 0, that represents an
6208 ellipses, otherwise the last specifier must be a VOID_TYPE. */
6210 static int
6211 validate_arglist (tree arglist, ...)
6213 enum tree_code code;
6214 int res = 0;
6215 va_list ap;
6217 va_start (ap, arglist);
6221 code = va_arg (ap, enum tree_code);
6222 switch (code)
6224 case 0:
6225 /* This signifies an ellipses, any further arguments are all ok. */
6226 res = 1;
6227 goto end;
6228 case VOID_TYPE:
6229 /* This signifies an endlink, if no arguments remain, return
6230 true, otherwise return false. */
6231 res = arglist == 0;
6232 goto end;
6233 default:
6234 /* If no parameters remain or the parameter's code does not
6235 match the specified code, return false. Otherwise continue
6236 checking any remaining arguments. */
6237 if (arglist == 0
6238 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
6239 goto end;
6240 break;
6242 arglist = TREE_CHAIN (arglist);
6244 while (1);
6246 /* We need gotos here since we can only have one VA_CLOSE in a
6247 function. */
6248 end: ;
6249 va_end (ap);
6251 return res;
6254 /* Default version of target-specific builtin setup that does nothing. */
6256 void
6257 default_init_builtins (void)
6261 /* Default target-specific builtin expander that does nothing. */
6264 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6265 rtx target ATTRIBUTE_UNUSED,
6266 rtx subtarget ATTRIBUTE_UNUSED,
6267 enum machine_mode mode ATTRIBUTE_UNUSED,
6268 int ignore ATTRIBUTE_UNUSED)
6270 return NULL_RTX;
6273 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
6275 void
6276 purge_builtin_constant_p (void)
6278 rtx insn, set, arg, new, note;
6280 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6281 if (INSN_P (insn)
6282 && (set = single_set (insn)) != NULL_RTX
6283 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6284 || (GET_CODE (arg) == SUBREG
6285 && (GET_CODE (arg = SUBREG_REG (arg))
6286 == CONSTANT_P_RTX))))
6288 arg = XEXP (arg, 0);
6289 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6290 validate_change (insn, &SET_SRC (set), new, 0);
6292 /* Remove the REG_EQUAL note from the insn. */
6293 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6294 remove_note (insn, note);
6298 /* Returns true is EXP represents data that would potentially reside
6299 in a readonly section. */
6301 static bool
6302 readonly_data_expr (tree exp)
6304 STRIP_NOPS (exp);
6306 if (TREE_CODE (exp) == ADDR_EXPR)
6307 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
6308 else
6309 return false;