* value-prof.c: New.
[official-gcc.git] / gcc / builtins.c
blob3c4268fd62d467b7b6a356c727ae0238eeef5f7f
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);
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 int apply_args_size (void);
94 static int apply_result_size (void);
95 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
96 static rtx result_vector (int, rtx);
97 #endif
98 static rtx expand_builtin_setjmp (tree, rtx);
99 static void expand_builtin_prefetch (tree);
100 static rtx expand_builtin_apply_args (void);
101 static rtx expand_builtin_apply_args_1 (void);
102 static rtx expand_builtin_apply (rtx, rtx, rtx);
103 static void expand_builtin_return (rtx);
104 static enum type_class type_to_class (tree);
105 static rtx expand_builtin_classify_type (tree);
106 static void expand_errno_check (tree, rtx);
107 static rtx expand_builtin_mathfn (tree, rtx, rtx);
108 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
109 static rtx expand_builtin_constant_p (tree, enum machine_mode);
110 static rtx expand_builtin_args_info (tree);
111 static rtx expand_builtin_next_arg (tree);
112 static rtx expand_builtin_va_start (tree);
113 static rtx expand_builtin_va_end (tree);
114 static rtx expand_builtin_va_copy (tree);
115 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
116 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
118 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
120 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
121 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
123 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
125 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_bcopy (tree);
127 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
129 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
130 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
131 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
132 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
133 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
134 static rtx expand_builtin_bzero (tree);
135 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
136 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
137 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
138 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
139 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
140 static rtx expand_builtin_alloca (tree, rtx);
141 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
142 static rtx expand_builtin_frame_address (tree, tree);
143 static rtx expand_builtin_fputs (tree, int, int);
144 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
145 static tree stabilize_va_list (tree, int);
146 static rtx expand_builtin_expect (tree, rtx);
147 static tree fold_builtin_constant_p (tree);
148 static tree fold_builtin_classify_type (tree);
149 static tree fold_builtin_inf (tree, int);
150 static tree fold_builtin_nan (tree, tree, int);
151 static int validate_arglist (tree, ...);
152 static tree fold_trunc_transparent_mathfn (tree);
153 static bool readonly_data_expr (tree);
154 static rtx expand_builtin_fabs (tree, rtx, rtx);
155 static rtx expand_builtin_cabs (tree, rtx);
156 static void init_builtin_dconsts (void);
157 static tree fold_builtin_cabs (tree, tree, tree);
159 /* Initialize mathematical constants for constant folding builtins.
160 These constants need to be given to at least 160 bits precision. */
162 static void
163 init_builtin_dconsts (void)
165 real_from_string (&dconstpi,
166 "3.1415926535897932384626433832795028841971693993751058209749445923078");
167 real_from_string (&dconste,
168 "2.7182818284590452353602874713526624977572470936999595749669676277241");
170 builtin_dconsts_init = true;
173 /* Return the alignment in bits of EXP, a pointer valued expression.
174 But don't return more than MAX_ALIGN no matter what.
175 The alignment returned is, by default, the alignment of the thing that
176 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
178 Otherwise, look at the expression to see if we can do better, i.e., if the
179 expression is actually pointing at an object whose alignment is tighter. */
181 static int
182 get_pointer_alignment (tree exp, unsigned int max_align)
184 unsigned int align, inner;
186 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
187 return 0;
189 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
190 align = MIN (align, max_align);
192 while (1)
194 switch (TREE_CODE (exp))
196 case NOP_EXPR:
197 case CONVERT_EXPR:
198 case NON_LVALUE_EXPR:
199 exp = TREE_OPERAND (exp, 0);
200 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
201 return align;
203 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
204 align = MIN (inner, max_align);
205 break;
207 case PLUS_EXPR:
208 /* If sum of pointer + int, restrict our maximum alignment to that
209 imposed by the integer. If not, we can't do any better than
210 ALIGN. */
211 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
212 return align;
214 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
215 & (max_align / BITS_PER_UNIT - 1))
216 != 0)
217 max_align >>= 1;
219 exp = TREE_OPERAND (exp, 0);
220 break;
222 case ADDR_EXPR:
223 /* See what we are pointing at and look at its alignment. */
224 exp = TREE_OPERAND (exp, 0);
225 if (TREE_CODE (exp) == FUNCTION_DECL)
226 align = FUNCTION_BOUNDARY;
227 else if (DECL_P (exp))
228 align = DECL_ALIGN (exp);
229 #ifdef CONSTANT_ALIGNMENT
230 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
231 align = CONSTANT_ALIGNMENT (exp, align);
232 #endif
233 return MIN (align, max_align);
235 default:
236 return align;
241 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
242 way, because it could contain a zero byte in the middle.
243 TREE_STRING_LENGTH is the size of the character array, not the string.
245 The value returned is of type `ssizetype'.
247 Unfortunately, string_constant can't access the values of const char
248 arrays with initializers, so neither can we do so here. */
250 static tree
251 c_strlen (tree src)
253 tree offset_node;
254 HOST_WIDE_INT offset;
255 int max;
256 const char *ptr;
258 src = string_constant (src, &offset_node);
259 if (src == 0)
260 return 0;
262 max = TREE_STRING_LENGTH (src) - 1;
263 ptr = TREE_STRING_POINTER (src);
265 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
267 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
268 compute the offset to the following null if we don't know where to
269 start searching for it. */
270 int i;
272 for (i = 0; i < max; i++)
273 if (ptr[i] == 0)
274 return 0;
276 /* We don't know the starting offset, but we do know that the string
277 has no internal zero bytes. We can assume that the offset falls
278 within the bounds of the string; otherwise, the programmer deserves
279 what he gets. Subtract the offset from the length of the string,
280 and return that. This would perhaps not be valid if we were dealing
281 with named arrays in addition to literal string constants. */
283 return size_diffop (size_int (max), offset_node);
286 /* We have a known offset into the string. Start searching there for
287 a null character if we can represent it as a single HOST_WIDE_INT. */
288 if (offset_node == 0)
289 offset = 0;
290 else if (! host_integerp (offset_node, 0))
291 offset = -1;
292 else
293 offset = tree_low_cst (offset_node, 0);
295 /* If the offset is known to be out of bounds, warn, and call strlen at
296 runtime. */
297 if (offset < 0 || offset > max)
299 warning ("offset outside bounds of constant string");
300 return 0;
303 /* Use strlen to search for the first zero byte. Since any strings
304 constructed with build_string will have nulls appended, we win even
305 if we get handed something like (char[4])"abcd".
307 Since OFFSET is our starting index into the string, no further
308 calculation is needed. */
309 return ssize_int (strlen (ptr + offset));
312 /* Return a char pointer for a C string if it is a string constant
313 or sum of string constant and integer constant. */
315 static const char *
316 c_getstr (tree src)
318 tree offset_node;
320 src = string_constant (src, &offset_node);
321 if (src == 0)
322 return 0;
324 if (offset_node == 0)
325 return TREE_STRING_POINTER (src);
326 else if (!host_integerp (offset_node, 1)
327 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
328 return 0;
330 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
333 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
334 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
336 static rtx
337 c_readstr (const char *str, enum machine_mode mode)
339 HOST_WIDE_INT c[2];
340 HOST_WIDE_INT ch;
341 unsigned int i, j;
343 if (GET_MODE_CLASS (mode) != MODE_INT)
344 abort ();
345 c[0] = 0;
346 c[1] = 0;
347 ch = 1;
348 for (i = 0; i < GET_MODE_SIZE (mode); i++)
350 j = i;
351 if (WORDS_BIG_ENDIAN)
352 j = GET_MODE_SIZE (mode) - i - 1;
353 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
354 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
355 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
356 j *= BITS_PER_UNIT;
357 if (j > 2 * HOST_BITS_PER_WIDE_INT)
358 abort ();
359 if (ch)
360 ch = (unsigned char) str[i];
361 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
363 return immed_double_const (c[0], c[1], mode);
366 /* Cast a target constant CST to target CHAR and if that value fits into
367 host char type, return zero and put that value into variable pointed by
368 P. */
370 static int
371 target_char_cast (tree cst, char *p)
373 unsigned HOST_WIDE_INT val, hostval;
375 if (!host_integerp (cst, 1)
376 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
377 return 1;
379 val = tree_low_cst (cst, 1);
380 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
381 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
383 hostval = val;
384 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
385 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
387 if (val != hostval)
388 return 1;
390 *p = hostval;
391 return 0;
394 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
395 times to get the address of either a higher stack frame, or a return
396 address located within it (depending on FNDECL_CODE). */
399 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
400 rtx tem)
402 int i;
404 /* Some machines need special handling before we can access
405 arbitrary frames. For example, on the sparc, we must first flush
406 all register windows to the stack. */
407 #ifdef SETUP_FRAME_ADDRESSES
408 if (count > 0)
409 SETUP_FRAME_ADDRESSES ();
410 #endif
412 /* On the sparc, the return address is not in the frame, it is in a
413 register. There is no way to access it off of the current frame
414 pointer, but it can be accessed off the previous frame pointer by
415 reading the value from the register window save area. */
416 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
417 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
418 count--;
419 #endif
421 /* Scan back COUNT frames to the specified frame. */
422 for (i = 0; i < count; i++)
424 /* Assume the dynamic chain pointer is in the word that the
425 frame address points to, unless otherwise specified. */
426 #ifdef DYNAMIC_CHAIN_ADDRESS
427 tem = DYNAMIC_CHAIN_ADDRESS (tem);
428 #endif
429 tem = memory_address (Pmode, tem);
430 tem = gen_rtx_MEM (Pmode, tem);
431 set_mem_alias_set (tem, get_frame_alias_set ());
432 tem = copy_to_reg (tem);
435 /* For __builtin_frame_address, return what we've got. */
436 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
437 return tem;
439 /* For __builtin_return_address, Get the return address from that
440 frame. */
441 #ifdef RETURN_ADDR_RTX
442 tem = RETURN_ADDR_RTX (count, tem);
443 #else
444 tem = memory_address (Pmode,
445 plus_constant (tem, GET_MODE_SIZE (Pmode)));
446 tem = gen_rtx_MEM (Pmode, tem);
447 set_mem_alias_set (tem, get_frame_alias_set ());
448 #endif
449 return tem;
452 /* Alias set used for setjmp buffer. */
453 static HOST_WIDE_INT setjmp_alias_set = -1;
455 /* Construct the leading half of a __builtin_setjmp call. Control will
456 return to RECEIVER_LABEL. This is used directly by sjlj exception
457 handling code. */
459 void
460 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
462 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
463 rtx stack_save;
464 rtx mem;
466 if (setjmp_alias_set == -1)
467 setjmp_alias_set = new_alias_set ();
469 #ifdef POINTERS_EXTEND_UNSIGNED
470 if (GET_MODE (buf_addr) != Pmode)
471 buf_addr = convert_memory_address (Pmode, buf_addr);
472 #endif
474 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
476 emit_queue ();
478 /* We store the frame pointer and the address of receiver_label in
479 the buffer and use the rest of it for the stack save area, which
480 is machine-dependent. */
482 #ifndef BUILTIN_SETJMP_FRAME_VALUE
483 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
484 #endif
486 mem = gen_rtx_MEM (Pmode, buf_addr);
487 set_mem_alias_set (mem, setjmp_alias_set);
488 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
490 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
491 set_mem_alias_set (mem, setjmp_alias_set);
493 emit_move_insn (validize_mem (mem),
494 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
496 stack_save = gen_rtx_MEM (sa_mode,
497 plus_constant (buf_addr,
498 2 * GET_MODE_SIZE (Pmode)));
499 set_mem_alias_set (stack_save, setjmp_alias_set);
500 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
502 /* If there is further processing to do, do it. */
503 #ifdef HAVE_builtin_setjmp_setup
504 if (HAVE_builtin_setjmp_setup)
505 emit_insn (gen_builtin_setjmp_setup (buf_addr));
506 #endif
508 /* Tell optimize_save_area_alloca that extra work is going to
509 need to go on during alloca. */
510 current_function_calls_setjmp = 1;
512 /* Set this so all the registers get saved in our frame; we need to be
513 able to copy the saved values for any registers from frames we unwind. */
514 current_function_has_nonlocal_label = 1;
517 /* Construct the trailing part of a __builtin_setjmp call.
518 This is used directly by sjlj exception handling code. */
520 void
521 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
523 /* Clobber the FP when we get here, so we have to make sure it's
524 marked as used by this function. */
525 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
527 /* Mark the static chain as clobbered here so life information
528 doesn't get messed up for it. */
529 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
531 /* Now put in the code to restore the frame pointer, and argument
532 pointer, if needed. The code below is from expand_end_bindings
533 in stmt.c; see detailed documentation there. */
534 #ifdef HAVE_nonlocal_goto
535 if (! HAVE_nonlocal_goto)
536 #endif
537 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
539 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
540 if (fixed_regs[ARG_POINTER_REGNUM])
542 #ifdef ELIMINABLE_REGS
543 size_t i;
544 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
546 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
547 if (elim_regs[i].from == ARG_POINTER_REGNUM
548 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
549 break;
551 if (i == ARRAY_SIZE (elim_regs))
552 #endif
554 /* Now restore our arg pointer from the address at which it
555 was saved in our stack frame. */
556 emit_move_insn (virtual_incoming_args_rtx,
557 copy_to_reg (get_arg_pointer_save_area (cfun)));
560 #endif
562 #ifdef HAVE_builtin_setjmp_receiver
563 if (HAVE_builtin_setjmp_receiver)
564 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
565 else
566 #endif
567 #ifdef HAVE_nonlocal_goto_receiver
568 if (HAVE_nonlocal_goto_receiver)
569 emit_insn (gen_nonlocal_goto_receiver ());
570 else
571 #endif
572 { /* Nothing */ }
574 /* @@@ This is a kludge. Not all machine descriptions define a blockage
575 insn, but we must not allow the code we just generated to be reordered
576 by scheduling. Specifically, the update of the frame pointer must
577 happen immediately, not later. So emit an ASM_INPUT to act as blockage
578 insn. */
579 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
582 /* __builtin_setjmp is passed a pointer to an array of five words (not
583 all will be used on all machines). It operates similarly to the C
584 library function of the same name, but is more efficient. Much of
585 the code below (and for longjmp) is copied from the handling of
586 non-local gotos.
588 NOTE: This is intended for use by GNAT and the exception handling
589 scheme in the compiler and will only work in the method used by
590 them. */
592 static rtx
593 expand_builtin_setjmp (tree arglist, rtx target)
595 rtx buf_addr, next_lab, cont_lab;
597 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
598 return NULL_RTX;
600 if (target == 0 || GET_CODE (target) != REG
601 || REGNO (target) < FIRST_PSEUDO_REGISTER)
602 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
604 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
606 next_lab = gen_label_rtx ();
607 cont_lab = gen_label_rtx ();
609 expand_builtin_setjmp_setup (buf_addr, next_lab);
611 /* Set TARGET to zero and branch to the continue label. */
612 emit_move_insn (target, const0_rtx);
613 emit_jump_insn (gen_jump (cont_lab));
614 emit_barrier ();
615 emit_label (next_lab);
617 expand_builtin_setjmp_receiver (next_lab);
619 /* Set TARGET to one. */
620 emit_move_insn (target, const1_rtx);
621 emit_label (cont_lab);
623 /* Tell flow about the strange goings on. Putting `next_lab' on
624 `nonlocal_goto_handler_labels' to indicates that function
625 calls may traverse the arc back to this label. */
627 current_function_has_nonlocal_label = 1;
628 nonlocal_goto_handler_labels
629 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
631 return target;
634 /* __builtin_longjmp is passed a pointer to an array of five words (not
635 all will be used on all machines). It operates similarly to the C
636 library function of the same name, but is more efficient. Much of
637 the code below is copied from the handling of non-local gotos.
639 NOTE: This is intended for use by GNAT and the exception handling
640 scheme in the compiler and will only work in the method used by
641 them. */
643 void
644 expand_builtin_longjmp (rtx buf_addr, rtx value)
646 rtx fp, lab, stack, insn, last;
647 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
649 if (setjmp_alias_set == -1)
650 setjmp_alias_set = new_alias_set ();
652 #ifdef POINTERS_EXTEND_UNSIGNED
653 if (GET_MODE (buf_addr) != Pmode)
654 buf_addr = convert_memory_address (Pmode, buf_addr);
655 #endif
657 buf_addr = force_reg (Pmode, buf_addr);
659 /* We used to store value in static_chain_rtx, but that fails if pointers
660 are smaller than integers. We instead require that the user must pass
661 a second argument of 1, because that is what builtin_setjmp will
662 return. This also makes EH slightly more efficient, since we are no
663 longer copying around a value that we don't care about. */
664 if (value != const1_rtx)
665 abort ();
667 current_function_calls_longjmp = 1;
669 last = get_last_insn ();
670 #ifdef HAVE_builtin_longjmp
671 if (HAVE_builtin_longjmp)
672 emit_insn (gen_builtin_longjmp (buf_addr));
673 else
674 #endif
676 fp = gen_rtx_MEM (Pmode, buf_addr);
677 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
678 GET_MODE_SIZE (Pmode)));
680 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
681 2 * GET_MODE_SIZE (Pmode)));
682 set_mem_alias_set (fp, setjmp_alias_set);
683 set_mem_alias_set (lab, setjmp_alias_set);
684 set_mem_alias_set (stack, setjmp_alias_set);
686 /* Pick up FP, label, and SP from the block and jump. This code is
687 from expand_goto in stmt.c; see there for detailed comments. */
688 #if HAVE_nonlocal_goto
689 if (HAVE_nonlocal_goto)
690 /* We have to pass a value to the nonlocal_goto pattern that will
691 get copied into the static_chain pointer, but it does not matter
692 what that value is, because builtin_setjmp does not use it. */
693 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
694 else
695 #endif
697 lab = copy_to_reg (lab);
699 emit_move_insn (hard_frame_pointer_rtx, fp);
700 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
702 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
703 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
704 emit_indirect_jump (lab);
708 /* Search backwards and mark the jump insn as a non-local goto.
709 Note that this precludes the use of __builtin_longjmp to a
710 __builtin_setjmp target in the same function. However, we've
711 already cautioned the user that these functions are for
712 internal exception handling use only. */
713 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
715 if (insn == last)
716 abort ();
717 if (GET_CODE (insn) == JUMP_INSN)
719 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
720 REG_NOTES (insn));
721 break;
723 else if (GET_CODE (insn) == CALL_INSN)
724 break;
728 /* Expand a call to __builtin_prefetch. For a target that does not support
729 data prefetch, evaluate the memory address argument in case it has side
730 effects. */
732 static void
733 expand_builtin_prefetch (tree arglist)
735 tree arg0, arg1, arg2;
736 rtx op0, op1, op2;
738 if (!validate_arglist (arglist, POINTER_TYPE, 0))
739 return;
741 arg0 = TREE_VALUE (arglist);
742 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
743 zero (read) and argument 2 (locality) defaults to 3 (high degree of
744 locality). */
745 if (TREE_CHAIN (arglist))
747 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
748 if (TREE_CHAIN (TREE_CHAIN (arglist)))
749 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
750 else
751 arg2 = build_int_2 (3, 0);
753 else
755 arg1 = integer_zero_node;
756 arg2 = build_int_2 (3, 0);
759 /* Argument 0 is an address. */
760 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
762 /* Argument 1 (read/write flag) must be a compile-time constant int. */
763 if (TREE_CODE (arg1) != INTEGER_CST)
765 error ("second arg to `__builtin_prefetch' must be a constant");
766 arg1 = integer_zero_node;
768 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
769 /* Argument 1 must be either zero or one. */
770 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
772 warning ("invalid second arg to __builtin_prefetch; using zero");
773 op1 = const0_rtx;
776 /* Argument 2 (locality) must be a compile-time constant int. */
777 if (TREE_CODE (arg2) != INTEGER_CST)
779 error ("third arg to `__builtin_prefetch' must be a constant");
780 arg2 = integer_zero_node;
782 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
783 /* Argument 2 must be 0, 1, 2, or 3. */
784 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
786 warning ("invalid third arg to __builtin_prefetch; using zero");
787 op2 = const0_rtx;
790 #ifdef HAVE_prefetch
791 if (HAVE_prefetch)
793 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
794 (op0,
795 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
796 || (GET_MODE(op0) != Pmode))
798 #ifdef POINTERS_EXTEND_UNSIGNED
799 if (GET_MODE(op0) != Pmode)
800 op0 = convert_memory_address (Pmode, op0);
801 #endif
802 op0 = force_reg (Pmode, op0);
804 emit_insn (gen_prefetch (op0, op1, op2));
806 else
807 #endif
808 op0 = protect_from_queue (op0, 0);
809 /* Don't do anything with direct references to volatile memory, but
810 generate code to handle other side effects. */
811 if (GET_CODE (op0) != MEM && side_effects_p (op0))
812 emit_insn (op0);
815 /* Get a MEM rtx for expression EXP which is the address of an operand
816 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
818 static rtx
819 get_memory_rtx (tree exp)
821 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
822 rtx mem;
824 #ifdef POINTERS_EXTEND_UNSIGNED
825 if (GET_MODE (addr) != Pmode)
826 addr = convert_memory_address (Pmode, addr);
827 #endif
829 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
831 /* Get an expression we can use to find the attributes to assign to MEM.
832 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
833 we can. First remove any nops. */
834 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
835 || TREE_CODE (exp) == NON_LVALUE_EXPR)
836 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
837 exp = TREE_OPERAND (exp, 0);
839 if (TREE_CODE (exp) == ADDR_EXPR)
841 exp = TREE_OPERAND (exp, 0);
842 set_mem_attributes (mem, exp, 0);
844 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
846 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
847 /* memcpy, memset and other builtin stringops can alias with anything. */
848 set_mem_alias_set (mem, 0);
851 return mem;
854 /* Built-in functions to perform an untyped call and return. */
856 /* For each register that may be used for calling a function, this
857 gives a mode used to copy the register's value. VOIDmode indicates
858 the register is not used for calling a function. If the machine
859 has register windows, this gives only the outbound registers.
860 INCOMING_REGNO gives the corresponding inbound register. */
861 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
863 /* For each register that may be used for returning values, this gives
864 a mode used to copy the register's value. VOIDmode indicates the
865 register is not used for returning values. If the machine has
866 register windows, this gives only the outbound registers.
867 INCOMING_REGNO gives the corresponding inbound register. */
868 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
870 /* For each register that may be used for calling a function, this
871 gives the offset of that register into the block returned by
872 __builtin_apply_args. 0 indicates that the register is not
873 used for calling a function. */
874 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
876 /* Return the offset of register REGNO into the block returned by
877 __builtin_apply_args. This is not declared static, since it is
878 needed in objc-act.c. */
881 apply_args_register_offset (int regno)
883 apply_args_size ();
885 /* Arguments are always put in outgoing registers (in the argument
886 block) if such make sense. */
887 #ifdef OUTGOING_REGNO
888 regno = OUTGOING_REGNO (regno);
889 #endif
890 return apply_args_reg_offset[regno];
893 /* Return the size required for the block returned by __builtin_apply_args,
894 and initialize apply_args_mode. */
896 static int
897 apply_args_size (void)
899 static int size = -1;
900 int align;
901 unsigned int regno;
902 enum machine_mode mode;
904 /* The values computed by this function never change. */
905 if (size < 0)
907 /* The first value is the incoming arg-pointer. */
908 size = GET_MODE_SIZE (Pmode);
910 /* The second value is the structure value address unless this is
911 passed as an "invisible" first argument. */
912 if (struct_value_rtx)
913 size += GET_MODE_SIZE (Pmode);
915 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
916 if (FUNCTION_ARG_REGNO_P (regno))
918 /* Search for the proper mode for copying this register's
919 value. I'm not sure this is right, but it works so far. */
920 enum machine_mode best_mode = VOIDmode;
922 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
923 mode != VOIDmode;
924 mode = GET_MODE_WIDER_MODE (mode))
925 if (HARD_REGNO_MODE_OK (regno, mode)
926 && HARD_REGNO_NREGS (regno, mode) == 1)
927 best_mode = mode;
929 if (best_mode == VOIDmode)
930 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
931 mode != VOIDmode;
932 mode = GET_MODE_WIDER_MODE (mode))
933 if (HARD_REGNO_MODE_OK (regno, mode)
934 && have_insn_for (SET, mode))
935 best_mode = mode;
937 if (best_mode == VOIDmode)
938 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
939 mode != VOIDmode;
940 mode = GET_MODE_WIDER_MODE (mode))
941 if (HARD_REGNO_MODE_OK (regno, mode)
942 && have_insn_for (SET, mode))
943 best_mode = mode;
945 if (best_mode == VOIDmode)
946 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
947 mode != VOIDmode;
948 mode = GET_MODE_WIDER_MODE (mode))
949 if (HARD_REGNO_MODE_OK (regno, mode)
950 && have_insn_for (SET, mode))
951 best_mode = mode;
953 mode = best_mode;
954 if (mode == VOIDmode)
955 abort ();
957 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
958 if (size % align != 0)
959 size = CEIL (size, align) * align;
960 apply_args_reg_offset[regno] = size;
961 size += GET_MODE_SIZE (mode);
962 apply_args_mode[regno] = mode;
964 else
966 apply_args_mode[regno] = VOIDmode;
967 apply_args_reg_offset[regno] = 0;
970 return size;
973 /* Return the size required for the block returned by __builtin_apply,
974 and initialize apply_result_mode. */
976 static int
977 apply_result_size (void)
979 static int size = -1;
980 int align, regno;
981 enum machine_mode mode;
983 /* The values computed by this function never change. */
984 if (size < 0)
986 size = 0;
988 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
989 if (FUNCTION_VALUE_REGNO_P (regno))
991 /* Search for the proper mode for copying this register's
992 value. I'm not sure this is right, but it works so far. */
993 enum machine_mode best_mode = VOIDmode;
995 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
996 mode != TImode;
997 mode = GET_MODE_WIDER_MODE (mode))
998 if (HARD_REGNO_MODE_OK (regno, mode))
999 best_mode = mode;
1001 if (best_mode == VOIDmode)
1002 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1003 mode != VOIDmode;
1004 mode = GET_MODE_WIDER_MODE (mode))
1005 if (HARD_REGNO_MODE_OK (regno, mode)
1006 && have_insn_for (SET, mode))
1007 best_mode = mode;
1009 if (best_mode == VOIDmode)
1010 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1011 mode != VOIDmode;
1012 mode = GET_MODE_WIDER_MODE (mode))
1013 if (HARD_REGNO_MODE_OK (regno, mode)
1014 && have_insn_for (SET, mode))
1015 best_mode = mode;
1017 if (best_mode == VOIDmode)
1018 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1019 mode != VOIDmode;
1020 mode = GET_MODE_WIDER_MODE (mode))
1021 if (HARD_REGNO_MODE_OK (regno, mode)
1022 && have_insn_for (SET, mode))
1023 best_mode = mode;
1025 mode = best_mode;
1026 if (mode == VOIDmode)
1027 abort ();
1029 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1030 if (size % align != 0)
1031 size = CEIL (size, align) * align;
1032 size += GET_MODE_SIZE (mode);
1033 apply_result_mode[regno] = mode;
1035 else
1036 apply_result_mode[regno] = VOIDmode;
1038 /* Allow targets that use untyped_call and untyped_return to override
1039 the size so that machine-specific information can be stored here. */
1040 #ifdef APPLY_RESULT_SIZE
1041 size = APPLY_RESULT_SIZE;
1042 #endif
1044 return size;
1047 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1048 /* Create a vector describing the result block RESULT. If SAVEP is true,
1049 the result block is used to save the values; otherwise it is used to
1050 restore the values. */
1052 static rtx
1053 result_vector (int savep, rtx result)
1055 int regno, size, align, nelts;
1056 enum machine_mode mode;
1057 rtx reg, mem;
1058 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1060 size = nelts = 0;
1061 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1062 if ((mode = apply_result_mode[regno]) != VOIDmode)
1064 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1065 if (size % align != 0)
1066 size = CEIL (size, align) * align;
1067 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1068 mem = adjust_address (result, mode, size);
1069 savevec[nelts++] = (savep
1070 ? gen_rtx_SET (VOIDmode, mem, reg)
1071 : gen_rtx_SET (VOIDmode, reg, mem));
1072 size += GET_MODE_SIZE (mode);
1074 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1076 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1078 /* Save the state required to perform an untyped call with the same
1079 arguments as were passed to the current function. */
1081 static rtx
1082 expand_builtin_apply_args_1 (void)
1084 rtx registers;
1085 int size, align, regno;
1086 enum machine_mode mode;
1088 /* Create a block where the arg-pointer, structure value address,
1089 and argument registers can be saved. */
1090 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1092 /* Walk past the arg-pointer and structure value address. */
1093 size = GET_MODE_SIZE (Pmode);
1094 if (struct_value_rtx)
1095 size += GET_MODE_SIZE (Pmode);
1097 /* Save each register used in calling a function to the block. */
1098 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1099 if ((mode = apply_args_mode[regno]) != VOIDmode)
1101 rtx tem;
1103 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1104 if (size % align != 0)
1105 size = CEIL (size, align) * align;
1107 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1109 emit_move_insn (adjust_address (registers, mode, size), tem);
1110 size += GET_MODE_SIZE (mode);
1113 /* Save the arg pointer to the block. */
1114 emit_move_insn (adjust_address (registers, Pmode, 0),
1115 copy_to_reg (virtual_incoming_args_rtx));
1116 size = GET_MODE_SIZE (Pmode);
1118 /* Save the structure value address unless this is passed as an
1119 "invisible" first argument. */
1120 if (struct_value_incoming_rtx)
1122 emit_move_insn (adjust_address (registers, Pmode, size),
1123 copy_to_reg (struct_value_incoming_rtx));
1124 size += GET_MODE_SIZE (Pmode);
1127 /* Return the address of the block. */
1128 return copy_addr_to_reg (XEXP (registers, 0));
1131 /* __builtin_apply_args returns block of memory allocated on
1132 the stack into which is stored the arg pointer, structure
1133 value address, static chain, and all the registers that might
1134 possibly be used in performing a function call. The code is
1135 moved to the start of the function so the incoming values are
1136 saved. */
1138 static rtx
1139 expand_builtin_apply_args (void)
1141 /* Don't do __builtin_apply_args more than once in a function.
1142 Save the result of the first call and reuse it. */
1143 if (apply_args_value != 0)
1144 return apply_args_value;
1146 /* When this function is called, it means that registers must be
1147 saved on entry to this function. So we migrate the
1148 call to the first insn of this function. */
1149 rtx temp;
1150 rtx seq;
1152 start_sequence ();
1153 temp = expand_builtin_apply_args_1 ();
1154 seq = get_insns ();
1155 end_sequence ();
1157 apply_args_value = temp;
1159 /* Put the insns after the NOTE that starts the function.
1160 If this is inside a start_sequence, make the outer-level insn
1161 chain current, so the code is placed at the start of the
1162 function. */
1163 push_topmost_sequence ();
1164 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1165 pop_topmost_sequence ();
1166 return temp;
1170 /* Perform an untyped call and save the state required to perform an
1171 untyped return of whatever value was returned by the given function. */
1173 static rtx
1174 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1176 int size, align, regno;
1177 enum machine_mode mode;
1178 rtx incoming_args, result, reg, dest, src, call_insn;
1179 rtx old_stack_level = 0;
1180 rtx call_fusage = 0;
1182 #ifdef POINTERS_EXTEND_UNSIGNED
1183 if (GET_MODE (arguments) != Pmode)
1184 arguments = convert_memory_address (Pmode, arguments);
1185 #endif
1187 /* Create a block where the return registers can be saved. */
1188 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1190 /* Fetch the arg pointer from the ARGUMENTS block. */
1191 incoming_args = gen_reg_rtx (Pmode);
1192 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1193 #ifndef STACK_GROWS_DOWNWARD
1194 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1195 incoming_args, 0, OPTAB_LIB_WIDEN);
1196 #endif
1198 /* Perform postincrements before actually calling the function. */
1199 emit_queue ();
1201 /* Push a new argument block and copy the arguments. Do not allow
1202 the (potential) memcpy call below to interfere with our stack
1203 manipulations. */
1204 do_pending_stack_adjust ();
1205 NO_DEFER_POP;
1207 /* Save the stack with nonlocal if available */
1208 #ifdef HAVE_save_stack_nonlocal
1209 if (HAVE_save_stack_nonlocal)
1210 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1211 else
1212 #endif
1213 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1215 /* Push a block of memory onto the stack to store the memory arguments.
1216 Save the address in a register, and copy the memory arguments. ??? I
1217 haven't figured out how the calling convention macros effect this,
1218 but it's likely that the source and/or destination addresses in
1219 the block copy will need updating in machine specific ways. */
1220 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1221 dest = gen_rtx_MEM (BLKmode, dest);
1222 set_mem_align (dest, PARM_BOUNDARY);
1223 src = gen_rtx_MEM (BLKmode, incoming_args);
1224 set_mem_align (src, PARM_BOUNDARY);
1225 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1227 /* Refer to the argument block. */
1228 apply_args_size ();
1229 arguments = gen_rtx_MEM (BLKmode, arguments);
1230 set_mem_align (arguments, PARM_BOUNDARY);
1232 /* Walk past the arg-pointer and structure value address. */
1233 size = GET_MODE_SIZE (Pmode);
1234 if (struct_value_rtx)
1235 size += GET_MODE_SIZE (Pmode);
1237 /* Restore each of the registers previously saved. Make USE insns
1238 for each of these registers for use in making the call. */
1239 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1240 if ((mode = apply_args_mode[regno]) != VOIDmode)
1242 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1243 if (size % align != 0)
1244 size = CEIL (size, align) * align;
1245 reg = gen_rtx_REG (mode, regno);
1246 emit_move_insn (reg, adjust_address (arguments, mode, size));
1247 use_reg (&call_fusage, reg);
1248 size += GET_MODE_SIZE (mode);
1251 /* Restore the structure value address unless this is passed as an
1252 "invisible" first argument. */
1253 size = GET_MODE_SIZE (Pmode);
1254 if (struct_value_rtx)
1256 rtx value = gen_reg_rtx (Pmode);
1257 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1258 emit_move_insn (struct_value_rtx, value);
1259 if (GET_CODE (struct_value_rtx) == REG)
1260 use_reg (&call_fusage, struct_value_rtx);
1261 size += GET_MODE_SIZE (Pmode);
1264 /* All arguments and registers used for the call are set up by now! */
1265 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1267 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1268 and we don't want to load it into a register as an optimization,
1269 because prepare_call_address already did it if it should be done. */
1270 if (GET_CODE (function) != SYMBOL_REF)
1271 function = memory_address (FUNCTION_MODE, function);
1273 /* Generate the actual call instruction and save the return value. */
1274 #ifdef HAVE_untyped_call
1275 if (HAVE_untyped_call)
1276 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1277 result, result_vector (1, result)));
1278 else
1279 #endif
1280 #ifdef HAVE_call_value
1281 if (HAVE_call_value)
1283 rtx valreg = 0;
1285 /* Locate the unique return register. It is not possible to
1286 express a call that sets more than one return register using
1287 call_value; use untyped_call for that. In fact, untyped_call
1288 only needs to save the return registers in the given block. */
1289 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1290 if ((mode = apply_result_mode[regno]) != VOIDmode)
1292 if (valreg)
1293 abort (); /* HAVE_untyped_call required. */
1294 valreg = gen_rtx_REG (mode, regno);
1297 emit_call_insn (GEN_CALL_VALUE (valreg,
1298 gen_rtx_MEM (FUNCTION_MODE, function),
1299 const0_rtx, NULL_RTX, const0_rtx));
1301 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1303 else
1304 #endif
1305 abort ();
1307 /* Find the CALL insn we just emitted, and attach the register usage
1308 information. */
1309 call_insn = last_call_insn ();
1310 add_function_usage_to (call_insn, call_fusage);
1312 /* Restore the stack. */
1313 #ifdef HAVE_save_stack_nonlocal
1314 if (HAVE_save_stack_nonlocal)
1315 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1316 else
1317 #endif
1318 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1320 OK_DEFER_POP;
1322 /* Return the address of the result block. */
1323 return copy_addr_to_reg (XEXP (result, 0));
1326 /* Perform an untyped return. */
1328 static void
1329 expand_builtin_return (rtx result)
1331 int size, align, regno;
1332 enum machine_mode mode;
1333 rtx reg;
1334 rtx call_fusage = 0;
1336 #ifdef POINTERS_EXTEND_UNSIGNED
1337 if (GET_MODE (result) != Pmode)
1338 result = convert_memory_address (Pmode, result);
1339 #endif
1341 apply_result_size ();
1342 result = gen_rtx_MEM (BLKmode, result);
1344 #ifdef HAVE_untyped_return
1345 if (HAVE_untyped_return)
1347 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1348 emit_barrier ();
1349 return;
1351 #endif
1353 /* Restore the return value and note that each value is used. */
1354 size = 0;
1355 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1356 if ((mode = apply_result_mode[regno]) != VOIDmode)
1358 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1359 if (size % align != 0)
1360 size = CEIL (size, align) * align;
1361 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1362 emit_move_insn (reg, adjust_address (result, mode, size));
1364 push_to_sequence (call_fusage);
1365 emit_insn (gen_rtx_USE (VOIDmode, reg));
1366 call_fusage = get_insns ();
1367 end_sequence ();
1368 size += GET_MODE_SIZE (mode);
1371 /* Put the USE insns before the return. */
1372 emit_insn (call_fusage);
1374 /* Return whatever values was restored by jumping directly to the end
1375 of the function. */
1376 expand_null_return ();
1379 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1381 static enum type_class
1382 type_to_class (tree type)
1384 switch (TREE_CODE (type))
1386 case VOID_TYPE: return void_type_class;
1387 case INTEGER_TYPE: return integer_type_class;
1388 case CHAR_TYPE: return char_type_class;
1389 case ENUMERAL_TYPE: return enumeral_type_class;
1390 case BOOLEAN_TYPE: return boolean_type_class;
1391 case POINTER_TYPE: return pointer_type_class;
1392 case REFERENCE_TYPE: return reference_type_class;
1393 case OFFSET_TYPE: return offset_type_class;
1394 case REAL_TYPE: return real_type_class;
1395 case COMPLEX_TYPE: return complex_type_class;
1396 case FUNCTION_TYPE: return function_type_class;
1397 case METHOD_TYPE: return method_type_class;
1398 case RECORD_TYPE: return record_type_class;
1399 case UNION_TYPE:
1400 case QUAL_UNION_TYPE: return union_type_class;
1401 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1402 ? string_type_class : array_type_class);
1403 case SET_TYPE: return set_type_class;
1404 case FILE_TYPE: return file_type_class;
1405 case LANG_TYPE: return lang_type_class;
1406 default: return no_type_class;
1410 /* Expand a call to __builtin_classify_type with arguments found in
1411 ARGLIST. */
1413 static rtx
1414 expand_builtin_classify_type (tree arglist)
1416 if (arglist != 0)
1417 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1418 return GEN_INT (no_type_class);
1421 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1423 static rtx
1424 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1426 rtx tmp;
1428 if (arglist == 0)
1429 return const0_rtx;
1430 arglist = TREE_VALUE (arglist);
1432 /* We have taken care of the easy cases during constant folding. This
1433 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1434 get a chance to see if it can deduce whether ARGLIST is constant. */
1436 current_function_calls_constant_p = 1;
1438 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1439 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1440 return tmp;
1443 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1444 if available. */
1445 tree
1446 mathfn_built_in (tree type, enum built_in_function fn)
1448 enum built_in_function fcode = NOT_BUILT_IN;
1449 if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
1450 switch (fn)
1452 case BUILT_IN_SQRT:
1453 case BUILT_IN_SQRTF:
1454 case BUILT_IN_SQRTL:
1455 fcode = BUILT_IN_SQRT;
1456 break;
1457 case BUILT_IN_SIN:
1458 case BUILT_IN_SINF:
1459 case BUILT_IN_SINL:
1460 fcode = BUILT_IN_SIN;
1461 break;
1462 case BUILT_IN_COS:
1463 case BUILT_IN_COSF:
1464 case BUILT_IN_COSL:
1465 fcode = BUILT_IN_COS;
1466 break;
1467 case BUILT_IN_EXP:
1468 case BUILT_IN_EXPF:
1469 case BUILT_IN_EXPL:
1470 fcode = BUILT_IN_EXP;
1471 break;
1472 case BUILT_IN_LOG:
1473 case BUILT_IN_LOGF:
1474 case BUILT_IN_LOGL:
1475 fcode = BUILT_IN_LOG;
1476 break;
1477 case BUILT_IN_TAN:
1478 case BUILT_IN_TANF:
1479 case BUILT_IN_TANL:
1480 fcode = BUILT_IN_TAN;
1481 break;
1482 case BUILT_IN_ATAN:
1483 case BUILT_IN_ATANF:
1484 case BUILT_IN_ATANL:
1485 fcode = BUILT_IN_ATAN;
1486 break;
1487 case BUILT_IN_FLOOR:
1488 case BUILT_IN_FLOORF:
1489 case BUILT_IN_FLOORL:
1490 fcode = BUILT_IN_FLOOR;
1491 break;
1492 case BUILT_IN_CEIL:
1493 case BUILT_IN_CEILF:
1494 case BUILT_IN_CEILL:
1495 fcode = BUILT_IN_CEIL;
1496 break;
1497 case BUILT_IN_TRUNC:
1498 case BUILT_IN_TRUNCF:
1499 case BUILT_IN_TRUNCL:
1500 fcode = BUILT_IN_TRUNC;
1501 break;
1502 case BUILT_IN_ROUND:
1503 case BUILT_IN_ROUNDF:
1504 case BUILT_IN_ROUNDL:
1505 fcode = BUILT_IN_ROUND;
1506 break;
1507 case BUILT_IN_NEARBYINT:
1508 case BUILT_IN_NEARBYINTF:
1509 case BUILT_IN_NEARBYINTL:
1510 fcode = BUILT_IN_NEARBYINT;
1511 break;
1512 default:
1513 abort ();
1515 else if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
1516 switch (fn)
1518 case BUILT_IN_SQRT:
1519 case BUILT_IN_SQRTF:
1520 case BUILT_IN_SQRTL:
1521 fcode = BUILT_IN_SQRTF;
1522 break;
1523 case BUILT_IN_SIN:
1524 case BUILT_IN_SINF:
1525 case BUILT_IN_SINL:
1526 fcode = BUILT_IN_SINF;
1527 break;
1528 case BUILT_IN_COS:
1529 case BUILT_IN_COSF:
1530 case BUILT_IN_COSL:
1531 fcode = BUILT_IN_COSF;
1532 break;
1533 case BUILT_IN_EXP:
1534 case BUILT_IN_EXPF:
1535 case BUILT_IN_EXPL:
1536 fcode = BUILT_IN_EXPF;
1537 break;
1538 case BUILT_IN_LOG:
1539 case BUILT_IN_LOGF:
1540 case BUILT_IN_LOGL:
1541 fcode = BUILT_IN_LOGF;
1542 break;
1543 case BUILT_IN_TAN:
1544 case BUILT_IN_TANF:
1545 case BUILT_IN_TANL:
1546 fcode = BUILT_IN_TANF;
1547 break;
1548 case BUILT_IN_ATAN:
1549 case BUILT_IN_ATANF:
1550 case BUILT_IN_ATANL:
1551 fcode = BUILT_IN_ATANF;
1552 break;
1553 case BUILT_IN_FLOOR:
1554 case BUILT_IN_FLOORF:
1555 case BUILT_IN_FLOORL:
1556 fcode = BUILT_IN_FLOORF;
1557 break;
1558 case BUILT_IN_CEIL:
1559 case BUILT_IN_CEILF:
1560 case BUILT_IN_CEILL:
1561 fcode = BUILT_IN_CEILF;
1562 break;
1563 case BUILT_IN_TRUNC:
1564 case BUILT_IN_TRUNCF:
1565 case BUILT_IN_TRUNCL:
1566 fcode = BUILT_IN_TRUNCF;
1567 break;
1568 case BUILT_IN_ROUND:
1569 case BUILT_IN_ROUNDF:
1570 case BUILT_IN_ROUNDL:
1571 fcode = BUILT_IN_ROUNDF;
1572 break;
1573 case BUILT_IN_NEARBYINT:
1574 case BUILT_IN_NEARBYINTF:
1575 case BUILT_IN_NEARBYINTL:
1576 fcode = BUILT_IN_NEARBYINTF;
1577 break;
1578 default:
1579 abort ();
1581 else if (TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
1582 switch (fn)
1584 case BUILT_IN_SQRT:
1585 case BUILT_IN_SQRTF:
1586 case BUILT_IN_SQRTL:
1587 fcode = BUILT_IN_SQRTL;
1588 break;
1589 case BUILT_IN_SIN:
1590 case BUILT_IN_SINF:
1591 case BUILT_IN_SINL:
1592 fcode = BUILT_IN_SINL;
1593 break;
1594 case BUILT_IN_COS:
1595 case BUILT_IN_COSF:
1596 case BUILT_IN_COSL:
1597 fcode = BUILT_IN_COSL;
1598 break;
1599 case BUILT_IN_EXP:
1600 case BUILT_IN_EXPF:
1601 case BUILT_IN_EXPL:
1602 fcode = BUILT_IN_EXPL;
1603 break;
1604 case BUILT_IN_LOG:
1605 case BUILT_IN_LOGF:
1606 case BUILT_IN_LOGL:
1607 fcode = BUILT_IN_LOGL;
1608 break;
1609 case BUILT_IN_TAN:
1610 case BUILT_IN_TANF:
1611 case BUILT_IN_TANL:
1612 fcode = BUILT_IN_TANL;
1613 break;
1614 case BUILT_IN_ATAN:
1615 case BUILT_IN_ATANF:
1616 case BUILT_IN_ATANL:
1617 fcode = BUILT_IN_ATANL;
1618 break;
1619 case BUILT_IN_FLOOR:
1620 case BUILT_IN_FLOORF:
1621 case BUILT_IN_FLOORL:
1622 fcode = BUILT_IN_FLOORL;
1623 break;
1624 case BUILT_IN_CEIL:
1625 case BUILT_IN_CEILF:
1626 case BUILT_IN_CEILL:
1627 fcode = BUILT_IN_CEILL;
1628 break;
1629 case BUILT_IN_TRUNC:
1630 case BUILT_IN_TRUNCF:
1631 case BUILT_IN_TRUNCL:
1632 fcode = BUILT_IN_TRUNCL;
1633 break;
1634 case BUILT_IN_ROUND:
1635 case BUILT_IN_ROUNDF:
1636 case BUILT_IN_ROUNDL:
1637 fcode = BUILT_IN_ROUNDL;
1638 break;
1639 case BUILT_IN_NEARBYINT:
1640 case BUILT_IN_NEARBYINTF:
1641 case BUILT_IN_NEARBYINTL:
1642 fcode = BUILT_IN_NEARBYINTL;
1643 break;
1644 default:
1645 abort ();
1647 return implicit_built_in_decls[fcode];
1650 /* If errno must be maintained, expand the RTL to check if the result,
1651 TARGET, of a built-in function call, EXP, is NaN, and if so set
1652 errno to EDOM. */
1654 static void
1655 expand_errno_check (tree exp, rtx target)
1657 rtx lab = gen_label_rtx ();
1659 /* Test the result; if it is NaN, set errno=EDOM because
1660 the argument was not in the domain. */
1661 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1662 0, lab);
1664 #ifdef TARGET_EDOM
1665 /* If this built-in doesn't throw an exception, set errno directly. */
1666 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1668 #ifdef GEN_ERRNO_RTX
1669 rtx errno_rtx = GEN_ERRNO_RTX;
1670 #else
1671 rtx errno_rtx
1672 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1673 #endif
1674 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1675 emit_label (lab);
1676 return;
1678 #endif
1680 /* We can't set errno=EDOM directly; let the library call do it.
1681 Pop the arguments right away in case the call gets deleted. */
1682 NO_DEFER_POP;
1683 expand_call (exp, target, 0);
1684 OK_DEFER_POP;
1685 emit_label (lab);
1689 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1690 Return 0 if a normal call should be emitted rather than expanding the
1691 function in-line. EXP is the expression that is a call to the builtin
1692 function; if convenient, the result should be placed in TARGET.
1693 SUBTARGET may be used as the target for computing one of EXP's operands. */
1695 static rtx
1696 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1698 optab builtin_optab;
1699 rtx op0, insns;
1700 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1701 tree arglist = TREE_OPERAND (exp, 1);
1702 enum machine_mode mode;
1703 bool errno_set = false;
1704 tree arg;
1706 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1707 return 0;
1709 arg = TREE_VALUE (arglist);
1711 switch (DECL_FUNCTION_CODE (fndecl))
1713 case BUILT_IN_SIN:
1714 case BUILT_IN_SINF:
1715 case BUILT_IN_SINL:
1716 builtin_optab = sin_optab; break;
1717 case BUILT_IN_COS:
1718 case BUILT_IN_COSF:
1719 case BUILT_IN_COSL:
1720 builtin_optab = cos_optab; break;
1721 case BUILT_IN_SQRT:
1722 case BUILT_IN_SQRTF:
1723 case BUILT_IN_SQRTL:
1724 errno_set = ! tree_expr_nonnegative_p (arg);
1725 builtin_optab = sqrt_optab;
1726 break;
1727 case BUILT_IN_EXP:
1728 case BUILT_IN_EXPF:
1729 case BUILT_IN_EXPL:
1730 errno_set = true; builtin_optab = exp_optab; break;
1731 case BUILT_IN_LOG:
1732 case BUILT_IN_LOGF:
1733 case BUILT_IN_LOGL:
1734 errno_set = true; builtin_optab = log_optab; break;
1735 case BUILT_IN_TAN:
1736 case BUILT_IN_TANF:
1737 case BUILT_IN_TANL:
1738 builtin_optab = tan_optab; break;
1739 case BUILT_IN_ATAN:
1740 case BUILT_IN_ATANF:
1741 case BUILT_IN_ATANL:
1742 builtin_optab = atan_optab; break;
1743 case BUILT_IN_FLOOR:
1744 case BUILT_IN_FLOORF:
1745 case BUILT_IN_FLOORL:
1746 builtin_optab = floor_optab; break;
1747 case BUILT_IN_CEIL:
1748 case BUILT_IN_CEILF:
1749 case BUILT_IN_CEILL:
1750 builtin_optab = ceil_optab; break;
1751 case BUILT_IN_TRUNC:
1752 case BUILT_IN_TRUNCF:
1753 case BUILT_IN_TRUNCL:
1754 builtin_optab = trunc_optab; break;
1755 case BUILT_IN_ROUND:
1756 case BUILT_IN_ROUNDF:
1757 case BUILT_IN_ROUNDL:
1758 builtin_optab = round_optab; break;
1759 case BUILT_IN_NEARBYINT:
1760 case BUILT_IN_NEARBYINTF:
1761 case BUILT_IN_NEARBYINTL:
1762 builtin_optab = nearbyint_optab; break;
1763 default:
1764 abort ();
1767 /* Make a suitable register to place result in. */
1768 mode = TYPE_MODE (TREE_TYPE (exp));
1769 target = gen_reg_rtx (mode);
1771 if (! flag_errno_math || ! HONOR_NANS (mode))
1772 errno_set = false;
1774 /* Stabilize and compute the argument. */
1775 if (errno_set)
1776 switch (TREE_CODE (arg))
1778 case VAR_DECL:
1779 case PARM_DECL:
1780 case SAVE_EXPR:
1781 case REAL_CST:
1782 break;
1784 default:
1785 /* Wrap the computation of the argument in a SAVE_EXPR, as we
1786 need to expand the argument again in expand_errno_check. This
1787 way, we will not perform side-effects more the once. */
1788 arg = save_expr (arg);
1789 arglist = build_tree_list (NULL_TREE, arg);
1790 exp = build_function_call_expr (fndecl, arglist);
1791 break;
1794 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1796 emit_queue ();
1797 start_sequence ();
1799 /* Compute into TARGET.
1800 Set TARGET to wherever the result comes back. */
1801 target = expand_unop (mode, builtin_optab, op0, target, 0);
1803 /* If we were unable to expand via the builtin, stop the
1804 sequence (without outputting the insns) and return 0, causing
1805 a call to the library function. */
1806 if (target == 0)
1808 end_sequence ();
1809 return 0;
1812 if (errno_set)
1813 expand_errno_check (exp, target);
1815 /* Output the entire sequence. */
1816 insns = get_insns ();
1817 end_sequence ();
1818 emit_insn (insns);
1820 return target;
1823 /* Expand a call to the builtin binary math functions (pow and atan2).
1824 Return 0 if a normal call should be emitted rather than expanding the
1825 function in-line. EXP is the expression that is a call to the builtin
1826 function; if convenient, the result should be placed in TARGET.
1827 SUBTARGET may be used as the target for computing one of EXP's
1828 operands. */
1830 static rtx
1831 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1833 optab builtin_optab;
1834 rtx op0, op1, insns;
1835 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1836 tree arglist = TREE_OPERAND (exp, 1);
1837 tree arg0, arg1, temp;
1838 enum machine_mode mode;
1839 bool errno_set = true;
1840 bool stable = true;
1842 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1843 return 0;
1845 arg0 = TREE_VALUE (arglist);
1846 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1848 switch (DECL_FUNCTION_CODE (fndecl))
1850 case BUILT_IN_POW:
1851 case BUILT_IN_POWF:
1852 case BUILT_IN_POWL:
1853 builtin_optab = pow_optab; break;
1854 case BUILT_IN_ATAN2:
1855 case BUILT_IN_ATAN2F:
1856 case BUILT_IN_ATAN2L:
1857 builtin_optab = atan2_optab; break;
1858 default:
1859 abort ();
1862 /* Make a suitable register to place result in. */
1863 mode = TYPE_MODE (TREE_TYPE (exp));
1864 target = gen_reg_rtx (mode);
1866 if (! flag_errno_math || ! HONOR_NANS (mode))
1867 errno_set = false;
1869 /* Stabilize the arguments. */
1870 if (errno_set)
1872 switch (TREE_CODE (arg1))
1874 case VAR_DECL:
1875 case PARM_DECL:
1876 case SAVE_EXPR:
1877 case REAL_CST:
1878 temp = TREE_CHAIN (arglist);
1879 break;
1881 default:
1882 stable = false;
1883 arg1 = save_expr (arg1);
1884 temp = build_tree_list (NULL_TREE, arg1);
1885 break;
1888 switch (TREE_CODE (arg0))
1890 case VAR_DECL:
1891 case PARM_DECL:
1892 case SAVE_EXPR:
1893 case REAL_CST:
1894 if (! stable)
1895 arglist = tree_cons (NULL_TREE, arg0, temp);
1896 break;
1898 default:
1899 stable = false;
1900 arg0 = save_expr (arg0);
1901 arglist = tree_cons (NULL_TREE, arg0, temp);
1902 break;
1905 if (! stable)
1906 exp = build_function_call_expr (fndecl, arglist);
1909 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1910 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1912 emit_queue ();
1913 start_sequence ();
1915 /* Compute into TARGET.
1916 Set TARGET to wherever the result comes back. */
1917 target = expand_binop (mode, builtin_optab, op0, op1,
1918 target, 0, OPTAB_DIRECT);
1920 /* If we were unable to expand via the builtin, stop the
1921 sequence (without outputting the insns) and return 0, causing
1922 a call to the library function. */
1923 if (target == 0)
1925 end_sequence ();
1926 return 0;
1929 if (errno_set)
1930 expand_errno_check (exp, target);
1932 /* Output the entire sequence. */
1933 insns = get_insns ();
1934 end_sequence ();
1935 emit_insn (insns);
1937 return target;
1940 /* To evaluate powi(x,n), the floating point value x raised to the
1941 constant integer exponent n, we use a hybrid algorithm that
1942 combines the "window method" with look-up tables. For an
1943 introduction to exponentiation algorithms and "addition chains",
1944 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1945 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1946 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1947 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1949 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1950 multiplications to inline before calling the system library's pow
1951 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1952 so this default never requires calling pow, powf or powl. */
1954 #ifndef POWI_MAX_MULTS
1955 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1956 #endif
1958 /* The size of the "optimal power tree" lookup table. All
1959 exponents less than this value are simply looked up in the
1960 powi_table below. This threshold is also used to size the
1961 cache of pseudo registers that hold intermediate results. */
1962 #define POWI_TABLE_SIZE 256
1964 /* The size, in bits of the window, used in the "window method"
1965 exponentiation algorithm. This is equivalent to a radix of
1966 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1967 #define POWI_WINDOW_SIZE 3
1969 /* The following table is an efficient representation of an
1970 "optimal power tree". For each value, i, the corresponding
1971 value, j, in the table states than an optimal evaluation
1972 sequence for calculating pow(x,i) can be found by evaluating
1973 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1974 100 integers is given in Knuth's "Seminumerical algorithms". */
1976 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1978 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1979 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1980 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1981 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1982 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1983 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1984 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1985 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1986 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1987 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1988 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1989 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1990 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1991 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1992 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1993 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1994 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1995 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1996 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1997 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1998 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1999 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2000 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2001 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2002 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2003 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2004 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2005 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2006 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2007 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2008 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2009 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2013 /* Return the number of multiplications required to calculate
2014 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2015 subroutine of powi_cost. CACHE is an array indicating
2016 which exponents have already been calculated. */
2018 static int
2019 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2021 /* If we've already calculated this exponent, then this evaluation
2022 doesn't require any additional multiplications. */
2023 if (cache[n])
2024 return 0;
2026 cache[n] = true;
2027 return powi_lookup_cost (n - powi_table[n], cache)
2028 + powi_lookup_cost (powi_table[n], cache) + 1;
2031 /* Return the number of multiplications required to calculate
2032 powi(x,n) for an arbitrary x, given the exponent N. This
2033 function needs to be kept in sync with expand_powi below. */
2035 static int
2036 powi_cost (HOST_WIDE_INT n)
2038 bool cache[POWI_TABLE_SIZE];
2039 unsigned HOST_WIDE_INT digit;
2040 unsigned HOST_WIDE_INT val;
2041 int result;
2043 if (n == 0)
2044 return 0;
2046 /* Ignore the reciprocal when calculating the cost. */
2047 val = (n < 0) ? -n : n;
2049 /* Initialize the exponent cache. */
2050 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2051 cache[1] = true;
2053 result = 0;
2055 while (val >= POWI_TABLE_SIZE)
2057 if (val & 1)
2059 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2060 result += powi_lookup_cost (digit, cache)
2061 + POWI_WINDOW_SIZE + 1;
2062 val >>= POWI_WINDOW_SIZE;
2064 else
2066 val >>= 1;
2067 result++;
2071 return result + powi_lookup_cost (val, cache);
2074 /* Recursive subroutine of expand_powi. This function takes the array,
2075 CACHE, of already calculated exponents and an exponent N and returns
2076 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2078 static rtx
2079 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2081 unsigned HOST_WIDE_INT digit;
2082 rtx target, result;
2083 rtx op0, op1;
2085 if (n < POWI_TABLE_SIZE)
2087 if (cache[n])
2088 return cache[n];
2090 target = gen_reg_rtx (mode);
2091 cache[n] = target;
2093 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2094 op1 = expand_powi_1 (mode, powi_table[n], cache);
2096 else if (n & 1)
2098 target = gen_reg_rtx (mode);
2099 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2100 op0 = expand_powi_1 (mode, n - digit, cache);
2101 op1 = expand_powi_1 (mode, digit, cache);
2103 else
2105 target = gen_reg_rtx (mode);
2106 op0 = expand_powi_1 (mode, n >> 1, cache);
2107 op1 = op0;
2110 result = expand_mult (mode, op0, op1, target, 0);
2111 if (result != target)
2112 emit_move_insn (target, result);
2113 return target;
2116 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2117 floating point operand in mode MODE, and N is the exponent. This
2118 function needs to be kept in sync with powi_cost above. */
2120 static rtx
2121 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2123 unsigned HOST_WIDE_INT val;
2124 rtx cache[POWI_TABLE_SIZE];
2125 rtx result;
2127 if (n == 0)
2128 return CONST1_RTX (mode);
2130 val = (n < 0) ? -n : n;
2132 memset (cache, 0, sizeof(cache));
2133 cache[1] = x;
2135 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2137 /* If the original exponent was negative, reciprocate the result. */
2138 if (n < 0)
2139 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2140 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2142 return result;
2145 /* Expand a call to the pow built-in mathematical function. Return 0 if
2146 a normal call should be emitted rather than expanding the function
2147 in-line. EXP is the expression that is a call to the builtin
2148 function; if convenient, the result should be placed in TARGET. */
2150 static rtx
2151 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2153 tree arglist = TREE_OPERAND (exp, 1);
2154 tree arg0, arg1;
2156 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2157 return 0;
2159 arg0 = TREE_VALUE (arglist);
2160 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2162 if (flag_unsafe_math_optimizations
2163 && ! flag_errno_math
2164 && ! optimize_size
2165 && TREE_CODE (arg1) == REAL_CST
2166 && ! TREE_CONSTANT_OVERFLOW (arg1))
2168 REAL_VALUE_TYPE cint;
2169 REAL_VALUE_TYPE c;
2170 HOST_WIDE_INT n;
2172 c = TREE_REAL_CST (arg1);
2173 n = real_to_integer (&c);
2174 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2175 if (real_identical (&c, &cint)
2176 && powi_cost (n) <= POWI_MAX_MULTS)
2178 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2179 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2180 op = force_reg (mode, op);
2181 return expand_powi (op, mode, n);
2184 return expand_builtin_mathfn_2 (exp, target, NULL_RTX);
2187 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2188 if we failed the caller should emit a normal call, otherwise
2189 try to get the result in TARGET, if convenient. */
2191 static rtx
2192 expand_builtin_strlen (tree arglist, rtx target,
2193 enum machine_mode target_mode)
2195 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2196 return 0;
2197 else
2199 rtx pat;
2200 tree len, src = TREE_VALUE (arglist);
2201 rtx result, src_reg, char_rtx, before_strlen;
2202 enum machine_mode insn_mode = target_mode, char_mode;
2203 enum insn_code icode = CODE_FOR_nothing;
2204 int align;
2206 /* If the length can be computed at compile-time, return it. */
2207 len = c_strlen (src);
2208 if (len)
2209 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2211 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2213 /* If SRC is not a pointer type, don't do this operation inline. */
2214 if (align == 0)
2215 return 0;
2217 /* Bail out if we can't compute strlen in the right mode. */
2218 while (insn_mode != VOIDmode)
2220 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2221 if (icode != CODE_FOR_nothing)
2222 break;
2224 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2226 if (insn_mode == VOIDmode)
2227 return 0;
2229 /* Make a place to write the result of the instruction. */
2230 result = target;
2231 if (! (result != 0
2232 && GET_CODE (result) == REG
2233 && GET_MODE (result) == insn_mode
2234 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2235 result = gen_reg_rtx (insn_mode);
2237 /* Make a place to hold the source address. We will not expand
2238 the actual source until we are sure that the expansion will
2239 not fail -- there are trees that cannot be expanded twice. */
2240 src_reg = gen_reg_rtx (Pmode);
2242 /* Mark the beginning of the strlen sequence so we can emit the
2243 source operand later. */
2244 before_strlen = get_last_insn ();
2246 char_rtx = const0_rtx;
2247 char_mode = insn_data[(int) icode].operand[2].mode;
2248 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2249 char_mode))
2250 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2252 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2253 char_rtx, GEN_INT (align));
2254 if (! pat)
2255 return 0;
2256 emit_insn (pat);
2258 /* Now that we are assured of success, expand the source. */
2259 start_sequence ();
2260 pat = memory_address (BLKmode,
2261 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2262 if (pat != src_reg)
2263 emit_move_insn (src_reg, pat);
2264 pat = get_insns ();
2265 end_sequence ();
2267 if (before_strlen)
2268 emit_insn_after (pat, before_strlen);
2269 else
2270 emit_insn_before (pat, get_insns ());
2272 /* Return the value in the proper mode for this function. */
2273 if (GET_MODE (result) == target_mode)
2274 target = result;
2275 else if (target != 0)
2276 convert_move (target, result, 0);
2277 else
2278 target = convert_to_mode (target_mode, result, 0);
2280 return target;
2284 /* Expand a call to the strstr builtin. Return 0 if we failed the
2285 caller should emit a normal call, otherwise try to get the result
2286 in TARGET, if convenient (and in mode MODE if that's convenient). */
2288 static rtx
2289 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2291 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2292 return 0;
2293 else
2295 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2296 tree fn;
2297 const char *p1, *p2;
2299 p2 = c_getstr (s2);
2300 if (p2 == NULL)
2301 return 0;
2303 p1 = c_getstr (s1);
2304 if (p1 != NULL)
2306 const char *r = strstr (p1, p2);
2308 if (r == NULL)
2309 return const0_rtx;
2311 /* Return an offset into the constant string argument. */
2312 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2313 s1, ssize_int (r - p1))),
2314 target, mode, EXPAND_NORMAL);
2317 if (p2[0] == '\0')
2318 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2320 if (p2[1] != '\0')
2321 return 0;
2323 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2324 if (!fn)
2325 return 0;
2327 /* New argument list transforming strstr(s1, s2) to
2328 strchr(s1, s2[0]). */
2329 arglist =
2330 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2331 arglist = tree_cons (NULL_TREE, s1, arglist);
2332 return expand_expr (build_function_call_expr (fn, arglist),
2333 target, mode, EXPAND_NORMAL);
2337 /* Expand a call to the strchr builtin. Return 0 if we failed the
2338 caller should emit a normal call, otherwise try to get the result
2339 in TARGET, if convenient (and in mode MODE if that's convenient). */
2341 static rtx
2342 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2344 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2345 return 0;
2346 else
2348 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2349 const char *p1;
2351 if (TREE_CODE (s2) != INTEGER_CST)
2352 return 0;
2354 p1 = c_getstr (s1);
2355 if (p1 != NULL)
2357 char c;
2358 const char *r;
2360 if (target_char_cast (s2, &c))
2361 return 0;
2363 r = strchr (p1, c);
2365 if (r == NULL)
2366 return const0_rtx;
2368 /* Return an offset into the constant string argument. */
2369 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2370 s1, ssize_int (r - p1))),
2371 target, mode, EXPAND_NORMAL);
2374 /* FIXME: Should use here strchrM optab so that ports can optimize
2375 this. */
2376 return 0;
2380 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2381 caller should emit a normal call, otherwise try to get the result
2382 in TARGET, if convenient (and in mode MODE if that's convenient). */
2384 static rtx
2385 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2387 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2388 return 0;
2389 else
2391 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2392 tree fn;
2393 const char *p1;
2395 if (TREE_CODE (s2) != INTEGER_CST)
2396 return 0;
2398 p1 = c_getstr (s1);
2399 if (p1 != NULL)
2401 char c;
2402 const char *r;
2404 if (target_char_cast (s2, &c))
2405 return 0;
2407 r = strrchr (p1, c);
2409 if (r == NULL)
2410 return const0_rtx;
2412 /* Return an offset into the constant string argument. */
2413 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2414 s1, ssize_int (r - p1))),
2415 target, mode, EXPAND_NORMAL);
2418 if (! integer_zerop (s2))
2419 return 0;
2421 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2422 if (!fn)
2423 return 0;
2425 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2426 return expand_expr (build_function_call_expr (fn, arglist),
2427 target, mode, EXPAND_NORMAL);
2431 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2432 caller should emit a normal call, otherwise try to get the result
2433 in TARGET, if convenient (and in mode MODE if that's convenient). */
2435 static rtx
2436 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2438 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2439 return 0;
2440 else
2442 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2443 tree fn;
2444 const char *p1, *p2;
2446 p2 = c_getstr (s2);
2447 if (p2 == NULL)
2448 return 0;
2450 p1 = c_getstr (s1);
2451 if (p1 != NULL)
2453 const char *r = strpbrk (p1, p2);
2455 if (r == NULL)
2456 return const0_rtx;
2458 /* Return an offset into the constant string argument. */
2459 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2460 s1, ssize_int (r - p1))),
2461 target, mode, EXPAND_NORMAL);
2464 if (p2[0] == '\0')
2466 /* strpbrk(x, "") == NULL.
2467 Evaluate and ignore the arguments in case they had
2468 side-effects. */
2469 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2470 return const0_rtx;
2473 if (p2[1] != '\0')
2474 return 0; /* Really call strpbrk. */
2476 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2477 if (!fn)
2478 return 0;
2480 /* New argument list transforming strpbrk(s1, s2) to
2481 strchr(s1, s2[0]). */
2482 arglist =
2483 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2484 arglist = tree_cons (NULL_TREE, s1, arglist);
2485 return expand_expr (build_function_call_expr (fn, arglist),
2486 target, mode, EXPAND_NORMAL);
2490 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2491 bytes from constant string DATA + OFFSET and return it as target
2492 constant. */
2494 static rtx
2495 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2496 enum machine_mode mode)
2498 const char *str = (const char *) data;
2500 if (offset < 0
2501 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2502 > strlen (str) + 1))
2503 abort (); /* Attempt to read past the end of constant string. */
2505 return c_readstr (str + offset, mode);
2508 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2509 Return 0 if we failed, the caller should emit a normal call,
2510 otherwise try to get the result in TARGET, if convenient (and in
2511 mode MODE if that's convenient). */
2512 static rtx
2513 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2515 if (!validate_arglist (arglist,
2516 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2517 return 0;
2518 else
2520 tree dest = TREE_VALUE (arglist);
2521 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2522 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2523 const char *src_str;
2524 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2525 unsigned int dest_align
2526 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2527 rtx dest_mem, src_mem, dest_addr, len_rtx;
2529 /* If DEST is not a pointer type, call the normal function. */
2530 if (dest_align == 0)
2531 return 0;
2533 /* If the LEN parameter is zero, return DEST. */
2534 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2536 /* Evaluate and ignore SRC in case it has side-effects. */
2537 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2538 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2541 /* If either SRC is not a pointer type, don't do this
2542 operation in-line. */
2543 if (src_align == 0)
2544 return 0;
2546 dest_mem = get_memory_rtx (dest);
2547 set_mem_align (dest_mem, dest_align);
2548 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2549 src_str = c_getstr (src);
2551 /* If SRC is a string constant and block move would be done
2552 by pieces, we can avoid loading the string from memory
2553 and only stored the computed constants. */
2554 if (src_str
2555 && GET_CODE (len_rtx) == CONST_INT
2556 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2557 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2558 (void *) src_str, dest_align))
2560 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2561 builtin_memcpy_read_str,
2562 (void *) src_str, dest_align, 0);
2563 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2564 #ifdef POINTERS_EXTEND_UNSIGNED
2565 if (GET_MODE (dest_mem) != ptr_mode)
2566 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2567 #endif
2568 return dest_mem;
2571 src_mem = get_memory_rtx (src);
2572 set_mem_align (src_mem, src_align);
2574 /* Copy word part most expediently. */
2575 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2576 BLOCK_OP_NORMAL);
2578 if (dest_addr == 0)
2580 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2581 #ifdef POINTERS_EXTEND_UNSIGNED
2582 if (GET_MODE (dest_addr) != ptr_mode)
2583 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2584 #endif
2586 return dest_addr;
2590 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2591 Return 0 if we failed the caller should emit a normal call,
2592 otherwise try to get the result in TARGET, if convenient (and in
2593 mode MODE if that's convenient). If ENDP is 0 return the
2594 destination pointer, if ENDP is 1 return the end pointer ala
2595 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2596 stpcpy. */
2598 static rtx
2599 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2600 int endp)
2602 if (!validate_arglist (arglist,
2603 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2604 return 0;
2605 /* If return value is ignored, transform mempcpy into memcpy. */
2606 else if (target == const0_rtx)
2608 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2610 if (!fn)
2611 return 0;
2613 return expand_expr (build_function_call_expr (fn, arglist),
2614 target, mode, EXPAND_NORMAL);
2616 else
2618 tree dest = TREE_VALUE (arglist);
2619 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2620 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2621 const char *src_str;
2622 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2623 unsigned int dest_align
2624 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2625 rtx dest_mem, src_mem, len_rtx;
2627 /* If DEST is not a pointer type or LEN is not constant,
2628 call the normal function. */
2629 if (dest_align == 0 || !host_integerp (len, 1))
2630 return 0;
2632 /* If the LEN parameter is zero, return DEST. */
2633 if (tree_low_cst (len, 1) == 0)
2635 /* Evaluate and ignore SRC in case it has side-effects. */
2636 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2637 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2640 /* If either SRC is not a pointer type, don't do this
2641 operation in-line. */
2642 if (src_align == 0)
2643 return 0;
2645 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2646 src_str = c_getstr (src);
2648 /* If SRC is a string constant and block move would be done
2649 by pieces, we can avoid loading the string from memory
2650 and only stored the computed constants. */
2651 if (src_str
2652 && GET_CODE (len_rtx) == CONST_INT
2653 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2654 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2655 (void *) src_str, dest_align))
2657 dest_mem = get_memory_rtx (dest);
2658 set_mem_align (dest_mem, dest_align);
2659 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2660 builtin_memcpy_read_str,
2661 (void *) src_str, dest_align, endp);
2662 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2663 #ifdef POINTERS_EXTEND_UNSIGNED
2664 if (GET_MODE (dest_mem) != ptr_mode)
2665 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2666 #endif
2667 return dest_mem;
2670 if (GET_CODE (len_rtx) == CONST_INT
2671 && can_move_by_pieces (INTVAL (len_rtx),
2672 MIN (dest_align, src_align)))
2674 dest_mem = get_memory_rtx (dest);
2675 set_mem_align (dest_mem, dest_align);
2676 src_mem = get_memory_rtx (src);
2677 set_mem_align (src_mem, src_align);
2678 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2679 MIN (dest_align, src_align), endp);
2680 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2681 #ifdef POINTERS_EXTEND_UNSIGNED
2682 if (GET_MODE (dest_mem) != ptr_mode)
2683 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2684 #endif
2685 return dest_mem;
2688 return 0;
2692 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2693 if we failed the caller should emit a normal call. */
2695 static rtx
2696 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2698 if (!validate_arglist (arglist,
2699 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2700 return 0;
2701 else
2703 tree dest = TREE_VALUE (arglist);
2704 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2705 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2707 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2708 unsigned int dest_align
2709 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2711 /* If DEST is not a pointer type, call the normal function. */
2712 if (dest_align == 0)
2713 return 0;
2715 /* If the LEN parameter is zero, return DEST. */
2716 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2718 /* Evaluate and ignore SRC in case it has side-effects. */
2719 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2720 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2723 /* If either SRC is not a pointer type, don't do this
2724 operation in-line. */
2725 if (src_align == 0)
2726 return 0;
2728 /* If src is categorized for a readonly section we can use
2729 normal memcpy. */
2730 if (readonly_data_expr (src))
2732 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2733 if (!fn)
2734 return 0;
2735 return expand_expr (build_function_call_expr (fn, arglist),
2736 target, mode, EXPAND_NORMAL);
2739 /* Otherwise, call the normal function. */
2740 return 0;
2744 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2745 if we failed the caller should emit a normal call. */
2747 static rtx
2748 expand_builtin_bcopy (tree arglist)
2750 tree src, dest, size, newarglist;
2752 if (!validate_arglist (arglist,
2753 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2754 return NULL_RTX;
2756 src = TREE_VALUE (arglist);
2757 dest = TREE_VALUE (TREE_CHAIN (arglist));
2758 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2760 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2761 memmove(ptr y, ptr x, size_t z). This is done this way
2762 so that if it isn't expanded inline, we fallback to
2763 calling bcopy instead of memmove. */
2765 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2766 newarglist = tree_cons (NULL_TREE, src, newarglist);
2767 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2769 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2772 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2773 if we failed the caller should emit a normal call, otherwise try to get
2774 the result in TARGET, if convenient (and in mode MODE if that's
2775 convenient). */
2777 static rtx
2778 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2780 tree fn, len, src, dst;
2782 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2783 return 0;
2785 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2786 if (!fn)
2787 return 0;
2789 src = TREE_VALUE (TREE_CHAIN (arglist));
2790 len = c_strlen (src);
2791 if (len == 0 || TREE_SIDE_EFFECTS (len))
2792 return 0;
2794 dst = TREE_VALUE (arglist);
2795 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2796 arglist = build_tree_list (NULL_TREE, len);
2797 arglist = tree_cons (NULL_TREE, src, arglist);
2798 arglist = tree_cons (NULL_TREE, dst, arglist);
2799 return expand_expr (build_function_call_expr (fn, arglist),
2800 target, mode, EXPAND_NORMAL);
2803 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2804 Return 0 if we failed the caller should emit a normal call,
2805 otherwise try to get the result in TARGET, if convenient (and in
2806 mode MODE if that's convenient). */
2808 static rtx
2809 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2811 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2812 return 0;
2813 else
2815 tree dst, src, len;
2817 /* If return value is ignored, transform stpcpy into strcpy. */
2818 if (target == const0_rtx)
2820 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2821 if (!fn)
2822 return 0;
2824 return expand_expr (build_function_call_expr (fn, arglist),
2825 target, mode, EXPAND_NORMAL);
2828 /* Ensure we get an actual string whose length can be evaluated at
2829 compile-time, not an expression containing a string. This is
2830 because the latter will potentially produce pessimized code
2831 when used to produce the return value. */
2832 src = TREE_VALUE (TREE_CHAIN (arglist));
2833 if (! c_getstr (src) || ! (len = c_strlen (src)))
2834 return 0;
2836 dst = TREE_VALUE (arglist);
2837 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2838 arglist = build_tree_list (NULL_TREE, len);
2839 arglist = tree_cons (NULL_TREE, src, arglist);
2840 arglist = tree_cons (NULL_TREE, dst, arglist);
2841 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2845 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2846 bytes from constant string DATA + OFFSET and return it as target
2847 constant. */
2849 static rtx
2850 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2851 enum machine_mode mode)
2853 const char *str = (const char *) data;
2855 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2856 return const0_rtx;
2858 return c_readstr (str + offset, mode);
2861 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2862 if we failed the caller should emit a normal call. */
2864 static rtx
2865 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2867 if (!validate_arglist (arglist,
2868 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2869 return 0;
2870 else
2872 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2873 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2874 tree fn;
2876 /* We must be passed a constant len parameter. */
2877 if (TREE_CODE (len) != INTEGER_CST)
2878 return 0;
2880 /* If the len parameter is zero, return the dst parameter. */
2881 if (integer_zerop (len))
2883 /* Evaluate and ignore the src argument in case it has
2884 side-effects. */
2885 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2886 VOIDmode, EXPAND_NORMAL);
2887 /* Return the dst parameter. */
2888 return expand_expr (TREE_VALUE (arglist), target, mode,
2889 EXPAND_NORMAL);
2892 /* Now, we must be passed a constant src ptr parameter. */
2893 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2894 return 0;
2896 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2898 /* We're required to pad with trailing zeros if the requested
2899 len is greater than strlen(s2)+1. In that case try to
2900 use store_by_pieces, if it fails, punt. */
2901 if (tree_int_cst_lt (slen, len))
2903 tree dest = TREE_VALUE (arglist);
2904 unsigned int dest_align
2905 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2906 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2907 rtx dest_mem;
2909 if (!p || dest_align == 0 || !host_integerp (len, 1)
2910 || !can_store_by_pieces (tree_low_cst (len, 1),
2911 builtin_strncpy_read_str,
2912 (void *) p, dest_align))
2913 return 0;
2915 dest_mem = get_memory_rtx (dest);
2916 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2917 builtin_strncpy_read_str,
2918 (void *) p, dest_align, 0);
2919 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2920 #ifdef POINTERS_EXTEND_UNSIGNED
2921 if (GET_MODE (dest_mem) != ptr_mode)
2922 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2923 #endif
2924 return dest_mem;
2927 /* OK transform into builtin memcpy. */
2928 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2929 if (!fn)
2930 return 0;
2931 return expand_expr (build_function_call_expr (fn, arglist),
2932 target, mode, EXPAND_NORMAL);
2936 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2937 bytes from constant string DATA + OFFSET and return it as target
2938 constant. */
2940 static rtx
2941 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2942 enum machine_mode mode)
2944 const char *c = (const char *) data;
2945 char *p = alloca (GET_MODE_SIZE (mode));
2947 memset (p, *c, GET_MODE_SIZE (mode));
2949 return c_readstr (p, mode);
2952 /* Callback routine for store_by_pieces. Return the RTL of a register
2953 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2954 char value given in the RTL register data. For example, if mode is
2955 4 bytes wide, return the RTL for 0x01010101*data. */
2957 static rtx
2958 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2959 enum machine_mode mode)
2961 rtx target, coeff;
2962 size_t size;
2963 char *p;
2965 size = GET_MODE_SIZE (mode);
2966 if (size == 1)
2967 return (rtx) data;
2969 p = alloca (size);
2970 memset (p, 1, size);
2971 coeff = c_readstr (p, mode);
2973 target = convert_to_mode (mode, (rtx) data, 1);
2974 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2975 return force_reg (mode, target);
2978 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2979 if we failed the caller should emit a normal call, otherwise try to get
2980 the result in TARGET, if convenient (and in mode MODE if that's
2981 convenient). */
2983 static rtx
2984 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2986 if (!validate_arglist (arglist,
2987 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2988 return 0;
2989 else
2991 tree dest = TREE_VALUE (arglist);
2992 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2993 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2994 char c;
2996 unsigned int dest_align
2997 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2998 rtx dest_mem, dest_addr, len_rtx;
3000 /* If DEST is not a pointer type, don't do this
3001 operation in-line. */
3002 if (dest_align == 0)
3003 return 0;
3005 /* If the LEN parameter is zero, return DEST. */
3006 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
3008 /* Evaluate and ignore VAL in case it has side-effects. */
3009 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3010 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3013 if (TREE_CODE (val) != INTEGER_CST)
3015 rtx val_rtx;
3017 if (!host_integerp (len, 1))
3018 return 0;
3020 if (optimize_size && tree_low_cst (len, 1) > 1)
3021 return 0;
3023 /* Assume that we can memset by pieces if we can store the
3024 * the coefficients by pieces (in the required modes).
3025 * We can't pass builtin_memset_gen_str as that emits RTL. */
3026 c = 1;
3027 if (!can_store_by_pieces (tree_low_cst (len, 1),
3028 builtin_memset_read_str,
3029 &c, dest_align))
3030 return 0;
3032 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3033 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3034 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3035 val_rtx);
3036 dest_mem = get_memory_rtx (dest);
3037 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3038 builtin_memset_gen_str,
3039 val_rtx, dest_align, 0);
3040 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3041 #ifdef POINTERS_EXTEND_UNSIGNED
3042 if (GET_MODE (dest_mem) != ptr_mode)
3043 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3044 #endif
3045 return dest_mem;
3048 if (target_char_cast (val, &c))
3049 return 0;
3051 if (c)
3053 if (!host_integerp (len, 1))
3054 return 0;
3055 if (!can_store_by_pieces (tree_low_cst (len, 1),
3056 builtin_memset_read_str, &c,
3057 dest_align))
3058 return 0;
3060 dest_mem = get_memory_rtx (dest);
3061 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3062 builtin_memset_read_str,
3063 &c, dest_align, 0);
3064 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3065 #ifdef POINTERS_EXTEND_UNSIGNED
3066 if (GET_MODE (dest_mem) != ptr_mode)
3067 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3068 #endif
3069 return dest_mem;
3072 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3074 dest_mem = get_memory_rtx (dest);
3075 set_mem_align (dest_mem, dest_align);
3076 dest_addr = clear_storage (dest_mem, len_rtx);
3078 if (dest_addr == 0)
3080 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3081 #ifdef POINTERS_EXTEND_UNSIGNED
3082 if (GET_MODE (dest_addr) != ptr_mode)
3083 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3084 #endif
3087 return dest_addr;
3091 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3092 if we failed the caller should emit a normal call. */
3094 static rtx
3095 expand_builtin_bzero (tree arglist)
3097 tree dest, size, newarglist;
3099 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3100 return NULL_RTX;
3102 dest = TREE_VALUE (arglist);
3103 size = TREE_VALUE (TREE_CHAIN (arglist));
3105 /* New argument list transforming bzero(ptr x, int y) to
3106 memset(ptr x, int 0, size_t y). This is done this way
3107 so that if it isn't expanded inline, we fallback to
3108 calling bzero instead of memset. */
3110 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3111 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3112 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3114 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3117 /* Expand expression EXP, which is a call to the memcmp built-in function.
3118 ARGLIST is the argument list for this call. Return 0 if we failed and the
3119 caller should emit a normal call, otherwise try to get the result in
3120 TARGET, if convenient (and in mode MODE, if that's convenient). */
3122 static rtx
3123 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3124 enum machine_mode mode)
3126 tree arg1, arg2, len;
3127 const char *p1, *p2;
3129 if (!validate_arglist (arglist,
3130 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3131 return 0;
3133 arg1 = TREE_VALUE (arglist);
3134 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3135 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3137 /* If the len parameter is zero, return zero. */
3138 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
3140 /* Evaluate and ignore arg1 and arg2 in case they have
3141 side-effects. */
3142 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3143 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3144 return const0_rtx;
3147 p1 = c_getstr (arg1);
3148 p2 = c_getstr (arg2);
3150 /* If all arguments are constant, and the value of len is not greater
3151 than the lengths of arg1 and arg2, evaluate at compile-time. */
3152 if (host_integerp (len, 1) && p1 && p2
3153 && compare_tree_int (len, strlen (p1) + 1) <= 0
3154 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3156 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3158 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3161 /* If len parameter is one, return an expression corresponding to
3162 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3163 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
3165 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3166 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3167 tree ind1 =
3168 fold (build1 (CONVERT_EXPR, integer_type_node,
3169 build1 (INDIRECT_REF, cst_uchar_node,
3170 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3171 tree ind2 =
3172 fold (build1 (CONVERT_EXPR, integer_type_node,
3173 build1 (INDIRECT_REF, cst_uchar_node,
3174 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3175 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3176 return expand_expr (result, target, mode, EXPAND_NORMAL);
3179 #ifdef HAVE_cmpstrsi
3181 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3182 rtx result;
3183 rtx insn;
3185 int arg1_align
3186 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3187 int arg2_align
3188 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3189 enum machine_mode insn_mode
3190 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3192 /* If we don't have POINTER_TYPE, call the function. */
3193 if (arg1_align == 0 || arg2_align == 0)
3194 return 0;
3196 /* Make a place to write the result of the instruction. */
3197 result = target;
3198 if (! (result != 0
3199 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3200 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3201 result = gen_reg_rtx (insn_mode);
3203 arg1_rtx = get_memory_rtx (arg1);
3204 arg2_rtx = get_memory_rtx (arg2);
3205 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3206 if (!HAVE_cmpstrsi)
3207 insn = NULL_RTX;
3208 else
3209 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3210 GEN_INT (MIN (arg1_align, arg2_align)));
3212 if (insn)
3213 emit_insn (insn);
3214 else
3215 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3216 TYPE_MODE (integer_type_node), 3,
3217 XEXP (arg1_rtx, 0), Pmode,
3218 XEXP (arg2_rtx, 0), Pmode,
3219 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3220 TREE_UNSIGNED (sizetype)),
3221 TYPE_MODE (sizetype));
3223 /* Return the value in the proper mode for this function. */
3224 mode = TYPE_MODE (TREE_TYPE (exp));
3225 if (GET_MODE (result) == mode)
3226 return result;
3227 else if (target != 0)
3229 convert_move (target, result, 0);
3230 return target;
3232 else
3233 return convert_to_mode (mode, result, 0);
3235 #endif
3237 return 0;
3240 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3241 if we failed the caller should emit a normal call, otherwise try to get
3242 the result in TARGET, if convenient. */
3244 static rtx
3245 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3247 tree arglist = TREE_OPERAND (exp, 1);
3248 tree arg1, arg2;
3249 const char *p1, *p2;
3251 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3252 return 0;
3254 arg1 = TREE_VALUE (arglist);
3255 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3257 p1 = c_getstr (arg1);
3258 p2 = c_getstr (arg2);
3260 if (p1 && p2)
3262 const int i = strcmp (p1, p2);
3263 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3266 /* If either arg is "", return an expression corresponding to
3267 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3268 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3270 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3271 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3272 tree ind1 =
3273 fold (build1 (CONVERT_EXPR, integer_type_node,
3274 build1 (INDIRECT_REF, cst_uchar_node,
3275 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3276 tree ind2 =
3277 fold (build1 (CONVERT_EXPR, integer_type_node,
3278 build1 (INDIRECT_REF, cst_uchar_node,
3279 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3280 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3281 return expand_expr (result, target, mode, EXPAND_NORMAL);
3284 #ifdef HAVE_cmpstrsi
3285 if (HAVE_cmpstrsi)
3287 tree len, len1, len2;
3288 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3289 rtx result, insn;
3291 int arg1_align
3292 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3293 int arg2_align
3294 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3295 enum machine_mode insn_mode
3296 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3298 len1 = c_strlen (arg1);
3299 len2 = c_strlen (arg2);
3301 if (len1)
3302 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3303 if (len2)
3304 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3306 /* If we don't have a constant length for the first, use the length
3307 of the second, if we know it. We don't require a constant for
3308 this case; some cost analysis could be done if both are available
3309 but neither is constant. For now, assume they're equally cheap,
3310 unless one has side effects. If both strings have constant lengths,
3311 use the smaller. */
3313 if (!len1)
3314 len = len2;
3315 else if (!len2)
3316 len = len1;
3317 else if (TREE_SIDE_EFFECTS (len1))
3318 len = len2;
3319 else if (TREE_SIDE_EFFECTS (len2))
3320 len = len1;
3321 else if (TREE_CODE (len1) != INTEGER_CST)
3322 len = len2;
3323 else if (TREE_CODE (len2) != INTEGER_CST)
3324 len = len1;
3325 else if (tree_int_cst_lt (len1, len2))
3326 len = len1;
3327 else
3328 len = len2;
3330 /* If both arguments have side effects, we cannot optimize. */
3331 if (!len || TREE_SIDE_EFFECTS (len))
3332 return 0;
3334 /* If we don't have POINTER_TYPE, call the function. */
3335 if (arg1_align == 0 || arg2_align == 0)
3336 return 0;
3338 /* Make a place to write the result of the instruction. */
3339 result = target;
3340 if (! (result != 0
3341 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3342 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3343 result = gen_reg_rtx (insn_mode);
3345 arg1_rtx = get_memory_rtx (arg1);
3346 arg2_rtx = get_memory_rtx (arg2);
3347 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3348 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3349 GEN_INT (MIN (arg1_align, arg2_align)));
3350 if (!insn)
3351 return 0;
3353 emit_insn (insn);
3355 /* Return the value in the proper mode for this function. */
3356 mode = TYPE_MODE (TREE_TYPE (exp));
3357 if (GET_MODE (result) == mode)
3358 return result;
3359 if (target == 0)
3360 return convert_to_mode (mode, result, 0);
3361 convert_move (target, result, 0);
3362 return target;
3364 #endif
3365 return 0;
3368 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3369 if we failed the caller should emit a normal call, otherwise try to get
3370 the result in TARGET, if convenient. */
3372 static rtx
3373 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3375 tree arglist = TREE_OPERAND (exp, 1);
3376 tree arg1, arg2, arg3;
3377 const char *p1, *p2;
3379 if (!validate_arglist (arglist,
3380 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3381 return 0;
3383 arg1 = TREE_VALUE (arglist);
3384 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3385 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3387 /* If the len parameter is zero, return zero. */
3388 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
3390 /* Evaluate and ignore arg1 and arg2 in case they have
3391 side-effects. */
3392 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3393 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3394 return const0_rtx;
3397 p1 = c_getstr (arg1);
3398 p2 = c_getstr (arg2);
3400 /* If all arguments are constant, evaluate at compile-time. */
3401 if (host_integerp (arg3, 1) && p1 && p2)
3403 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3404 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3407 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3408 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3409 if (host_integerp (arg3, 1)
3410 && (tree_low_cst (arg3, 1) == 1
3411 || (tree_low_cst (arg3, 1) > 1
3412 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3414 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3415 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3416 tree ind1 =
3417 fold (build1 (CONVERT_EXPR, integer_type_node,
3418 build1 (INDIRECT_REF, cst_uchar_node,
3419 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3420 tree ind2 =
3421 fold (build1 (CONVERT_EXPR, integer_type_node,
3422 build1 (INDIRECT_REF, cst_uchar_node,
3423 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3424 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3425 return expand_expr (result, target, mode, EXPAND_NORMAL);
3428 /* If c_strlen can determine an expression for one of the string
3429 lengths, and it doesn't have side effects, then emit cmpstrsi
3430 using length MIN(strlen(string)+1, arg3). */
3431 #ifdef HAVE_cmpstrsi
3432 if (HAVE_cmpstrsi)
3434 tree len, len1, len2;
3435 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3436 rtx result, insn;
3438 int arg1_align
3439 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3440 int arg2_align
3441 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3442 enum machine_mode insn_mode
3443 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3445 len1 = c_strlen (arg1);
3446 len2 = c_strlen (arg2);
3448 if (len1)
3449 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3450 if (len2)
3451 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3453 /* If we don't have a constant length for the first, use the length
3454 of the second, if we know it. We don't require a constant for
3455 this case; some cost analysis could be done if both are available
3456 but neither is constant. For now, assume they're equally cheap,
3457 unless one has side effects. If both strings have constant lengths,
3458 use the smaller. */
3460 if (!len1)
3461 len = len2;
3462 else if (!len2)
3463 len = len1;
3464 else if (TREE_SIDE_EFFECTS (len1))
3465 len = len2;
3466 else if (TREE_SIDE_EFFECTS (len2))
3467 len = len1;
3468 else if (TREE_CODE (len1) != INTEGER_CST)
3469 len = len2;
3470 else if (TREE_CODE (len2) != INTEGER_CST)
3471 len = len1;
3472 else if (tree_int_cst_lt (len1, len2))
3473 len = len1;
3474 else
3475 len = len2;
3477 /* If both arguments have side effects, we cannot optimize. */
3478 if (!len || TREE_SIDE_EFFECTS (len))
3479 return 0;
3481 /* The actual new length parameter is MIN(len,arg3). */
3482 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3484 /* If we don't have POINTER_TYPE, call the function. */
3485 if (arg1_align == 0 || arg2_align == 0)
3486 return 0;
3488 /* Make a place to write the result of the instruction. */
3489 result = target;
3490 if (! (result != 0
3491 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3492 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3493 result = gen_reg_rtx (insn_mode);
3495 arg1_rtx = get_memory_rtx (arg1);
3496 arg2_rtx = get_memory_rtx (arg2);
3497 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3498 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3499 GEN_INT (MIN (arg1_align, arg2_align)));
3500 if (!insn)
3501 return 0;
3503 emit_insn (insn);
3505 /* Return the value in the proper mode for this function. */
3506 mode = TYPE_MODE (TREE_TYPE (exp));
3507 if (GET_MODE (result) == mode)
3508 return result;
3509 if (target == 0)
3510 return convert_to_mode (mode, result, 0);
3511 convert_move (target, result, 0);
3512 return target;
3514 #endif
3515 return 0;
3518 /* Expand expression EXP, which is a call to the strcat builtin.
3519 Return 0 if we failed the caller should emit a normal call,
3520 otherwise try to get the result in TARGET, if convenient. */
3522 static rtx
3523 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3525 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3526 return 0;
3527 else
3529 tree dst = TREE_VALUE (arglist),
3530 src = TREE_VALUE (TREE_CHAIN (arglist));
3531 const char *p = c_getstr (src);
3533 /* If the string length is zero, return the dst parameter. */
3534 if (p && *p == '\0')
3535 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3537 return 0;
3541 /* Expand expression EXP, which is a call to the strncat builtin.
3542 Return 0 if we failed the caller should emit a normal call,
3543 otherwise try to get the result in TARGET, if convenient. */
3545 static rtx
3546 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3548 if (!validate_arglist (arglist,
3549 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3550 return 0;
3551 else
3553 tree dst = TREE_VALUE (arglist),
3554 src = TREE_VALUE (TREE_CHAIN (arglist)),
3555 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3556 const char *p = c_getstr (src);
3558 /* If the requested length is zero, or the src parameter string
3559 length is zero, return the dst parameter. */
3560 if (integer_zerop (len) || (p && *p == '\0'))
3562 /* Evaluate and ignore the src and len parameters in case
3563 they have side-effects. */
3564 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3565 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3566 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3569 /* If the requested len is greater than or equal to the string
3570 length, call strcat. */
3571 if (TREE_CODE (len) == INTEGER_CST && p
3572 && compare_tree_int (len, strlen (p)) >= 0)
3574 tree newarglist
3575 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3576 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3578 /* If the replacement _DECL isn't initialized, don't do the
3579 transformation. */
3580 if (!fn)
3581 return 0;
3583 return expand_expr (build_function_call_expr (fn, newarglist),
3584 target, mode, EXPAND_NORMAL);
3586 return 0;
3590 /* Expand expression EXP, which is a call to the strspn builtin.
3591 Return 0 if we failed the caller should emit a normal call,
3592 otherwise try to get the result in TARGET, if convenient. */
3594 static rtx
3595 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3597 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3598 return 0;
3599 else
3601 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3602 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3604 /* If both arguments are constants, evaluate at compile-time. */
3605 if (p1 && p2)
3607 const size_t r = strspn (p1, p2);
3608 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3611 /* If either argument is "", return 0. */
3612 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3614 /* Evaluate and ignore both arguments in case either one has
3615 side-effects. */
3616 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3617 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3618 return const0_rtx;
3620 return 0;
3624 /* Expand expression EXP, which is a call to the strcspn builtin.
3625 Return 0 if we failed the caller should emit a normal call,
3626 otherwise try to get the result in TARGET, if convenient. */
3628 static rtx
3629 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3631 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3632 return 0;
3633 else
3635 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3636 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3638 /* If both arguments are constants, evaluate at compile-time. */
3639 if (p1 && p2)
3641 const size_t r = strcspn (p1, p2);
3642 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3645 /* If the first argument is "", return 0. */
3646 if (p1 && *p1 == '\0')
3648 /* Evaluate and ignore argument s2 in case it has
3649 side-effects. */
3650 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3651 return const0_rtx;
3654 /* If the second argument is "", return __builtin_strlen(s1). */
3655 if (p2 && *p2 == '\0')
3657 tree newarglist = build_tree_list (NULL_TREE, s1),
3658 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3660 /* If the replacement _DECL isn't initialized, don't do the
3661 transformation. */
3662 if (!fn)
3663 return 0;
3665 return expand_expr (build_function_call_expr (fn, newarglist),
3666 target, mode, EXPAND_NORMAL);
3668 return 0;
3672 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3673 if that's convenient. */
3676 expand_builtin_saveregs (void)
3678 rtx val, seq;
3680 /* Don't do __builtin_saveregs more than once in a function.
3681 Save the result of the first call and reuse it. */
3682 if (saveregs_value != 0)
3683 return saveregs_value;
3685 /* When this function is called, it means that registers must be
3686 saved on entry to this function. So we migrate the call to the
3687 first insn of this function. */
3689 start_sequence ();
3691 #ifdef EXPAND_BUILTIN_SAVEREGS
3692 /* Do whatever the machine needs done in this case. */
3693 val = EXPAND_BUILTIN_SAVEREGS ();
3694 #else
3695 /* ??? We used to try and build up a call to the out of line function,
3696 guessing about what registers needed saving etc. This became much
3697 harder with __builtin_va_start, since we don't have a tree for a
3698 call to __builtin_saveregs to fall back on. There was exactly one
3699 port (i860) that used this code, and I'm unconvinced it could actually
3700 handle the general case. So we no longer try to handle anything
3701 weird and make the backend absorb the evil. */
3703 error ("__builtin_saveregs not supported by this target");
3704 val = const0_rtx;
3705 #endif
3707 seq = get_insns ();
3708 end_sequence ();
3710 saveregs_value = val;
3712 /* Put the insns after the NOTE that starts the function. If this
3713 is inside a start_sequence, make the outer-level insn chain current, so
3714 the code is placed at the start of the function. */
3715 push_topmost_sequence ();
3716 emit_insn_after (seq, get_insns ());
3717 pop_topmost_sequence ();
3719 return val;
3722 /* __builtin_args_info (N) returns word N of the arg space info
3723 for the current function. The number and meanings of words
3724 is controlled by the definition of CUMULATIVE_ARGS. */
3726 static rtx
3727 expand_builtin_args_info (tree arglist)
3729 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3730 int *word_ptr = (int *) &current_function_args_info;
3732 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3733 abort ();
3735 if (arglist != 0)
3737 if (!host_integerp (TREE_VALUE (arglist), 0))
3738 error ("argument of `__builtin_args_info' must be constant");
3739 else
3741 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3743 if (wordnum < 0 || wordnum >= nwords)
3744 error ("argument of `__builtin_args_info' out of range");
3745 else
3746 return GEN_INT (word_ptr[wordnum]);
3749 else
3750 error ("missing argument in `__builtin_args_info'");
3752 return const0_rtx;
3755 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3757 static rtx
3758 expand_builtin_next_arg (tree arglist)
3760 tree fntype = TREE_TYPE (current_function_decl);
3762 if (TYPE_ARG_TYPES (fntype) == 0
3763 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3764 == void_type_node))
3766 error ("`va_start' used in function with fixed args");
3767 return const0_rtx;
3770 if (arglist)
3772 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3773 tree arg = TREE_VALUE (arglist);
3775 /* Strip off all nops for the sake of the comparison. This
3776 is not quite the same as STRIP_NOPS. It does more.
3777 We must also strip off INDIRECT_EXPR for C++ reference
3778 parameters. */
3779 while (TREE_CODE (arg) == NOP_EXPR
3780 || TREE_CODE (arg) == CONVERT_EXPR
3781 || TREE_CODE (arg) == NON_LVALUE_EXPR
3782 || TREE_CODE (arg) == INDIRECT_REF)
3783 arg = TREE_OPERAND (arg, 0);
3784 if (arg != last_parm)
3785 warning ("second parameter of `va_start' not last named argument");
3787 else
3788 /* Evidently an out of date version of <stdarg.h>; can't validate
3789 va_start's second argument, but can still work as intended. */
3790 warning ("`__builtin_next_arg' called without an argument");
3792 return expand_binop (Pmode, add_optab,
3793 current_function_internal_arg_pointer,
3794 current_function_arg_offset_rtx,
3795 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3798 /* Make it easier for the backends by protecting the valist argument
3799 from multiple evaluations. */
3801 static tree
3802 stabilize_va_list (tree valist, int needs_lvalue)
3804 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3806 if (TREE_SIDE_EFFECTS (valist))
3807 valist = save_expr (valist);
3809 /* For this case, the backends will be expecting a pointer to
3810 TREE_TYPE (va_list_type_node), but it's possible we've
3811 actually been given an array (an actual va_list_type_node).
3812 So fix it. */
3813 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3815 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3816 tree p2 = build_pointer_type (va_list_type_node);
3818 valist = build1 (ADDR_EXPR, p2, valist);
3819 valist = fold (build1 (NOP_EXPR, p1, valist));
3822 else
3824 tree pt;
3826 if (! needs_lvalue)
3828 if (! TREE_SIDE_EFFECTS (valist))
3829 return valist;
3831 pt = build_pointer_type (va_list_type_node);
3832 valist = fold (build1 (ADDR_EXPR, pt, valist));
3833 TREE_SIDE_EFFECTS (valist) = 1;
3836 if (TREE_SIDE_EFFECTS (valist))
3837 valist = save_expr (valist);
3838 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3839 valist));
3842 return valist;
3845 /* The "standard" implementation of va_start: just assign `nextarg' to
3846 the variable. */
3848 void
3849 std_expand_builtin_va_start (tree valist, rtx nextarg)
3851 tree t;
3853 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3854 make_tree (ptr_type_node, nextarg));
3855 TREE_SIDE_EFFECTS (t) = 1;
3857 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3860 /* Expand ARGLIST, from a call to __builtin_va_start. */
3862 static rtx
3863 expand_builtin_va_start (tree arglist)
3865 rtx nextarg;
3866 tree chain, valist;
3868 chain = TREE_CHAIN (arglist);
3870 if (TREE_CHAIN (chain))
3871 error ("too many arguments to function `va_start'");
3873 nextarg = expand_builtin_next_arg (chain);
3874 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3876 #ifdef EXPAND_BUILTIN_VA_START
3877 EXPAND_BUILTIN_VA_START (valist, nextarg);
3878 #else
3879 std_expand_builtin_va_start (valist, nextarg);
3880 #endif
3882 return const0_rtx;
3885 /* The "standard" implementation of va_arg: read the value from the
3886 current (padded) address and increment by the (padded) size. */
3889 std_expand_builtin_va_arg (tree valist, tree type)
3891 tree addr_tree, t, type_size = NULL;
3892 tree align, alignm1;
3893 tree rounded_size;
3894 rtx addr;
3896 /* Compute the rounded size of the type. */
3897 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3898 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3899 if (type == error_mark_node
3900 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3901 || TREE_OVERFLOW (type_size))
3902 rounded_size = size_zero_node;
3903 else
3904 rounded_size = fold (build (MULT_EXPR, sizetype,
3905 fold (build (TRUNC_DIV_EXPR, sizetype,
3906 fold (build (PLUS_EXPR, sizetype,
3907 type_size, alignm1)),
3908 align)),
3909 align));
3911 /* Get AP. */
3912 addr_tree = valist;
3913 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3915 /* Small args are padded downward. */
3916 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3917 fold (build (COND_EXPR, sizetype,
3918 fold (build (GT_EXPR, sizetype,
3919 rounded_size,
3920 align)),
3921 size_zero_node,
3922 fold (build (MINUS_EXPR, sizetype,
3923 rounded_size,
3924 type_size))))));
3927 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3928 addr = copy_to_reg (addr);
3930 /* Compute new value for AP. */
3931 if (! integer_zerop (rounded_size))
3933 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3934 build (PLUS_EXPR, TREE_TYPE (valist), valist,
3935 rounded_size));
3936 TREE_SIDE_EFFECTS (t) = 1;
3937 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3940 return addr;
3943 /* Expand __builtin_va_arg, which is not really a builtin function, but
3944 a very special sort of operator. */
3947 expand_builtin_va_arg (tree valist, tree type)
3949 rtx addr, result;
3950 tree promoted_type, want_va_type, have_va_type;
3952 /* Verify that valist is of the proper type. */
3954 want_va_type = va_list_type_node;
3955 have_va_type = TREE_TYPE (valist);
3956 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3958 /* If va_list is an array type, the argument may have decayed
3959 to a pointer type, e.g. by being passed to another function.
3960 In that case, unwrap both types so that we can compare the
3961 underlying records. */
3962 if (TREE_CODE (have_va_type) == ARRAY_TYPE
3963 || TREE_CODE (have_va_type) == POINTER_TYPE)
3965 want_va_type = TREE_TYPE (want_va_type);
3966 have_va_type = TREE_TYPE (have_va_type);
3969 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3971 error ("first argument to `va_arg' not of type `va_list'");
3972 addr = const0_rtx;
3975 /* Generate a diagnostic for requesting data of a type that cannot
3976 be passed through `...' due to type promotion at the call site. */
3977 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3978 != type)
3980 const char *name = "<anonymous type>", *pname = 0;
3981 static bool gave_help;
3983 if (TYPE_NAME (type))
3985 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3986 name = IDENTIFIER_POINTER (TYPE_NAME (type));
3987 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3988 && DECL_NAME (TYPE_NAME (type)))
3989 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3991 if (TYPE_NAME (promoted_type))
3993 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3994 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3995 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3996 && DECL_NAME (TYPE_NAME (promoted_type)))
3997 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4000 /* Unfortunately, this is merely undefined, rather than a constraint
4001 violation, so we cannot make this an error. If this call is never
4002 executed, the program is still strictly conforming. */
4003 warning ("`%s' is promoted to `%s' when passed through `...'",
4004 name, pname);
4005 if (! gave_help)
4007 gave_help = true;
4008 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4009 pname, name);
4012 /* We can, however, treat "undefined" any way we please.
4013 Call abort to encourage the user to fix the program. */
4014 expand_builtin_trap ();
4016 /* This is dead code, but go ahead and finish so that the
4017 mode of the result comes out right. */
4018 addr = const0_rtx;
4020 else
4022 /* Make it easier for the backends by protecting the valist argument
4023 from multiple evaluations. */
4024 valist = stabilize_va_list (valist, 0);
4026 #ifdef EXPAND_BUILTIN_VA_ARG
4027 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4028 #else
4029 addr = std_expand_builtin_va_arg (valist, type);
4030 #endif
4033 #ifdef POINTERS_EXTEND_UNSIGNED
4034 if (GET_MODE (addr) != Pmode)
4035 addr = convert_memory_address (Pmode, addr);
4036 #endif
4038 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4039 set_mem_alias_set (result, get_varargs_alias_set ());
4041 return result;
4044 /* Expand ARGLIST, from a call to __builtin_va_end. */
4046 static rtx
4047 expand_builtin_va_end (tree arglist)
4049 tree valist = TREE_VALUE (arglist);
4051 #ifdef EXPAND_BUILTIN_VA_END
4052 valist = stabilize_va_list (valist, 0);
4053 EXPAND_BUILTIN_VA_END (arglist);
4054 #else
4055 /* Evaluate for side effects, if needed. I hate macros that don't
4056 do that. */
4057 if (TREE_SIDE_EFFECTS (valist))
4058 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4059 #endif
4061 return const0_rtx;
4064 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4065 builtin rather than just as an assignment in stdarg.h because of the
4066 nastiness of array-type va_list types. */
4068 static rtx
4069 expand_builtin_va_copy (tree arglist)
4071 tree dst, src, t;
4073 dst = TREE_VALUE (arglist);
4074 src = TREE_VALUE (TREE_CHAIN (arglist));
4076 dst = stabilize_va_list (dst, 1);
4077 src = stabilize_va_list (src, 0);
4079 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4081 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4082 TREE_SIDE_EFFECTS (t) = 1;
4083 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4085 else
4087 rtx dstb, srcb, size;
4089 /* Evaluate to pointers. */
4090 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4091 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4092 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4093 VOIDmode, EXPAND_NORMAL);
4095 #ifdef POINTERS_EXTEND_UNSIGNED
4096 if (GET_MODE (dstb) != Pmode)
4097 dstb = convert_memory_address (Pmode, dstb);
4099 if (GET_MODE (srcb) != Pmode)
4100 srcb = convert_memory_address (Pmode, srcb);
4101 #endif
4103 /* "Dereference" to BLKmode memories. */
4104 dstb = gen_rtx_MEM (BLKmode, dstb);
4105 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4106 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4107 srcb = gen_rtx_MEM (BLKmode, srcb);
4108 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4109 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4111 /* Copy. */
4112 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4115 return const0_rtx;
4118 /* Expand a call to one of the builtin functions __builtin_frame_address or
4119 __builtin_return_address. */
4121 static rtx
4122 expand_builtin_frame_address (tree fndecl, tree arglist)
4124 /* The argument must be a nonnegative integer constant.
4125 It counts the number of frames to scan up the stack.
4126 The value is the return address saved in that frame. */
4127 if (arglist == 0)
4128 /* Warning about missing arg was already issued. */
4129 return const0_rtx;
4130 else if (! host_integerp (TREE_VALUE (arglist), 1))
4132 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4133 error ("invalid arg to `__builtin_frame_address'");
4134 else
4135 error ("invalid arg to `__builtin_return_address'");
4136 return const0_rtx;
4138 else
4140 rtx tem
4141 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4142 tree_low_cst (TREE_VALUE (arglist), 1),
4143 hard_frame_pointer_rtx);
4145 /* Some ports cannot access arbitrary stack frames. */
4146 if (tem == NULL)
4148 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4149 warning ("unsupported arg to `__builtin_frame_address'");
4150 else
4151 warning ("unsupported arg to `__builtin_return_address'");
4152 return const0_rtx;
4155 /* For __builtin_frame_address, return what we've got. */
4156 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4157 return tem;
4159 if (GET_CODE (tem) != REG
4160 && ! CONSTANT_P (tem))
4161 tem = copy_to_mode_reg (Pmode, tem);
4162 return tem;
4166 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4167 we failed and the caller should emit a normal call, otherwise try to get
4168 the result in TARGET, if convenient. */
4170 static rtx
4171 expand_builtin_alloca (tree arglist, rtx target)
4173 rtx op0;
4174 rtx result;
4176 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4177 return 0;
4179 /* Compute the argument. */
4180 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4182 /* Allocate the desired space. */
4183 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4185 #ifdef POINTERS_EXTEND_UNSIGNED
4186 if (GET_MODE (result) != ptr_mode)
4187 result = convert_memory_address (ptr_mode, result);
4188 #endif
4190 return result;
4193 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4194 Return 0 if a normal call should be emitted rather than expanding the
4195 function in-line. If convenient, the result should be placed in TARGET.
4196 SUBTARGET may be used as the target for computing one of EXP's operands. */
4198 static rtx
4199 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4200 rtx subtarget, optab op_optab)
4202 rtx op0;
4203 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4204 return 0;
4206 /* Compute the argument. */
4207 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4208 /* Compute op, into TARGET if possible.
4209 Set TARGET to wherever the result comes back. */
4210 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4211 op_optab, op0, target, 1);
4212 if (target == 0)
4213 abort ();
4215 return convert_to_mode (target_mode, target, 0);
4218 /* If the string passed to fputs is a constant and is one character
4219 long, we attempt to transform this call into __builtin_fputc(). */
4221 static rtx
4222 expand_builtin_fputs (tree arglist, int ignore, int unlocked)
4224 tree len, fn;
4225 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4226 : implicit_built_in_decls[BUILT_IN_FPUTC];
4227 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4228 : implicit_built_in_decls[BUILT_IN_FWRITE];
4230 /* If the return value is used, or the replacement _DECL isn't
4231 initialized, don't do the transformation. */
4232 if (!ignore || !fn_fputc || !fn_fwrite)
4233 return 0;
4235 /* Verify the arguments in the original call. */
4236 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4237 return 0;
4239 /* Get the length of the string passed to fputs. If the length
4240 can't be determined, punt. */
4241 if (!(len = c_strlen (TREE_VALUE (arglist)))
4242 || TREE_CODE (len) != INTEGER_CST)
4243 return 0;
4245 switch (compare_tree_int (len, 1))
4247 case -1: /* length is 0, delete the call entirely . */
4249 /* Evaluate and ignore the argument in case it has
4250 side-effects. */
4251 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4252 VOIDmode, EXPAND_NORMAL);
4253 return const0_rtx;
4255 case 0: /* length is 1, call fputc. */
4257 const char *p = c_getstr (TREE_VALUE (arglist));
4259 if (p != NULL)
4261 /* New argument list transforming fputs(string, stream) to
4262 fputc(string[0], stream). */
4263 arglist =
4264 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4265 arglist =
4266 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4267 fn = fn_fputc;
4268 break;
4271 /* FALLTHROUGH */
4272 case 1: /* length is greater than 1, call fwrite. */
4274 tree string_arg;
4276 /* If optimizing for size keep fputs. */
4277 if (optimize_size)
4278 return 0;
4279 string_arg = TREE_VALUE (arglist);
4280 /* New argument list transforming fputs(string, stream) to
4281 fwrite(string, 1, len, stream). */
4282 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4283 arglist = tree_cons (NULL_TREE, len, arglist);
4284 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4285 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4286 fn = fn_fwrite;
4287 break;
4289 default:
4290 abort ();
4293 return expand_expr (build_function_call_expr (fn, arglist),
4294 (ignore ? const0_rtx : NULL_RTX),
4295 VOIDmode, EXPAND_NORMAL);
4298 /* Expand a call to __builtin_expect. We return our argument and emit a
4299 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4300 a non-jump context. */
4302 static rtx
4303 expand_builtin_expect (tree arglist, rtx target)
4305 tree exp, c;
4306 rtx note, rtx_c;
4308 if (arglist == NULL_TREE
4309 || TREE_CHAIN (arglist) == NULL_TREE)
4310 return const0_rtx;
4311 exp = TREE_VALUE (arglist);
4312 c = TREE_VALUE (TREE_CHAIN (arglist));
4314 if (TREE_CODE (c) != INTEGER_CST)
4316 error ("second arg to `__builtin_expect' must be a constant");
4317 c = integer_zero_node;
4320 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4322 /* Don't bother with expected value notes for integral constants. */
4323 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4325 /* We do need to force this into a register so that we can be
4326 moderately sure to be able to correctly interpret the branch
4327 condition later. */
4328 target = force_reg (GET_MODE (target), target);
4330 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4332 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
4333 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4336 return target;
4339 /* Like expand_builtin_expect, except do this in a jump context. This is
4340 called from do_jump if the conditional is a __builtin_expect. Return either
4341 a list of insns to emit the jump or NULL if we cannot optimize
4342 __builtin_expect. We need to optimize this at jump time so that machines
4343 like the PowerPC don't turn the test into a SCC operation, and then jump
4344 based on the test being 0/1. */
4347 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4349 tree arglist = TREE_OPERAND (exp, 1);
4350 tree arg0 = TREE_VALUE (arglist);
4351 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4352 rtx ret = NULL_RTX;
4354 /* Only handle __builtin_expect (test, 0) and
4355 __builtin_expect (test, 1). */
4356 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4357 && (integer_zerop (arg1) || integer_onep (arg1)))
4359 int num_jumps = 0;
4360 rtx insn;
4362 /* If we fail to locate an appropriate conditional jump, we'll
4363 fall back to normal evaluation. Ensure that the expression
4364 can be re-evaluated. */
4365 switch (unsafe_for_reeval (arg0))
4367 case 0: /* Safe. */
4368 break;
4370 case 1: /* Mildly unsafe. */
4371 arg0 = unsave_expr (arg0);
4372 break;
4374 case 2: /* Wildly unsafe. */
4375 return NULL_RTX;
4378 /* Expand the jump insns. */
4379 start_sequence ();
4380 do_jump (arg0, if_false_label, if_true_label);
4381 ret = get_insns ();
4382 end_sequence ();
4384 /* Now that the __builtin_expect has been validated, go through and add
4385 the expect's to each of the conditional jumps. If we run into an
4386 error, just give up and generate the 'safe' code of doing a SCC
4387 operation and then doing a branch on that. */
4388 insn = ret;
4389 while (insn != NULL_RTX)
4391 rtx next = NEXT_INSN (insn);
4393 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4395 rtx ifelse = SET_SRC (pc_set (insn));
4396 rtx label;
4397 int taken;
4399 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4401 taken = 1;
4402 label = XEXP (XEXP (ifelse, 1), 0);
4404 /* An inverted jump reverses the probabilities. */
4405 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4407 taken = 0;
4408 label = XEXP (XEXP (ifelse, 2), 0);
4410 /* We shouldn't have to worry about conditional returns during
4411 the expansion stage, but handle it gracefully anyway. */
4412 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4414 taken = 1;
4415 label = NULL_RTX;
4417 /* An inverted return reverses the probabilities. */
4418 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4420 taken = 0;
4421 label = NULL_RTX;
4423 else
4424 goto do_next_insn;
4426 /* If the test is expected to fail, reverse the
4427 probabilities. */
4428 if (integer_zerop (arg1))
4429 taken = 1 - taken;
4431 /* If we are jumping to the false label, reverse the
4432 probabilities. */
4433 if (label == NULL_RTX)
4434 ; /* conditional return */
4435 else if (label == if_false_label)
4436 taken = 1 - taken;
4437 else if (label != if_true_label)
4438 goto do_next_insn;
4440 num_jumps++;
4441 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4444 do_next_insn:
4445 insn = next;
4448 /* If no jumps were modified, fail and do __builtin_expect the normal
4449 way. */
4450 if (num_jumps == 0)
4451 ret = NULL_RTX;
4454 return ret;
4457 void
4458 expand_builtin_trap (void)
4460 #ifdef HAVE_trap
4461 if (HAVE_trap)
4462 emit_insn (gen_trap ());
4463 else
4464 #endif
4465 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4466 emit_barrier ();
4469 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4470 Return 0 if a normal call should be emitted rather than expanding
4471 the function inline. If convenient, the result should be placed
4472 in TARGET. SUBTARGET may be used as the target for computing
4473 the operand. */
4475 static rtx
4476 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4478 enum machine_mode mode;
4479 tree arg;
4480 rtx op0;
4482 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4483 return 0;
4485 arg = TREE_VALUE (arglist);
4486 mode = TYPE_MODE (TREE_TYPE (arg));
4487 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4488 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4491 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4492 Return 0 if a normal call should be emitted rather than expanding
4493 the function inline. If convenient, the result should be placed
4494 in target. */
4496 static rtx
4497 expand_builtin_cabs (tree arglist, rtx target)
4499 enum machine_mode mode;
4500 tree arg;
4501 rtx op0;
4503 if (arglist == 0 || TREE_CHAIN (arglist))
4504 return 0;
4505 arg = TREE_VALUE (arglist);
4506 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4507 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4508 return 0;
4510 mode = TYPE_MODE (TREE_TYPE (arg));
4511 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4512 return expand_complex_abs (mode, op0, target, 0);
4515 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4516 a normal call should be emitted rather than expanding the function
4517 inline. If convenient, the result should be placed in TARGET with
4518 mode MODE. */
4520 static rtx
4521 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4523 tree dest, fmt, stripped;
4524 tree orig_arglist;
4526 orig_arglist = arglist;
4528 /* Verify the required arguments in the original call. */
4529 if (! arglist)
4530 return 0;
4531 dest = TREE_VALUE (arglist);
4532 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4533 return 0;
4534 arglist = TREE_CHAIN (arglist);
4535 if (! arglist)
4536 return 0;
4537 fmt = TREE_VALUE (arglist);
4538 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4539 return 0;
4540 arglist = TREE_CHAIN (arglist);
4542 /* Check whether the format is a literal string constant. */
4543 stripped = fmt;
4544 STRIP_NOPS (stripped);
4545 if (stripped && TREE_CODE (stripped) == ADDR_EXPR)
4546 stripped = TREE_OPERAND (stripped, 0);
4547 if (TREE_CODE (stripped) != STRING_CST)
4548 return 0;
4550 /* If the format doesn't contain % args or %%, use strcpy. */
4551 if (strchr (TREE_STRING_POINTER (stripped), '%') == 0)
4553 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4554 tree exp;
4556 if (arglist || !fn)
4557 return 0;
4558 expand_expr (build_function_call_expr (fn, orig_arglist),
4559 const0_rtx, VOIDmode, EXPAND_NORMAL);
4560 if (target == const0_rtx)
4561 return const0_rtx;
4562 exp = build_int_2 (TREE_STRING_LENGTH (stripped) - 1, 0);
4563 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4564 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4566 /* If the format is "%s", use strcpy and possibly strlen. */
4567 else if (strcmp (TREE_STRING_POINTER (stripped), "%s") == 0)
4569 tree strcpy_fn, strlen_fn, exp, arg;
4570 strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4572 if (! strcpy_fn)
4573 return 0;
4575 if (! arglist || TREE_CHAIN (arglist))
4576 return 0;
4577 arg = TREE_VALUE (arglist);
4578 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4579 return 0;
4581 if (target != const0_rtx)
4583 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4584 if (! strlen_fn)
4585 return 0;
4586 arg = save_expr (arg);
4588 else
4589 strlen_fn = 0;
4591 arglist = build_tree_list (NULL_TREE, arg);
4592 arglist = tree_cons (NULL_TREE, dest, arglist);
4593 expand_expr (build_function_call_expr (strcpy_fn, arglist),
4594 const0_rtx, VOIDmode, EXPAND_NORMAL);
4596 if (target == const0_rtx)
4597 return const0_rtx;
4599 exp = build_function_call_expr (strlen_fn, TREE_CHAIN (arglist));
4600 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4601 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4604 return 0;
4607 /* Expand an expression EXP that calls a built-in function,
4608 with result going to TARGET if that's convenient
4609 (and in mode MODE if that's convenient).
4610 SUBTARGET may be used as the target for computing one of EXP's operands.
4611 IGNORE is nonzero if the value is to be ignored. */
4614 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4615 int ignore)
4617 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4618 tree arglist = TREE_OPERAND (exp, 1);
4619 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4620 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4622 /* Perform postincrements before expanding builtin functions.  */
4623 emit_queue ();
4625 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4626 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4628 /* When not optimizing, generate calls to library functions for a certain
4629 set of builtins. */
4630 if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
4631 switch (fcode)
4633 case BUILT_IN_SQRT:
4634 case BUILT_IN_SQRTF:
4635 case BUILT_IN_SQRTL:
4636 case BUILT_IN_SIN:
4637 case BUILT_IN_SINF:
4638 case BUILT_IN_SINL:
4639 case BUILT_IN_COS:
4640 case BUILT_IN_COSF:
4641 case BUILT_IN_COSL:
4642 case BUILT_IN_EXP:
4643 case BUILT_IN_EXPF:
4644 case BUILT_IN_EXPL:
4645 case BUILT_IN_LOG:
4646 case BUILT_IN_LOGF:
4647 case BUILT_IN_LOGL:
4648 case BUILT_IN_TAN:
4649 case BUILT_IN_TANF:
4650 case BUILT_IN_TANL:
4651 case BUILT_IN_ATAN:
4652 case BUILT_IN_ATANF:
4653 case BUILT_IN_ATANL:
4654 case BUILT_IN_POW:
4655 case BUILT_IN_POWF:
4656 case BUILT_IN_POWL:
4657 case BUILT_IN_ATAN2:
4658 case BUILT_IN_ATAN2F:
4659 case BUILT_IN_ATAN2L:
4660 case BUILT_IN_MEMSET:
4661 case BUILT_IN_MEMCPY:
4662 case BUILT_IN_MEMCMP:
4663 case BUILT_IN_MEMPCPY:
4664 case BUILT_IN_MEMMOVE:
4665 case BUILT_IN_BCMP:
4666 case BUILT_IN_BZERO:
4667 case BUILT_IN_BCOPY:
4668 case BUILT_IN_INDEX:
4669 case BUILT_IN_RINDEX:
4670 case BUILT_IN_SPRINTF:
4671 case BUILT_IN_STPCPY:
4672 case BUILT_IN_STRCHR:
4673 case BUILT_IN_STRRCHR:
4674 case BUILT_IN_STRLEN:
4675 case BUILT_IN_STRCPY:
4676 case BUILT_IN_STRNCPY:
4677 case BUILT_IN_STRNCMP:
4678 case BUILT_IN_STRSTR:
4679 case BUILT_IN_STRPBRK:
4680 case BUILT_IN_STRCAT:
4681 case BUILT_IN_STRNCAT:
4682 case BUILT_IN_STRSPN:
4683 case BUILT_IN_STRCSPN:
4684 case BUILT_IN_STRCMP:
4685 case BUILT_IN_FFS:
4686 case BUILT_IN_PUTCHAR:
4687 case BUILT_IN_PUTS:
4688 case BUILT_IN_PRINTF:
4689 case BUILT_IN_FPUTC:
4690 case BUILT_IN_FPUTS:
4691 case BUILT_IN_FWRITE:
4692 case BUILT_IN_PUTCHAR_UNLOCKED:
4693 case BUILT_IN_PUTS_UNLOCKED:
4694 case BUILT_IN_PRINTF_UNLOCKED:
4695 case BUILT_IN_FPUTC_UNLOCKED:
4696 case BUILT_IN_FPUTS_UNLOCKED:
4697 case BUILT_IN_FWRITE_UNLOCKED:
4698 case BUILT_IN_FLOOR:
4699 case BUILT_IN_FLOORF:
4700 case BUILT_IN_FLOORL:
4701 case BUILT_IN_CEIL:
4702 case BUILT_IN_CEILF:
4703 case BUILT_IN_CEILL:
4704 case BUILT_IN_TRUNC:
4705 case BUILT_IN_TRUNCF:
4706 case BUILT_IN_TRUNCL:
4707 case BUILT_IN_ROUND:
4708 case BUILT_IN_ROUNDF:
4709 case BUILT_IN_ROUNDL:
4710 case BUILT_IN_NEARBYINT:
4711 case BUILT_IN_NEARBYINTF:
4712 case BUILT_IN_NEARBYINTL:
4713 return expand_call (exp, target, ignore);
4715 default:
4716 break;
4719 /* The built-in function expanders test for target == const0_rtx
4720 to determine whether the function's result will be ignored. */
4721 if (ignore)
4722 target = const0_rtx;
4724 /* If the result of a pure or const built-in function is ignored, and
4725 none of its arguments are volatile, we can avoid expanding the
4726 built-in call and just evaluate the arguments for side-effects. */
4727 if (target == const0_rtx
4728 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4730 bool volatilep = false;
4731 tree arg;
4733 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4734 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4736 volatilep = true;
4737 break;
4740 if (! volatilep)
4742 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4743 expand_expr (TREE_VALUE (arg), const0_rtx,
4744 VOIDmode, EXPAND_NORMAL);
4745 return const0_rtx;
4749 switch (fcode)
4751 case BUILT_IN_ABS:
4752 case BUILT_IN_LABS:
4753 case BUILT_IN_LLABS:
4754 case BUILT_IN_IMAXABS:
4755 /* build_function_call changes these into ABS_EXPR. */
4756 abort ();
4758 case BUILT_IN_FABS:
4759 case BUILT_IN_FABSF:
4760 case BUILT_IN_FABSL:
4761 target = expand_builtin_fabs (arglist, target, subtarget);
4762 if (target)
4763 return target;
4764 break;
4766 case BUILT_IN_CABS:
4767 case BUILT_IN_CABSF:
4768 case BUILT_IN_CABSL:
4769 if (flag_unsafe_math_optimizations)
4771 target = expand_builtin_cabs (arglist, target);
4772 if (target)
4773 return target;
4775 break;
4777 case BUILT_IN_CONJ:
4778 case BUILT_IN_CONJF:
4779 case BUILT_IN_CONJL:
4780 case BUILT_IN_CREAL:
4781 case BUILT_IN_CREALF:
4782 case BUILT_IN_CREALL:
4783 case BUILT_IN_CIMAG:
4784 case BUILT_IN_CIMAGF:
4785 case BUILT_IN_CIMAGL:
4786 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4787 and IMAGPART_EXPR. */
4788 abort ();
4790 case BUILT_IN_SIN:
4791 case BUILT_IN_SINF:
4792 case BUILT_IN_SINL:
4793 case BUILT_IN_COS:
4794 case BUILT_IN_COSF:
4795 case BUILT_IN_COSL:
4796 case BUILT_IN_EXP:
4797 case BUILT_IN_EXPF:
4798 case BUILT_IN_EXPL:
4799 case BUILT_IN_LOG:
4800 case BUILT_IN_LOGF:
4801 case BUILT_IN_LOGL:
4802 case BUILT_IN_TAN:
4803 case BUILT_IN_TANF:
4804 case BUILT_IN_TANL:
4805 case BUILT_IN_ATAN:
4806 case BUILT_IN_ATANF:
4807 case BUILT_IN_ATANL:
4808 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4809 because of possible accuracy problems. */
4810 if (! flag_unsafe_math_optimizations)
4811 break;
4812 case BUILT_IN_SQRT:
4813 case BUILT_IN_SQRTF:
4814 case BUILT_IN_SQRTL:
4815 case BUILT_IN_FLOOR:
4816 case BUILT_IN_FLOORF:
4817 case BUILT_IN_FLOORL:
4818 case BUILT_IN_CEIL:
4819 case BUILT_IN_CEILF:
4820 case BUILT_IN_CEILL:
4821 case BUILT_IN_TRUNC:
4822 case BUILT_IN_TRUNCF:
4823 case BUILT_IN_TRUNCL:
4824 case BUILT_IN_ROUND:
4825 case BUILT_IN_ROUNDF:
4826 case BUILT_IN_ROUNDL:
4827 case BUILT_IN_NEARBYINT:
4828 case BUILT_IN_NEARBYINTF:
4829 case BUILT_IN_NEARBYINTL:
4830 target = expand_builtin_mathfn (exp, target, subtarget);
4831 if (target)
4832 return target;
4833 break;
4835 case BUILT_IN_POW:
4836 case BUILT_IN_POWF:
4837 case BUILT_IN_POWL:
4838 if (! flag_unsafe_math_optimizations)
4839 break;
4840 target = expand_builtin_pow (exp, target, subtarget);
4841 if (target)
4842 return target;
4843 break;
4845 case BUILT_IN_ATAN2:
4846 case BUILT_IN_ATAN2F:
4847 case BUILT_IN_ATAN2L:
4848 if (! flag_unsafe_math_optimizations)
4849 break;
4850 target = expand_builtin_mathfn_2 (exp, target, subtarget);
4851 if (target)
4852 return target;
4853 break;
4855 case BUILT_IN_APPLY_ARGS:
4856 return expand_builtin_apply_args ();
4858 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4859 FUNCTION with a copy of the parameters described by
4860 ARGUMENTS, and ARGSIZE. It returns a block of memory
4861 allocated on the stack into which is stored all the registers
4862 that might possibly be used for returning the result of a
4863 function. ARGUMENTS is the value returned by
4864 __builtin_apply_args. ARGSIZE is the number of bytes of
4865 arguments that must be copied. ??? How should this value be
4866 computed? We'll also need a safe worst case value for varargs
4867 functions. */
4868 case BUILT_IN_APPLY:
4869 if (!validate_arglist (arglist, POINTER_TYPE,
4870 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4871 && !validate_arglist (arglist, REFERENCE_TYPE,
4872 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4873 return const0_rtx;
4874 else
4876 int i;
4877 tree t;
4878 rtx ops[3];
4880 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4881 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4883 return expand_builtin_apply (ops[0], ops[1], ops[2]);
4886 /* __builtin_return (RESULT) causes the function to return the
4887 value described by RESULT. RESULT is address of the block of
4888 memory returned by __builtin_apply. */
4889 case BUILT_IN_RETURN:
4890 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4891 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4892 NULL_RTX, VOIDmode, 0));
4893 return const0_rtx;
4895 case BUILT_IN_SAVEREGS:
4896 return expand_builtin_saveregs ();
4898 case BUILT_IN_ARGS_INFO:
4899 return expand_builtin_args_info (arglist);
4901 /* Return the address of the first anonymous stack arg. */
4902 case BUILT_IN_NEXT_ARG:
4903 return expand_builtin_next_arg (arglist);
4905 case BUILT_IN_CLASSIFY_TYPE:
4906 return expand_builtin_classify_type (arglist);
4908 case BUILT_IN_CONSTANT_P:
4909 return expand_builtin_constant_p (arglist, target_mode);
4911 case BUILT_IN_FRAME_ADDRESS:
4912 case BUILT_IN_RETURN_ADDRESS:
4913 return expand_builtin_frame_address (fndecl, arglist);
4915 /* Returns the address of the area where the structure is returned.
4916 0 otherwise. */
4917 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
4918 if (arglist != 0
4919 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
4920 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
4921 return const0_rtx;
4922 else
4923 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
4925 case BUILT_IN_ALLOCA:
4926 target = expand_builtin_alloca (arglist, target);
4927 if (target)
4928 return target;
4929 break;
4931 case BUILT_IN_FFS:
4932 case BUILT_IN_FFSL:
4933 case BUILT_IN_FFSLL:
4934 target = expand_builtin_unop (target_mode, arglist, target,
4935 subtarget, ffs_optab);
4936 if (target)
4937 return target;
4938 break;
4940 case BUILT_IN_CLZ:
4941 case BUILT_IN_CLZL:
4942 case BUILT_IN_CLZLL:
4943 target = expand_builtin_unop (target_mode, arglist, target,
4944 subtarget, clz_optab);
4945 if (target)
4946 return target;
4947 break;
4949 case BUILT_IN_CTZ:
4950 case BUILT_IN_CTZL:
4951 case BUILT_IN_CTZLL:
4952 target = expand_builtin_unop (target_mode, arglist, target,
4953 subtarget, ctz_optab);
4954 if (target)
4955 return target;
4956 break;
4958 case BUILT_IN_POPCOUNT:
4959 case BUILT_IN_POPCOUNTL:
4960 case BUILT_IN_POPCOUNTLL:
4961 target = expand_builtin_unop (target_mode, arglist, target,
4962 subtarget, popcount_optab);
4963 if (target)
4964 return target;
4965 break;
4967 case BUILT_IN_PARITY:
4968 case BUILT_IN_PARITYL:
4969 case BUILT_IN_PARITYLL:
4970 target = expand_builtin_unop (target_mode, arglist, target,
4971 subtarget, parity_optab);
4972 if (target)
4973 return target;
4974 break;
4976 case BUILT_IN_STRLEN:
4977 target = expand_builtin_strlen (arglist, target, target_mode);
4978 if (target)
4979 return target;
4980 break;
4982 case BUILT_IN_STRCPY:
4983 target = expand_builtin_strcpy (arglist, target, mode);
4984 if (target)
4985 return target;
4986 break;
4988 case BUILT_IN_STRNCPY:
4989 target = expand_builtin_strncpy (arglist, target, mode);
4990 if (target)
4991 return target;
4992 break;
4994 case BUILT_IN_STPCPY:
4995 target = expand_builtin_stpcpy (arglist, target, mode);
4996 if (target)
4997 return target;
4998 break;
5000 case BUILT_IN_STRCAT:
5001 target = expand_builtin_strcat (arglist, target, mode);
5002 if (target)
5003 return target;
5004 break;
5006 case BUILT_IN_STRNCAT:
5007 target = expand_builtin_strncat (arglist, target, mode);
5008 if (target)
5009 return target;
5010 break;
5012 case BUILT_IN_STRSPN:
5013 target = expand_builtin_strspn (arglist, target, mode);
5014 if (target)
5015 return target;
5016 break;
5018 case BUILT_IN_STRCSPN:
5019 target = expand_builtin_strcspn (arglist, target, mode);
5020 if (target)
5021 return target;
5022 break;
5024 case BUILT_IN_STRSTR:
5025 target = expand_builtin_strstr (arglist, target, mode);
5026 if (target)
5027 return target;
5028 break;
5030 case BUILT_IN_STRPBRK:
5031 target = expand_builtin_strpbrk (arglist, target, mode);
5032 if (target)
5033 return target;
5034 break;
5036 case BUILT_IN_INDEX:
5037 case BUILT_IN_STRCHR:
5038 target = expand_builtin_strchr (arglist, target, mode);
5039 if (target)
5040 return target;
5041 break;
5043 case BUILT_IN_RINDEX:
5044 case BUILT_IN_STRRCHR:
5045 target = expand_builtin_strrchr (arglist, target, mode);
5046 if (target)
5047 return target;
5048 break;
5050 case BUILT_IN_MEMCPY:
5051 target = expand_builtin_memcpy (arglist, target, mode);
5052 if (target)
5053 return target;
5054 break;
5056 case BUILT_IN_MEMPCPY:
5057 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5058 if (target)
5059 return target;
5060 break;
5062 case BUILT_IN_MEMMOVE:
5063 target = expand_builtin_memmove (arglist, target, mode);
5064 if (target)
5065 return target;
5066 break;
5068 case BUILT_IN_BCOPY:
5069 target = expand_builtin_bcopy (arglist);
5070 if (target)
5071 return target;
5072 break;
5074 case BUILT_IN_MEMSET:
5075 target = expand_builtin_memset (arglist, target, mode);
5076 if (target)
5077 return target;
5078 break;
5080 case BUILT_IN_BZERO:
5081 target = expand_builtin_bzero (arglist);
5082 if (target)
5083 return target;
5084 break;
5086 case BUILT_IN_STRCMP:
5087 target = expand_builtin_strcmp (exp, target, mode);
5088 if (target)
5089 return target;
5090 break;
5092 case BUILT_IN_STRNCMP:
5093 target = expand_builtin_strncmp (exp, target, mode);
5094 if (target)
5095 return target;
5096 break;
5098 case BUILT_IN_BCMP:
5099 case BUILT_IN_MEMCMP:
5100 target = expand_builtin_memcmp (exp, arglist, target, mode);
5101 if (target)
5102 return target;
5103 break;
5105 case BUILT_IN_SETJMP:
5106 target = expand_builtin_setjmp (arglist, target);
5107 if (target)
5108 return target;
5109 break;
5111 /* __builtin_longjmp is passed a pointer to an array of five words.
5112 It's similar to the C library longjmp function but works with
5113 __builtin_setjmp above. */
5114 case BUILT_IN_LONGJMP:
5115 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5116 break;
5117 else
5119 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5120 VOIDmode, 0);
5121 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5122 NULL_RTX, VOIDmode, 0);
5124 if (value != const1_rtx)
5126 error ("__builtin_longjmp second argument must be 1");
5127 return const0_rtx;
5130 expand_builtin_longjmp (buf_addr, value);
5131 return const0_rtx;
5134 case BUILT_IN_TRAP:
5135 expand_builtin_trap ();
5136 return const0_rtx;
5138 case BUILT_IN_FPUTS:
5139 target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
5140 if (target)
5141 return target;
5142 break;
5143 case BUILT_IN_FPUTS_UNLOCKED:
5144 target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
5145 if (target)
5146 return target;
5147 break;
5149 case BUILT_IN_SPRINTF:
5150 target = expand_builtin_sprintf (arglist, target, mode);
5151 if (target)
5152 return target;
5153 break;
5155 /* Various hooks for the DWARF 2 __throw routine. */
5156 case BUILT_IN_UNWIND_INIT:
5157 expand_builtin_unwind_init ();
5158 return const0_rtx;
5159 case BUILT_IN_DWARF_CFA:
5160 return virtual_cfa_rtx;
5161 #ifdef DWARF2_UNWIND_INFO
5162 case BUILT_IN_DWARF_SP_COLUMN:
5163 return expand_builtin_dwarf_sp_column ();
5164 case BUILT_IN_INIT_DWARF_REG_SIZES:
5165 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5166 return const0_rtx;
5167 #endif
5168 case BUILT_IN_FROB_RETURN_ADDR:
5169 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5170 case BUILT_IN_EXTRACT_RETURN_ADDR:
5171 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5172 case BUILT_IN_EH_RETURN:
5173 expand_builtin_eh_return (TREE_VALUE (arglist),
5174 TREE_VALUE (TREE_CHAIN (arglist)));
5175 return const0_rtx;
5176 #ifdef EH_RETURN_DATA_REGNO
5177 case BUILT_IN_EH_RETURN_DATA_REGNO:
5178 return expand_builtin_eh_return_data_regno (arglist);
5179 #endif
5180 case BUILT_IN_VA_START:
5181 case BUILT_IN_STDARG_START:
5182 return expand_builtin_va_start (arglist);
5183 case BUILT_IN_VA_END:
5184 return expand_builtin_va_end (arglist);
5185 case BUILT_IN_VA_COPY:
5186 return expand_builtin_va_copy (arglist);
5187 case BUILT_IN_EXPECT:
5188 return expand_builtin_expect (arglist, target);
5189 case BUILT_IN_PREFETCH:
5190 expand_builtin_prefetch (arglist);
5191 return const0_rtx;
5194 default: /* just do library call, if unknown builtin */
5195 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5196 error ("built-in function `%s' not currently supported",
5197 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5200 /* The switch statement above can drop through to cause the function
5201 to be called normally. */
5202 return expand_call (exp, target, ignore);
5205 /* Determine whether a tree node represents a call to a built-in
5206 math function. If the tree T is a call to a built-in function
5207 taking a single real argument, then the return value is the
5208 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
5209 the return value is END_BUILTINS. */
5211 enum built_in_function
5212 builtin_mathfn_code (tree t)
5214 tree fndecl, arglist;
5216 if (TREE_CODE (t) != CALL_EXPR
5217 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5218 return END_BUILTINS;
5220 fndecl = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
5221 if (TREE_CODE (fndecl) != FUNCTION_DECL
5222 || ! DECL_BUILT_IN (fndecl)
5223 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5224 return END_BUILTINS;
5226 arglist = TREE_OPERAND (t, 1);
5227 if (! arglist
5228 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
5229 return END_BUILTINS;
5231 arglist = TREE_CHAIN (arglist);
5232 switch (DECL_FUNCTION_CODE (fndecl))
5234 case BUILT_IN_POW:
5235 case BUILT_IN_POWF:
5236 case BUILT_IN_POWL:
5237 case BUILT_IN_ATAN2:
5238 case BUILT_IN_ATAN2F:
5239 case BUILT_IN_ATAN2L:
5240 if (! arglist
5241 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
5242 || TREE_CHAIN (arglist))
5243 return END_BUILTINS;
5244 break;
5246 default:
5247 if (arglist)
5248 return END_BUILTINS;
5249 break;
5252 return DECL_FUNCTION_CODE (fndecl);
5255 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5256 constant. ARGLIST is the argument list of the call. */
5258 static tree
5259 fold_builtin_constant_p (tree arglist)
5261 if (arglist == 0)
5262 return 0;
5264 arglist = TREE_VALUE (arglist);
5266 /* We return 1 for a numeric type that's known to be a constant
5267 value at compile-time or for an aggregate type that's a
5268 literal constant. */
5269 STRIP_NOPS (arglist);
5271 /* If we know this is a constant, emit the constant of one. */
5272 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5273 || (TREE_CODE (arglist) == CONSTRUCTOR
5274 && TREE_CONSTANT (arglist))
5275 || (TREE_CODE (arglist) == ADDR_EXPR
5276 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5277 return integer_one_node;
5279 /* If we aren't going to be running CSE or this expression
5280 has side effects, show we don't know it to be a constant.
5281 Likewise if it's a pointer or aggregate type since in those
5282 case we only want literals, since those are only optimized
5283 when generating RTL, not later.
5284 And finally, if we are compiling an initializer, not code, we
5285 need to return a definite result now; there's not going to be any
5286 more optimization done. */
5287 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
5288 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5289 || POINTER_TYPE_P (TREE_TYPE (arglist))
5290 || cfun == 0)
5291 return integer_zero_node;
5293 return 0;
5296 /* Fold a call to __builtin_classify_type. */
5298 static tree
5299 fold_builtin_classify_type (tree arglist)
5301 if (arglist == 0)
5302 return build_int_2 (no_type_class, 0);
5304 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5307 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5309 static tree
5310 fold_builtin_inf (tree type, int warn)
5312 REAL_VALUE_TYPE real;
5314 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5315 warning ("target format does not support infinity");
5317 real_inf (&real);
5318 return build_real (type, real);
5321 /* Fold a call to __builtin_nan or __builtin_nans. */
5323 static tree
5324 fold_builtin_nan (tree arglist, tree type, int quiet)
5326 REAL_VALUE_TYPE real;
5327 const char *str;
5329 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5330 return 0;
5331 str = c_getstr (TREE_VALUE (arglist));
5332 if (!str)
5333 return 0;
5335 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5336 return 0;
5338 return build_real (type, real);
5341 /* EXP is assumed to me builtin call where truncation can be propagated
5342 across (for instance floor((double)f) == (double)floorf (f).
5343 Do the transformation. */
5344 static tree
5345 fold_trunc_transparent_mathfn (tree exp)
5347 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5348 tree arglist = TREE_OPERAND (exp, 1);
5349 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5351 if (optimize && validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5353 tree arg0 = strip_float_extensions (TREE_VALUE (arglist));
5354 tree ftype = TREE_TYPE (exp);
5355 tree newtype = TREE_TYPE (arg0);
5356 tree decl;
5358 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5359 && (decl = mathfn_built_in (newtype, fcode)))
5361 arglist =
5362 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5363 return convert (ftype,
5364 build_function_call_expr (decl, arglist));
5367 return 0;
5370 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5371 function's DECL, ARGLIST is the argument list and TYPE is the return
5372 type. Return NULL_TREE if no simplification can be made. */
5374 static tree
5375 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5377 tree arg;
5379 if (!arglist || TREE_CHAIN (arglist))
5380 return NULL_TREE;
5382 arg = TREE_VALUE (arglist);
5383 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5384 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5385 return NULL_TREE;
5387 /* Evaluate cabs of a constant at compile-time. */
5388 if (flag_unsafe_math_optimizations
5389 && TREE_CODE (arg) == COMPLEX_CST
5390 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5391 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5392 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5393 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5395 REAL_VALUE_TYPE r, i;
5397 r = TREE_REAL_CST (TREE_REALPART (arg));
5398 i = TREE_REAL_CST (TREE_IMAGPART (arg));
5400 real_arithmetic (&r, MULT_EXPR, &r, &r);
5401 real_arithmetic (&i, MULT_EXPR, &i, &i);
5402 real_arithmetic (&r, PLUS_EXPR, &r, &i);
5403 if (real_sqrt (&r, TYPE_MODE (type), &r)
5404 || ! flag_trapping_math)
5405 return build_real (type, r);
5408 /* If either part is zero, cabs is fabs of the other. */
5409 if (TREE_CODE (arg) == COMPLEX_EXPR
5410 && real_zerop (TREE_OPERAND (arg, 0)))
5411 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5412 if (TREE_CODE (arg) == COMPLEX_EXPR
5413 && real_zerop (TREE_OPERAND (arg, 1)))
5414 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5416 if (flag_unsafe_math_optimizations)
5418 enum built_in_function fcode;
5419 tree sqrtfn;
5421 fcode = DECL_FUNCTION_CODE (fndecl);
5422 if (fcode == BUILT_IN_CABS)
5423 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5424 else if (fcode == BUILT_IN_CABSF)
5425 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5426 else if (fcode == BUILT_IN_CABSL)
5427 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5428 else
5429 sqrtfn = NULL_TREE;
5431 if (sqrtfn != NULL_TREE)
5433 tree rpart, ipart, result, arglist;
5435 rpart = fold (build1 (REALPART_EXPR, type, arg));
5436 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5438 rpart = save_expr (rpart);
5439 ipart = save_expr (ipart);
5441 result = fold (build (PLUS_EXPR, type,
5442 fold (build (MULT_EXPR, type,
5443 rpart, rpart)),
5444 fold (build (MULT_EXPR, type,
5445 ipart, ipart))));
5447 arglist = build_tree_list (NULL_TREE, result);
5448 return build_function_call_expr (sqrtfn, arglist);
5452 return NULL_TREE;
5455 /* Used by constant folding to eliminate some builtin calls early. EXP is
5456 the CALL_EXPR of a call to a builtin function. */
5458 tree
5459 fold_builtin (tree exp)
5461 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5462 tree arglist = TREE_OPERAND (exp, 1);
5463 tree type = TREE_TYPE (TREE_TYPE (fndecl));
5465 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5466 return 0;
5468 switch (DECL_FUNCTION_CODE (fndecl))
5470 case BUILT_IN_CONSTANT_P:
5471 return fold_builtin_constant_p (arglist);
5473 case BUILT_IN_CLASSIFY_TYPE:
5474 return fold_builtin_classify_type (arglist);
5476 case BUILT_IN_STRLEN:
5477 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5479 tree len = c_strlen (TREE_VALUE (arglist));
5480 if (len)
5482 /* Convert from the internal "sizetype" type to "size_t". */
5483 if (size_type_node)
5484 len = convert (size_type_node, len);
5485 return len;
5488 break;
5490 case BUILT_IN_FABS:
5491 case BUILT_IN_FABSF:
5492 case BUILT_IN_FABSL:
5493 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5494 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
5495 break;
5497 case BUILT_IN_CABS:
5498 case BUILT_IN_CABSF:
5499 case BUILT_IN_CABSL:
5500 return fold_builtin_cabs (fndecl, arglist, type);
5502 case BUILT_IN_SQRT:
5503 case BUILT_IN_SQRTF:
5504 case BUILT_IN_SQRTL:
5505 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5507 enum built_in_function fcode;
5508 tree arg = TREE_VALUE (arglist);
5510 /* Optimize sqrt of constant value. */
5511 if (TREE_CODE (arg) == REAL_CST
5512 && ! TREE_CONSTANT_OVERFLOW (arg))
5514 REAL_VALUE_TYPE r, x;
5516 x = TREE_REAL_CST (arg);
5517 if (real_sqrt (&r, TYPE_MODE (type), &x)
5518 || (!flag_trapping_math && !flag_errno_math))
5519 return build_real (type, r);
5522 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
5523 fcode = builtin_mathfn_code (arg);
5524 if (flag_unsafe_math_optimizations
5525 && (fcode == BUILT_IN_EXP
5526 || fcode == BUILT_IN_EXPF
5527 || fcode == BUILT_IN_EXPL))
5529 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
5530 arg = fold (build (MULT_EXPR, type,
5531 TREE_VALUE (TREE_OPERAND (arg, 1)),
5532 build_real (type, dconsthalf)));
5533 arglist = build_tree_list (NULL_TREE, arg);
5534 return build_function_call_expr (expfn, arglist);
5537 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
5538 if (flag_unsafe_math_optimizations
5539 && (fcode == BUILT_IN_POW
5540 || fcode == BUILT_IN_POWF
5541 || fcode == BUILT_IN_POWL))
5543 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
5544 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
5545 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
5546 tree narg1 = fold (build (MULT_EXPR, type, arg1,
5547 build_real (type, dconsthalf)));
5548 arglist = tree_cons (NULL_TREE, arg0,
5549 build_tree_list (NULL_TREE, narg1));
5550 return build_function_call_expr (powfn, arglist);
5553 break;
5555 case BUILT_IN_SIN:
5556 case BUILT_IN_SINF:
5557 case BUILT_IN_SINL:
5558 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5560 tree arg = TREE_VALUE (arglist);
5562 /* Optimize sin(0.0) = 0.0. */
5563 if (real_zerop (arg))
5564 return arg;
5566 break;
5568 case BUILT_IN_COS:
5569 case BUILT_IN_COSF:
5570 case BUILT_IN_COSL:
5571 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5573 tree arg = TREE_VALUE (arglist);
5575 /* Optimize cos(0.0) = 1.0. */
5576 if (real_zerop (arg))
5577 return build_real (type, dconst1);
5579 /* Optimize cos(-x) into cos(x). */
5580 if (TREE_CODE (arg) == NEGATE_EXPR)
5582 tree arglist = build_tree_list (NULL_TREE,
5583 TREE_OPERAND (arg, 0));
5584 return build_function_call_expr (fndecl, arglist);
5587 break;
5589 case BUILT_IN_EXP:
5590 case BUILT_IN_EXPF:
5591 case BUILT_IN_EXPL:
5592 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5594 enum built_in_function fcode;
5595 tree arg = TREE_VALUE (arglist);
5597 /* Optimize exp(0.0) = 1.0. */
5598 if (real_zerop (arg))
5599 return build_real (type, dconst1);
5601 /* Optimize exp(1.0) = e. */
5602 if (real_onep (arg))
5604 REAL_VALUE_TYPE cst;
5606 if (! builtin_dconsts_init)
5607 init_builtin_dconsts ();
5608 real_convert (&cst, TYPE_MODE (type), &dconste);
5609 return build_real (type, cst);
5612 /* Attempt to evaluate exp at compile-time. */
5613 if (flag_unsafe_math_optimizations
5614 && TREE_CODE (arg) == REAL_CST
5615 && ! TREE_CONSTANT_OVERFLOW (arg))
5617 REAL_VALUE_TYPE cint;
5618 REAL_VALUE_TYPE c;
5619 HOST_WIDE_INT n;
5621 c = TREE_REAL_CST (arg);
5622 n = real_to_integer (&c);
5623 real_from_integer (&cint, VOIDmode, n,
5624 n < 0 ? -1 : 0, 0);
5625 if (real_identical (&c, &cint))
5627 REAL_VALUE_TYPE x;
5629 if (! builtin_dconsts_init)
5630 init_builtin_dconsts ();
5631 real_powi (&x, TYPE_MODE (type), &dconste, n);
5632 return build_real (type, x);
5636 /* Optimize exp(log(x)) = x. */
5637 fcode = builtin_mathfn_code (arg);
5638 if (flag_unsafe_math_optimizations
5639 && (fcode == BUILT_IN_LOG
5640 || fcode == BUILT_IN_LOGF
5641 || fcode == BUILT_IN_LOGL))
5642 return TREE_VALUE (TREE_OPERAND (arg, 1));
5644 break;
5646 case BUILT_IN_LOG:
5647 case BUILT_IN_LOGF:
5648 case BUILT_IN_LOGL:
5649 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5651 enum built_in_function fcode;
5652 tree arg = TREE_VALUE (arglist);
5654 /* Optimize log(1.0) = 0.0. */
5655 if (real_onep (arg))
5656 return build_real (type, dconst0);
5658 /* Optimize log(exp(x)) = x. */
5659 fcode = builtin_mathfn_code (arg);
5660 if (flag_unsafe_math_optimizations
5661 && (fcode == BUILT_IN_EXP
5662 || fcode == BUILT_IN_EXPF
5663 || fcode == BUILT_IN_EXPL))
5664 return TREE_VALUE (TREE_OPERAND (arg, 1));
5666 /* Optimize log(sqrt(x)) = log(x)*0.5. */
5667 if (flag_unsafe_math_optimizations
5668 && (fcode == BUILT_IN_SQRT
5669 || fcode == BUILT_IN_SQRTF
5670 || fcode == BUILT_IN_SQRTL))
5672 tree logfn = build_function_call_expr (fndecl,
5673 TREE_OPERAND (arg, 1));
5674 return fold (build (MULT_EXPR, type, logfn,
5675 build_real (type, dconsthalf)));
5678 /* Optimize log(pow(x,y)) = y*log(x). */
5679 if (flag_unsafe_math_optimizations
5680 && (fcode == BUILT_IN_POW
5681 || fcode == BUILT_IN_POWF
5682 || fcode == BUILT_IN_POWL))
5684 tree arg0, arg1, logfn;
5686 arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
5687 arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
5688 arglist = build_tree_list (NULL_TREE, arg0);
5689 logfn = build_function_call_expr (fndecl, arglist);
5690 return fold (build (MULT_EXPR, type, arg1, logfn));
5693 break;
5695 case BUILT_IN_TAN:
5696 case BUILT_IN_TANF:
5697 case BUILT_IN_TANL:
5698 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5700 enum built_in_function fcode;
5701 tree arg = TREE_VALUE (arglist);
5703 /* Optimize tan(0.0) = 0.0. */
5704 if (real_zerop (arg))
5705 return arg;
5707 /* Optimize tan(atan(x)) = x. */
5708 fcode = builtin_mathfn_code (arg);
5709 if (flag_unsafe_math_optimizations
5710 && (fcode == BUILT_IN_ATAN
5711 || fcode == BUILT_IN_ATANF
5712 || fcode == BUILT_IN_ATANL))
5713 return TREE_VALUE (TREE_OPERAND (arg, 1));
5715 break;
5717 case BUILT_IN_ATAN:
5718 case BUILT_IN_ATANF:
5719 case BUILT_IN_ATANL:
5720 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5722 tree arg = TREE_VALUE (arglist);
5724 /* Optimize atan(0.0) = 0.0. */
5725 if (real_zerop (arg))
5726 return arg;
5728 /* Optimize atan(1.0) = pi/4. */
5729 if (real_onep (arg))
5731 REAL_VALUE_TYPE cst;
5733 if (! builtin_dconsts_init)
5734 init_builtin_dconsts ();
5735 real_convert (&cst, TYPE_MODE (type), &dconstpi);
5736 cst.exp -= 2;
5737 return build_real (type, cst);
5740 break;
5742 case BUILT_IN_POW:
5743 case BUILT_IN_POWF:
5744 case BUILT_IN_POWL:
5745 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5747 enum built_in_function fcode;
5748 tree arg0 = TREE_VALUE (arglist);
5749 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5751 /* Optimize pow(1.0,y) = 1.0. */
5752 if (real_onep (arg0))
5753 return omit_one_operand (type, build_real (type, dconst1), arg1);
5755 if (TREE_CODE (arg1) == REAL_CST
5756 && ! TREE_CONSTANT_OVERFLOW (arg1))
5758 REAL_VALUE_TYPE c;
5759 c = TREE_REAL_CST (arg1);
5761 /* Optimize pow(x,0.0) = 1.0. */
5762 if (REAL_VALUES_EQUAL (c, dconst0))
5763 return omit_one_operand (type, build_real (type, dconst1),
5764 arg0);
5766 /* Optimize pow(x,1.0) = x. */
5767 if (REAL_VALUES_EQUAL (c, dconst1))
5768 return arg0;
5770 /* Optimize pow(x,-1.0) = 1.0/x. */
5771 if (REAL_VALUES_EQUAL (c, dconstm1))
5772 return fold (build (RDIV_EXPR, type,
5773 build_real (type, dconst1),
5774 arg0));
5776 /* Optimize pow(x,2.0) = x*x. */
5777 if (REAL_VALUES_EQUAL (c, dconst2)
5778 && (*lang_hooks.decls.global_bindings_p) () == 0
5779 && ! CONTAINS_PLACEHOLDER_P (arg0))
5781 arg0 = save_expr (arg0);
5782 return fold (build (MULT_EXPR, type, arg0, arg0));
5785 /* Optimize pow(x,-2.0) = 1.0/(x*x). */
5786 if (flag_unsafe_math_optimizations
5787 && REAL_VALUES_EQUAL (c, dconstm2)
5788 && (*lang_hooks.decls.global_bindings_p) () == 0
5789 && ! CONTAINS_PLACEHOLDER_P (arg0))
5791 arg0 = save_expr (arg0);
5792 return fold (build (RDIV_EXPR, type,
5793 build_real (type, dconst1),
5794 fold (build (MULT_EXPR, type,
5795 arg0, arg0))));
5798 /* Optimize pow(x,0.5) = sqrt(x). */
5799 if (flag_unsafe_math_optimizations
5800 && REAL_VALUES_EQUAL (c, dconsthalf))
5802 tree sqrtfn;
5804 fcode = DECL_FUNCTION_CODE (fndecl);
5805 if (fcode == BUILT_IN_POW)
5806 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5807 else if (fcode == BUILT_IN_POWF)
5808 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5809 else if (fcode == BUILT_IN_POWL)
5810 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5811 else
5812 sqrtfn = NULL_TREE;
5814 if (sqrtfn != NULL_TREE)
5816 tree arglist = build_tree_list (NULL_TREE, arg0);
5817 return build_function_call_expr (sqrtfn, arglist);
5821 /* Attempt to evaluate pow at compile-time. */
5822 if (TREE_CODE (arg0) == REAL_CST
5823 && ! TREE_CONSTANT_OVERFLOW (arg0))
5825 REAL_VALUE_TYPE cint;
5826 HOST_WIDE_INT n;
5828 n = real_to_integer (&c);
5829 real_from_integer (&cint, VOIDmode, n,
5830 n < 0 ? -1 : 0, 0);
5831 if (real_identical (&c, &cint))
5833 REAL_VALUE_TYPE x;
5834 bool inexact;
5836 x = TREE_REAL_CST (arg0);
5837 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
5838 if (flag_unsafe_math_optimizations || !inexact)
5839 return build_real (type, x);
5844 /* Optimize pow(exp(x),y) = exp(x*y). */
5845 fcode = builtin_mathfn_code (arg0);
5846 if (flag_unsafe_math_optimizations
5847 && (fcode == BUILT_IN_EXP
5848 || fcode == BUILT_IN_EXPF
5849 || fcode == BUILT_IN_EXPL))
5851 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
5852 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
5853 arg = fold (build (MULT_EXPR, type, arg, arg1));
5854 arglist = build_tree_list (NULL_TREE, arg);
5855 return build_function_call_expr (expfn, arglist);
5858 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
5859 if (flag_unsafe_math_optimizations
5860 && (fcode == BUILT_IN_SQRT
5861 || fcode == BUILT_IN_SQRTF
5862 || fcode == BUILT_IN_SQRTL))
5864 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
5865 tree narg1 = fold (build (MULT_EXPR, type, arg1,
5866 build_real (type, dconsthalf)));
5868 arglist = tree_cons (NULL_TREE, narg0,
5869 build_tree_list (NULL_TREE, narg1));
5870 return build_function_call_expr (fndecl, arglist);
5873 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
5874 if (flag_unsafe_math_optimizations
5875 && (fcode == BUILT_IN_POW
5876 || fcode == BUILT_IN_POWF
5877 || fcode == BUILT_IN_POWL))
5879 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
5880 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
5881 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
5882 arglist = tree_cons (NULL_TREE, arg00,
5883 build_tree_list (NULL_TREE, narg1));
5884 return build_function_call_expr (fndecl, arglist);
5887 break;
5889 case BUILT_IN_INF:
5890 case BUILT_IN_INFF:
5891 case BUILT_IN_INFL:
5892 return fold_builtin_inf (type, true);
5894 case BUILT_IN_HUGE_VAL:
5895 case BUILT_IN_HUGE_VALF:
5896 case BUILT_IN_HUGE_VALL:
5897 return fold_builtin_inf (type, false);
5899 case BUILT_IN_NAN:
5900 case BUILT_IN_NANF:
5901 case BUILT_IN_NANL:
5902 return fold_builtin_nan (arglist, type, true);
5904 case BUILT_IN_NANS:
5905 case BUILT_IN_NANSF:
5906 case BUILT_IN_NANSL:
5907 return fold_builtin_nan (arglist, type, false);
5909 case BUILT_IN_FLOOR:
5910 case BUILT_IN_FLOORF:
5911 case BUILT_IN_FLOORL:
5912 case BUILT_IN_CEIL:
5913 case BUILT_IN_CEILF:
5914 case BUILT_IN_CEILL:
5915 case BUILT_IN_TRUNC:
5916 case BUILT_IN_TRUNCF:
5917 case BUILT_IN_TRUNCL:
5918 case BUILT_IN_ROUND:
5919 case BUILT_IN_ROUNDF:
5920 case BUILT_IN_ROUNDL:
5921 case BUILT_IN_NEARBYINT:
5922 case BUILT_IN_NEARBYINTF:
5923 case BUILT_IN_NEARBYINTL:
5924 return fold_trunc_transparent_mathfn (exp);
5926 default:
5927 break;
5930 return 0;
5933 /* Conveniently construct a function call expression. */
5935 tree
5936 build_function_call_expr (tree fn, tree arglist)
5938 tree call_expr;
5940 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
5941 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
5942 call_expr, arglist);
5943 TREE_SIDE_EFFECTS (call_expr) = 1;
5944 return fold (call_expr);
5947 /* This function validates the types of a function call argument list
5948 represented as a tree chain of parameters against a specified list
5949 of tree_codes. If the last specifier is a 0, that represents an
5950 ellipses, otherwise the last specifier must be a VOID_TYPE. */
5952 static int
5953 validate_arglist (tree arglist, ...)
5955 enum tree_code code;
5956 int res = 0;
5957 va_list ap;
5959 va_start (ap, arglist);
5963 code = va_arg (ap, enum tree_code);
5964 switch (code)
5966 case 0:
5967 /* This signifies an ellipses, any further arguments are all ok. */
5968 res = 1;
5969 goto end;
5970 case VOID_TYPE:
5971 /* This signifies an endlink, if no arguments remain, return
5972 true, otherwise return false. */
5973 res = arglist == 0;
5974 goto end;
5975 default:
5976 /* If no parameters remain or the parameter's code does not
5977 match the specified code, return false. Otherwise continue
5978 checking any remaining arguments. */
5979 if (arglist == 0
5980 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
5981 goto end;
5982 break;
5984 arglist = TREE_CHAIN (arglist);
5986 while (1);
5988 /* We need gotos here since we can only have one VA_CLOSE in a
5989 function. */
5990 end: ;
5991 va_end (ap);
5993 return res;
5996 /* Default version of target-specific builtin setup that does nothing. */
5998 void
5999 default_init_builtins (void)
6003 /* Default target-specific builtin expander that does nothing. */
6006 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6007 rtx target ATTRIBUTE_UNUSED,
6008 rtx subtarget ATTRIBUTE_UNUSED,
6009 enum machine_mode mode ATTRIBUTE_UNUSED,
6010 int ignore ATTRIBUTE_UNUSED)
6012 return NULL_RTX;
6015 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
6017 void
6018 purge_builtin_constant_p (void)
6020 rtx insn, set, arg, new, note;
6022 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6023 if (INSN_P (insn)
6024 && (set = single_set (insn)) != NULL_RTX
6025 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6026 || (GET_CODE (arg) == SUBREG
6027 && (GET_CODE (arg = SUBREG_REG (arg))
6028 == CONSTANT_P_RTX))))
6030 arg = XEXP (arg, 0);
6031 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6032 validate_change (insn, &SET_SRC (set), new, 0);
6034 /* Remove the REG_EQUAL note from the insn. */
6035 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6036 remove_note (insn, note);
6040 /* Returns true is EXP represents data that would potentially reside
6041 in a readonly section. */
6043 static bool
6044 readonly_data_expr (tree exp)
6046 STRIP_NOPS (exp);
6048 if (TREE_CODE (exp) == ADDR_EXPR)
6049 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
6050 else
6051 return false;