* builtins.c (mathfn_built_in): Check TYPE_MAIN_VARIANT, not
[official-gcc.git] / gcc / builtins.c
blob8720666c7c05b30c5ce22f371b813f7b3c4bd6e7
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
60 const char *const built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases. */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static tree c_strlen (tree, int);
76 static const char *c_getstr (tree);
77 static rtx c_readstr (const char *, enum machine_mode);
78 static int target_char_cast (tree, char *);
79 static rtx get_memory_rtx (tree);
80 static tree build_string_literal (int, const char *);
81 static int apply_args_size (void);
82 static int apply_result_size (void);
83 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
84 static rtx result_vector (int, rtx);
85 #endif
86 static rtx expand_builtin_setjmp (tree, rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_constant_p (tree, enum machine_mode);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (tree);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_inf (tree, int);
141 static tree fold_builtin_nan (tree, tree, int);
142 static int validate_arglist (tree, ...);
143 static bool integer_valued_real_p (tree);
144 static tree fold_trunc_transparent_mathfn (tree);
145 static bool readonly_data_expr (tree);
146 static rtx expand_builtin_fabs (tree, rtx, rtx);
147 static rtx expand_builtin_cabs (tree, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree, tree);
150 static tree fold_builtin_trunc (tree);
151 static tree fold_builtin_floor (tree);
152 static tree fold_builtin_ceil (tree);
153 static tree fold_builtin_round (tree);
154 static tree fold_builtin_bitop (tree);
155 static tree fold_builtin_memcpy (tree);
156 static tree fold_builtin_mempcpy (tree);
157 static tree fold_builtin_memmove (tree);
158 static tree fold_builtin_strcpy (tree);
159 static tree fold_builtin_strncpy (tree);
160 static tree fold_builtin_memcmp (tree);
161 static tree fold_builtin_strcmp (tree);
162 static tree fold_builtin_strncmp (tree);
163 static tree fold_builtin_signbit (tree);
165 /* Return the alignment in bits of EXP, a pointer valued expression.
166 But don't return more than MAX_ALIGN no matter what.
167 The alignment returned is, by default, the alignment of the thing that
168 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
170 Otherwise, look at the expression to see if we can do better, i.e., if the
171 expression is actually pointing at an object whose alignment is tighter. */
173 static int
174 get_pointer_alignment (tree exp, unsigned int max_align)
176 unsigned int align, inner;
178 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
179 return 0;
181 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
182 align = MIN (align, max_align);
184 while (1)
186 switch (TREE_CODE (exp))
188 case NOP_EXPR:
189 case CONVERT_EXPR:
190 case NON_LVALUE_EXPR:
191 exp = TREE_OPERAND (exp, 0);
192 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
193 return align;
195 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
196 align = MIN (inner, max_align);
197 break;
199 case PLUS_EXPR:
200 /* If sum of pointer + int, restrict our maximum alignment to that
201 imposed by the integer. If not, we can't do any better than
202 ALIGN. */
203 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
204 return align;
206 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
207 & (max_align / BITS_PER_UNIT - 1))
208 != 0)
209 max_align >>= 1;
211 exp = TREE_OPERAND (exp, 0);
212 break;
214 case ADDR_EXPR:
215 /* See what we are pointing at and look at its alignment. */
216 exp = TREE_OPERAND (exp, 0);
217 if (TREE_CODE (exp) == FUNCTION_DECL)
218 align = FUNCTION_BOUNDARY;
219 else if (DECL_P (exp))
220 align = DECL_ALIGN (exp);
221 #ifdef CONSTANT_ALIGNMENT
222 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
223 align = CONSTANT_ALIGNMENT (exp, align);
224 #endif
225 return MIN (align, max_align);
227 default:
228 return align;
233 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
234 way, because it could contain a zero byte in the middle.
235 TREE_STRING_LENGTH is the size of the character array, not the string.
237 ONLY_VALUE should be nonzero if the result is not going to be emitted
238 into the instruction stream and zero if it is going to be expanded.
239 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
240 is returned, otherwise NULL, since
241 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
242 evaluate the side-effects.
244 The value returned is of type `ssizetype'.
246 Unfortunately, string_constant can't access the values of const char
247 arrays with initializers, so neither can we do so here. */
249 static tree
250 c_strlen (tree src, int only_value)
252 tree offset_node;
253 HOST_WIDE_INT offset;
254 int max;
255 const char *ptr;
257 STRIP_NOPS (src);
258 if (TREE_CODE (src) == COND_EXPR
259 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
261 tree len1, len2;
263 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
264 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
265 if (tree_int_cst_equal (len1, len2))
266 return len1;
269 if (TREE_CODE (src) == COMPOUND_EXPR
270 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
271 return c_strlen (TREE_OPERAND (src, 1), only_value);
273 src = string_constant (src, &offset_node);
274 if (src == 0)
275 return 0;
277 max = TREE_STRING_LENGTH (src) - 1;
278 ptr = TREE_STRING_POINTER (src);
280 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
282 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
283 compute the offset to the following null if we don't know where to
284 start searching for it. */
285 int i;
287 for (i = 0; i < max; i++)
288 if (ptr[i] == 0)
289 return 0;
291 /* We don't know the starting offset, but we do know that the string
292 has no internal zero bytes. We can assume that the offset falls
293 within the bounds of the string; otherwise, the programmer deserves
294 what he gets. Subtract the offset from the length of the string,
295 and return that. This would perhaps not be valid if we were dealing
296 with named arrays in addition to literal string constants. */
298 return size_diffop (size_int (max), offset_node);
301 /* We have a known offset into the string. Start searching there for
302 a null character if we can represent it as a single HOST_WIDE_INT. */
303 if (offset_node == 0)
304 offset = 0;
305 else if (! host_integerp (offset_node, 0))
306 offset = -1;
307 else
308 offset = tree_low_cst (offset_node, 0);
310 /* If the offset is known to be out of bounds, warn, and call strlen at
311 runtime. */
312 if (offset < 0 || offset > max)
314 warning ("offset outside bounds of constant string");
315 return 0;
318 /* Use strlen to search for the first zero byte. Since any strings
319 constructed with build_string will have nulls appended, we win even
320 if we get handed something like (char[4])"abcd".
322 Since OFFSET is our starting index into the string, no further
323 calculation is needed. */
324 return ssize_int (strlen (ptr + offset));
327 /* Return a char pointer for a C string if it is a string constant
328 or sum of string constant and integer constant. */
330 static const char *
331 c_getstr (tree src)
333 tree offset_node;
335 src = string_constant (src, &offset_node);
336 if (src == 0)
337 return 0;
339 if (offset_node == 0)
340 return TREE_STRING_POINTER (src);
341 else if (!host_integerp (offset_node, 1)
342 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
343 return 0;
345 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
348 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
349 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
351 static rtx
352 c_readstr (const char *str, enum machine_mode mode)
354 HOST_WIDE_INT c[2];
355 HOST_WIDE_INT ch;
356 unsigned int i, j;
358 if (GET_MODE_CLASS (mode) != MODE_INT)
359 abort ();
360 c[0] = 0;
361 c[1] = 0;
362 ch = 1;
363 for (i = 0; i < GET_MODE_SIZE (mode); i++)
365 j = i;
366 if (WORDS_BIG_ENDIAN)
367 j = GET_MODE_SIZE (mode) - i - 1;
368 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
369 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
370 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
371 j *= BITS_PER_UNIT;
372 if (j > 2 * HOST_BITS_PER_WIDE_INT)
373 abort ();
374 if (ch)
375 ch = (unsigned char) str[i];
376 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
378 return immed_double_const (c[0], c[1], mode);
381 /* Cast a target constant CST to target CHAR and if that value fits into
382 host char type, return zero and put that value into variable pointed by
383 P. */
385 static int
386 target_char_cast (tree cst, char *p)
388 unsigned HOST_WIDE_INT val, hostval;
390 if (!host_integerp (cst, 1)
391 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
392 return 1;
394 val = tree_low_cst (cst, 1);
395 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
396 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
398 hostval = val;
399 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
400 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
402 if (val != hostval)
403 return 1;
405 *p = hostval;
406 return 0;
409 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
410 times to get the address of either a higher stack frame, or a return
411 address located within it (depending on FNDECL_CODE). */
414 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
415 rtx tem)
417 int i;
419 /* Some machines need special handling before we can access
420 arbitrary frames. For example, on the sparc, we must first flush
421 all register windows to the stack. */
422 #ifdef SETUP_FRAME_ADDRESSES
423 if (count > 0)
424 SETUP_FRAME_ADDRESSES ();
425 #endif
427 /* On the sparc, the return address is not in the frame, it is in a
428 register. There is no way to access it off of the current frame
429 pointer, but it can be accessed off the previous frame pointer by
430 reading the value from the register window save area. */
431 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
432 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
433 count--;
434 #endif
436 /* Scan back COUNT frames to the specified frame. */
437 for (i = 0; i < count; i++)
439 /* Assume the dynamic chain pointer is in the word that the
440 frame address points to, unless otherwise specified. */
441 #ifdef DYNAMIC_CHAIN_ADDRESS
442 tem = DYNAMIC_CHAIN_ADDRESS (tem);
443 #endif
444 tem = memory_address (Pmode, tem);
445 tem = gen_rtx_MEM (Pmode, tem);
446 set_mem_alias_set (tem, get_frame_alias_set ());
447 tem = copy_to_reg (tem);
450 /* For __builtin_frame_address, return what we've got. */
451 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
452 return tem;
454 /* For __builtin_return_address, Get the return address from that
455 frame. */
456 #ifdef RETURN_ADDR_RTX
457 tem = RETURN_ADDR_RTX (count, tem);
458 #else
459 tem = memory_address (Pmode,
460 plus_constant (tem, GET_MODE_SIZE (Pmode)));
461 tem = gen_rtx_MEM (Pmode, tem);
462 set_mem_alias_set (tem, get_frame_alias_set ());
463 #endif
464 return tem;
467 /* Alias set used for setjmp buffer. */
468 static HOST_WIDE_INT setjmp_alias_set = -1;
470 /* Construct the leading half of a __builtin_setjmp call. Control will
471 return to RECEIVER_LABEL. This is used directly by sjlj exception
472 handling code. */
474 void
475 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
477 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
478 rtx stack_save;
479 rtx mem;
481 if (setjmp_alias_set == -1)
482 setjmp_alias_set = new_alias_set ();
484 buf_addr = convert_memory_address (Pmode, buf_addr);
486 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
488 emit_queue ();
490 /* We store the frame pointer and the address of receiver_label in
491 the buffer and use the rest of it for the stack save area, which
492 is machine-dependent. */
494 mem = gen_rtx_MEM (Pmode, buf_addr);
495 set_mem_alias_set (mem, setjmp_alias_set);
496 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
498 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
499 set_mem_alias_set (mem, setjmp_alias_set);
501 emit_move_insn (validize_mem (mem),
502 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
504 stack_save = gen_rtx_MEM (sa_mode,
505 plus_constant (buf_addr,
506 2 * GET_MODE_SIZE (Pmode)));
507 set_mem_alias_set (stack_save, setjmp_alias_set);
508 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
510 /* If there is further processing to do, do it. */
511 #ifdef HAVE_builtin_setjmp_setup
512 if (HAVE_builtin_setjmp_setup)
513 emit_insn (gen_builtin_setjmp_setup (buf_addr));
514 #endif
516 /* Tell optimize_save_area_alloca that extra work is going to
517 need to go on during alloca. */
518 current_function_calls_setjmp = 1;
520 /* Set this so all the registers get saved in our frame; we need to be
521 able to copy the saved values for any registers from frames we unwind. */
522 current_function_has_nonlocal_label = 1;
525 /* Construct the trailing part of a __builtin_setjmp call.
526 This is used directly by sjlj exception handling code. */
528 void
529 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
531 /* Clobber the FP when we get here, so we have to make sure it's
532 marked as used by this function. */
533 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
535 /* Mark the static chain as clobbered here so life information
536 doesn't get messed up for it. */
537 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
539 /* Now put in the code to restore the frame pointer, and argument
540 pointer, if needed. The code below is from expand_end_bindings
541 in stmt.c; see detailed documentation there. */
542 #ifdef HAVE_nonlocal_goto
543 if (! HAVE_nonlocal_goto)
544 #endif
545 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
547 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
548 if (fixed_regs[ARG_POINTER_REGNUM])
550 #ifdef ELIMINABLE_REGS
551 size_t i;
552 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
554 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
555 if (elim_regs[i].from == ARG_POINTER_REGNUM
556 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
557 break;
559 if (i == ARRAY_SIZE (elim_regs))
560 #endif
562 /* Now restore our arg pointer from the address at which it
563 was saved in our stack frame. */
564 emit_move_insn (virtual_incoming_args_rtx,
565 copy_to_reg (get_arg_pointer_save_area (cfun)));
568 #endif
570 #ifdef HAVE_builtin_setjmp_receiver
571 if (HAVE_builtin_setjmp_receiver)
572 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
573 else
574 #endif
575 #ifdef HAVE_nonlocal_goto_receiver
576 if (HAVE_nonlocal_goto_receiver)
577 emit_insn (gen_nonlocal_goto_receiver ());
578 else
579 #endif
580 { /* Nothing */ }
582 /* @@@ This is a kludge. Not all machine descriptions define a blockage
583 insn, but we must not allow the code we just generated to be reordered
584 by scheduling. Specifically, the update of the frame pointer must
585 happen immediately, not later. So emit an ASM_INPUT to act as blockage
586 insn. */
587 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
590 /* __builtin_setjmp is passed a pointer to an array of five words (not
591 all will be used on all machines). It operates similarly to the C
592 library function of the same name, but is more efficient. Much of
593 the code below (and for longjmp) is copied from the handling of
594 non-local gotos.
596 NOTE: This is intended for use by GNAT and the exception handling
597 scheme in the compiler and will only work in the method used by
598 them. */
600 static rtx
601 expand_builtin_setjmp (tree arglist, rtx target)
603 rtx buf_addr, next_lab, cont_lab;
605 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
606 return NULL_RTX;
608 if (target == 0 || GET_CODE (target) != REG
609 || REGNO (target) < FIRST_PSEUDO_REGISTER)
610 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
612 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
614 next_lab = gen_label_rtx ();
615 cont_lab = gen_label_rtx ();
617 expand_builtin_setjmp_setup (buf_addr, next_lab);
619 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
620 ensure that pending stack adjustments are flushed. */
621 emit_move_insn (target, const0_rtx);
622 emit_jump (cont_lab);
624 emit_label (next_lab);
626 expand_builtin_setjmp_receiver (next_lab);
628 /* Set TARGET to one. */
629 emit_move_insn (target, const1_rtx);
630 emit_label (cont_lab);
632 /* Tell flow about the strange goings on. Putting `next_lab' on
633 `nonlocal_goto_handler_labels' to indicates that function
634 calls may traverse the arc back to this label. */
636 current_function_has_nonlocal_label = 1;
637 nonlocal_goto_handler_labels
638 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
640 return target;
643 /* __builtin_longjmp is passed a pointer to an array of five words (not
644 all will be used on all machines). It operates similarly to the C
645 library function of the same name, but is more efficient. Much of
646 the code below is copied from the handling of non-local gotos.
648 NOTE: This is intended for use by GNAT and the exception handling
649 scheme in the compiler and will only work in the method used by
650 them. */
652 void
653 expand_builtin_longjmp (rtx buf_addr, rtx value)
655 rtx fp, lab, stack, insn, last;
656 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
658 if (setjmp_alias_set == -1)
659 setjmp_alias_set = new_alias_set ();
661 buf_addr = convert_memory_address (Pmode, buf_addr);
663 buf_addr = force_reg (Pmode, buf_addr);
665 /* We used to store value in static_chain_rtx, but that fails if pointers
666 are smaller than integers. We instead require that the user must pass
667 a second argument of 1, because that is what builtin_setjmp will
668 return. This also makes EH slightly more efficient, since we are no
669 longer copying around a value that we don't care about. */
670 if (value != const1_rtx)
671 abort ();
673 current_function_calls_longjmp = 1;
675 last = get_last_insn ();
676 #ifdef HAVE_builtin_longjmp
677 if (HAVE_builtin_longjmp)
678 emit_insn (gen_builtin_longjmp (buf_addr));
679 else
680 #endif
682 fp = gen_rtx_MEM (Pmode, buf_addr);
683 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
684 GET_MODE_SIZE (Pmode)));
686 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
687 2 * GET_MODE_SIZE (Pmode)));
688 set_mem_alias_set (fp, setjmp_alias_set);
689 set_mem_alias_set (lab, setjmp_alias_set);
690 set_mem_alias_set (stack, setjmp_alias_set);
692 /* Pick up FP, label, and SP from the block and jump. This code is
693 from expand_goto in stmt.c; see there for detailed comments. */
694 #if HAVE_nonlocal_goto
695 if (HAVE_nonlocal_goto)
696 /* We have to pass a value to the nonlocal_goto pattern that will
697 get copied into the static_chain pointer, but it does not matter
698 what that value is, because builtin_setjmp does not use it. */
699 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
700 else
701 #endif
703 lab = copy_to_reg (lab);
705 emit_insn (gen_rtx_CLOBBER (VOIDmode,
706 gen_rtx_MEM (BLKmode,
707 gen_rtx_SCRATCH (VOIDmode))));
708 emit_insn (gen_rtx_CLOBBER (VOIDmode,
709 gen_rtx_MEM (BLKmode,
710 hard_frame_pointer_rtx)));
712 emit_move_insn (hard_frame_pointer_rtx, fp);
713 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
715 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
716 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
717 emit_indirect_jump (lab);
721 /* Search backwards and mark the jump insn as a non-local goto.
722 Note that this precludes the use of __builtin_longjmp to a
723 __builtin_setjmp target in the same function. However, we've
724 already cautioned the user that these functions are for
725 internal exception handling use only. */
726 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
728 if (insn == last)
729 abort ();
730 if (GET_CODE (insn) == JUMP_INSN)
732 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
733 REG_NOTES (insn));
734 break;
736 else if (GET_CODE (insn) == CALL_INSN)
737 break;
741 /* Expand a call to __builtin_prefetch. For a target that does not support
742 data prefetch, evaluate the memory address argument in case it has side
743 effects. */
745 static void
746 expand_builtin_prefetch (tree arglist)
748 tree arg0, arg1, arg2;
749 rtx op0, op1, op2;
751 if (!validate_arglist (arglist, POINTER_TYPE, 0))
752 return;
754 arg0 = TREE_VALUE (arglist);
755 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
756 zero (read) and argument 2 (locality) defaults to 3 (high degree of
757 locality). */
758 if (TREE_CHAIN (arglist))
760 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
761 if (TREE_CHAIN (TREE_CHAIN (arglist)))
762 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
763 else
764 arg2 = build_int_2 (3, 0);
766 else
768 arg1 = integer_zero_node;
769 arg2 = build_int_2 (3, 0);
772 /* Argument 0 is an address. */
773 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
775 /* Argument 1 (read/write flag) must be a compile-time constant int. */
776 if (TREE_CODE (arg1) != INTEGER_CST)
778 error ("second arg to `__builtin_prefetch' must be a constant");
779 arg1 = integer_zero_node;
781 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
782 /* Argument 1 must be either zero or one. */
783 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
785 warning ("invalid second arg to __builtin_prefetch; using zero");
786 op1 = const0_rtx;
789 /* Argument 2 (locality) must be a compile-time constant int. */
790 if (TREE_CODE (arg2) != INTEGER_CST)
792 error ("third arg to `__builtin_prefetch' must be a constant");
793 arg2 = integer_zero_node;
795 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
796 /* Argument 2 must be 0, 1, 2, or 3. */
797 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
799 warning ("invalid third arg to __builtin_prefetch; using zero");
800 op2 = const0_rtx;
803 #ifdef HAVE_prefetch
804 if (HAVE_prefetch)
806 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
807 (op0,
808 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
809 || (GET_MODE (op0) != Pmode))
811 op0 = convert_memory_address (Pmode, op0);
812 op0 = force_reg (Pmode, op0);
814 emit_insn (gen_prefetch (op0, op1, op2));
816 else
817 #endif
818 op0 = protect_from_queue (op0, 0);
819 /* Don't do anything with direct references to volatile memory, but
820 generate code to handle other side effects. */
821 if (GET_CODE (op0) != MEM && side_effects_p (op0))
822 emit_insn (op0);
825 /* Get a MEM rtx for expression EXP which is the address of an operand
826 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
828 static rtx
829 get_memory_rtx (tree exp)
831 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
832 rtx mem;
834 addr = convert_memory_address (Pmode, addr);
836 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
838 /* Get an expression we can use to find the attributes to assign to MEM.
839 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
840 we can. First remove any nops. */
841 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
842 || TREE_CODE (exp) == NON_LVALUE_EXPR)
843 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
844 exp = TREE_OPERAND (exp, 0);
846 if (TREE_CODE (exp) == ADDR_EXPR)
848 exp = TREE_OPERAND (exp, 0);
849 set_mem_attributes (mem, exp, 0);
851 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
853 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
854 /* memcpy, memset and other builtin stringops can alias with anything. */
855 set_mem_alias_set (mem, 0);
858 return mem;
861 /* Built-in functions to perform an untyped call and return. */
863 /* For each register that may be used for calling a function, this
864 gives a mode used to copy the register's value. VOIDmode indicates
865 the register is not used for calling a function. If the machine
866 has register windows, this gives only the outbound registers.
867 INCOMING_REGNO gives the corresponding inbound register. */
868 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
870 /* For each register that may be used for returning values, this gives
871 a mode used to copy the register's value. VOIDmode indicates the
872 register is not used for returning values. If the machine has
873 register windows, this gives only the outbound registers.
874 INCOMING_REGNO gives the corresponding inbound register. */
875 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
877 /* For each register that may be used for calling a function, this
878 gives the offset of that register into the block returned by
879 __builtin_apply_args. 0 indicates that the register is not
880 used for calling a function. */
881 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
883 /* Return the size required for the block returned by __builtin_apply_args,
884 and initialize apply_args_mode. */
886 static int
887 apply_args_size (void)
889 static int size = -1;
890 int align;
891 unsigned int regno;
892 enum machine_mode mode;
894 /* The values computed by this function never change. */
895 if (size < 0)
897 /* The first value is the incoming arg-pointer. */
898 size = GET_MODE_SIZE (Pmode);
900 /* The second value is the structure value address unless this is
901 passed as an "invisible" first argument. */
902 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
903 size += GET_MODE_SIZE (Pmode);
905 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
906 if (FUNCTION_ARG_REGNO_P (regno))
908 mode = reg_raw_mode[regno];
910 if (mode == VOIDmode)
911 abort ();
913 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
914 if (size % align != 0)
915 size = CEIL (size, align) * align;
916 apply_args_reg_offset[regno] = size;
917 size += GET_MODE_SIZE (mode);
918 apply_args_mode[regno] = mode;
920 else
922 apply_args_mode[regno] = VOIDmode;
923 apply_args_reg_offset[regno] = 0;
926 return size;
929 /* Return the size required for the block returned by __builtin_apply,
930 and initialize apply_result_mode. */
932 static int
933 apply_result_size (void)
935 static int size = -1;
936 int align, regno;
937 enum machine_mode mode;
939 /* The values computed by this function never change. */
940 if (size < 0)
942 size = 0;
944 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
945 if (FUNCTION_VALUE_REGNO_P (regno))
947 mode = reg_raw_mode[regno];
949 if (mode == VOIDmode)
950 abort ();
952 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
953 if (size % align != 0)
954 size = CEIL (size, align) * align;
955 size += GET_MODE_SIZE (mode);
956 apply_result_mode[regno] = mode;
958 else
959 apply_result_mode[regno] = VOIDmode;
961 /* Allow targets that use untyped_call and untyped_return to override
962 the size so that machine-specific information can be stored here. */
963 #ifdef APPLY_RESULT_SIZE
964 size = APPLY_RESULT_SIZE;
965 #endif
967 return size;
970 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
971 /* Create a vector describing the result block RESULT. If SAVEP is true,
972 the result block is used to save the values; otherwise it is used to
973 restore the values. */
975 static rtx
976 result_vector (int savep, rtx result)
978 int regno, size, align, nelts;
979 enum machine_mode mode;
980 rtx reg, mem;
981 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
983 size = nelts = 0;
984 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
985 if ((mode = apply_result_mode[regno]) != VOIDmode)
987 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
988 if (size % align != 0)
989 size = CEIL (size, align) * align;
990 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
991 mem = adjust_address (result, mode, size);
992 savevec[nelts++] = (savep
993 ? gen_rtx_SET (VOIDmode, mem, reg)
994 : gen_rtx_SET (VOIDmode, reg, mem));
995 size += GET_MODE_SIZE (mode);
997 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
999 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1001 /* Save the state required to perform an untyped call with the same
1002 arguments as were passed to the current function. */
1004 static rtx
1005 expand_builtin_apply_args_1 (void)
1007 rtx registers, tem;
1008 int size, align, regno;
1009 enum machine_mode mode;
1010 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1012 /* Create a block where the arg-pointer, structure value address,
1013 and argument registers can be saved. */
1014 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1016 /* Walk past the arg-pointer and structure value address. */
1017 size = GET_MODE_SIZE (Pmode);
1018 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1019 size += GET_MODE_SIZE (Pmode);
1021 /* Save each register used in calling a function to the block. */
1022 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1023 if ((mode = apply_args_mode[regno]) != VOIDmode)
1025 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1026 if (size % align != 0)
1027 size = CEIL (size, align) * align;
1029 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1031 emit_move_insn (adjust_address (registers, mode, size), tem);
1032 size += GET_MODE_SIZE (mode);
1035 /* Save the arg pointer to the block. */
1036 tem = copy_to_reg (virtual_incoming_args_rtx);
1037 #ifdef STACK_GROWS_DOWNWARD
1038 /* We need the pointer as the caller actually passed them to us, not
1039 as we might have pretended they were passed. Make sure it's a valid
1040 operand, as emit_move_insn isn't expected to handle a PLUS. */
1042 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1043 NULL_RTX);
1044 #endif
1045 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1047 size = GET_MODE_SIZE (Pmode);
1049 /* Save the structure value address unless this is passed as an
1050 "invisible" first argument. */
1051 if (struct_incoming_value)
1053 emit_move_insn (adjust_address (registers, Pmode, size),
1054 copy_to_reg (struct_incoming_value));
1055 size += GET_MODE_SIZE (Pmode);
1058 /* Return the address of the block. */
1059 return copy_addr_to_reg (XEXP (registers, 0));
1062 /* __builtin_apply_args returns block of memory allocated on
1063 the stack into which is stored the arg pointer, structure
1064 value address, static chain, and all the registers that might
1065 possibly be used in performing a function call. The code is
1066 moved to the start of the function so the incoming values are
1067 saved. */
1069 static rtx
1070 expand_builtin_apply_args (void)
1072 /* Don't do __builtin_apply_args more than once in a function.
1073 Save the result of the first call and reuse it. */
1074 if (apply_args_value != 0)
1075 return apply_args_value;
1077 /* When this function is called, it means that registers must be
1078 saved on entry to this function. So we migrate the
1079 call to the first insn of this function. */
1080 rtx temp;
1081 rtx seq;
1083 start_sequence ();
1084 temp = expand_builtin_apply_args_1 ();
1085 seq = get_insns ();
1086 end_sequence ();
1088 apply_args_value = temp;
1090 /* Put the insns after the NOTE that starts the function.
1091 If this is inside a start_sequence, make the outer-level insn
1092 chain current, so the code is placed at the start of the
1093 function. */
1094 push_topmost_sequence ();
1095 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1096 pop_topmost_sequence ();
1097 return temp;
1101 /* Perform an untyped call and save the state required to perform an
1102 untyped return of whatever value was returned by the given function. */
1104 static rtx
1105 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1107 int size, align, regno;
1108 enum machine_mode mode;
1109 rtx incoming_args, result, reg, dest, src, call_insn;
1110 rtx old_stack_level = 0;
1111 rtx call_fusage = 0;
1112 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1114 arguments = convert_memory_address (Pmode, arguments);
1116 /* Create a block where the return registers can be saved. */
1117 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1119 /* Fetch the arg pointer from the ARGUMENTS block. */
1120 incoming_args = gen_reg_rtx (Pmode);
1121 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1122 #ifndef STACK_GROWS_DOWNWARD
1123 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1124 incoming_args, 0, OPTAB_LIB_WIDEN);
1125 #endif
1127 /* Perform postincrements before actually calling the function. */
1128 emit_queue ();
1130 /* Push a new argument block and copy the arguments. Do not allow
1131 the (potential) memcpy call below to interfere with our stack
1132 manipulations. */
1133 do_pending_stack_adjust ();
1134 NO_DEFER_POP;
1136 /* Save the stack with nonlocal if available. */
1137 #ifdef HAVE_save_stack_nonlocal
1138 if (HAVE_save_stack_nonlocal)
1139 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1140 else
1141 #endif
1142 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1144 /* Allocate a block of memory onto the stack and copy the memory
1145 arguments to the outgoing arguments address. */
1146 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1147 dest = virtual_outgoing_args_rtx;
1148 #ifndef STACK_GROWS_DOWNWARD
1149 if (GET_CODE (argsize) == CONST_INT)
1150 dest = plus_constant (dest, -INTVAL (argsize));
1151 else
1152 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1153 #endif
1154 dest = gen_rtx_MEM (BLKmode, dest);
1155 set_mem_align (dest, PARM_BOUNDARY);
1156 src = gen_rtx_MEM (BLKmode, incoming_args);
1157 set_mem_align (src, PARM_BOUNDARY);
1158 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1160 /* Refer to the argument block. */
1161 apply_args_size ();
1162 arguments = gen_rtx_MEM (BLKmode, arguments);
1163 set_mem_align (arguments, PARM_BOUNDARY);
1165 /* Walk past the arg-pointer and structure value address. */
1166 size = GET_MODE_SIZE (Pmode);
1167 if (struct_value)
1168 size += GET_MODE_SIZE (Pmode);
1170 /* Restore each of the registers previously saved. Make USE insns
1171 for each of these registers for use in making the call. */
1172 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1173 if ((mode = apply_args_mode[regno]) != VOIDmode)
1175 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1176 if (size % align != 0)
1177 size = CEIL (size, align) * align;
1178 reg = gen_rtx_REG (mode, regno);
1179 emit_move_insn (reg, adjust_address (arguments, mode, size));
1180 use_reg (&call_fusage, reg);
1181 size += GET_MODE_SIZE (mode);
1184 /* Restore the structure value address unless this is passed as an
1185 "invisible" first argument. */
1186 size = GET_MODE_SIZE (Pmode);
1187 if (struct_value)
1189 rtx value = gen_reg_rtx (Pmode);
1190 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1191 emit_move_insn (struct_value, value);
1192 if (GET_CODE (struct_value) == REG)
1193 use_reg (&call_fusage, struct_value);
1194 size += GET_MODE_SIZE (Pmode);
1197 /* All arguments and registers used for the call are set up by now! */
1198 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1200 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1201 and we don't want to load it into a register as an optimization,
1202 because prepare_call_address already did it if it should be done. */
1203 if (GET_CODE (function) != SYMBOL_REF)
1204 function = memory_address (FUNCTION_MODE, function);
1206 /* Generate the actual call instruction and save the return value. */
1207 #ifdef HAVE_untyped_call
1208 if (HAVE_untyped_call)
1209 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1210 result, result_vector (1, result)));
1211 else
1212 #endif
1213 #ifdef HAVE_call_value
1214 if (HAVE_call_value)
1216 rtx valreg = 0;
1218 /* Locate the unique return register. It is not possible to
1219 express a call that sets more than one return register using
1220 call_value; use untyped_call for that. In fact, untyped_call
1221 only needs to save the return registers in the given block. */
1222 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1223 if ((mode = apply_result_mode[regno]) != VOIDmode)
1225 if (valreg)
1226 abort (); /* HAVE_untyped_call required. */
1227 valreg = gen_rtx_REG (mode, regno);
1230 emit_call_insn (GEN_CALL_VALUE (valreg,
1231 gen_rtx_MEM (FUNCTION_MODE, function),
1232 const0_rtx, NULL_RTX, const0_rtx));
1234 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1236 else
1237 #endif
1238 abort ();
1240 /* Find the CALL insn we just emitted, and attach the register usage
1241 information. */
1242 call_insn = last_call_insn ();
1243 add_function_usage_to (call_insn, call_fusage);
1245 /* Restore the stack. */
1246 #ifdef HAVE_save_stack_nonlocal
1247 if (HAVE_save_stack_nonlocal)
1248 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1249 else
1250 #endif
1251 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1253 OK_DEFER_POP;
1255 /* Return the address of the result block. */
1256 result = copy_addr_to_reg (XEXP (result, 0));
1257 return convert_memory_address (ptr_mode, result);
1260 /* Perform an untyped return. */
1262 static void
1263 expand_builtin_return (rtx result)
1265 int size, align, regno;
1266 enum machine_mode mode;
1267 rtx reg;
1268 rtx call_fusage = 0;
1270 result = convert_memory_address (Pmode, result);
1272 apply_result_size ();
1273 result = gen_rtx_MEM (BLKmode, result);
1275 #ifdef HAVE_untyped_return
1276 if (HAVE_untyped_return)
1278 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1279 emit_barrier ();
1280 return;
1282 #endif
1284 /* Restore the return value and note that each value is used. */
1285 size = 0;
1286 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1287 if ((mode = apply_result_mode[regno]) != VOIDmode)
1289 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1290 if (size % align != 0)
1291 size = CEIL (size, align) * align;
1292 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1293 emit_move_insn (reg, adjust_address (result, mode, size));
1295 push_to_sequence (call_fusage);
1296 emit_insn (gen_rtx_USE (VOIDmode, reg));
1297 call_fusage = get_insns ();
1298 end_sequence ();
1299 size += GET_MODE_SIZE (mode);
1302 /* Put the USE insns before the return. */
1303 emit_insn (call_fusage);
1305 /* Return whatever values was restored by jumping directly to the end
1306 of the function. */
1307 expand_naked_return ();
1310 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1312 static enum type_class
1313 type_to_class (tree type)
1315 switch (TREE_CODE (type))
1317 case VOID_TYPE: return void_type_class;
1318 case INTEGER_TYPE: return integer_type_class;
1319 case CHAR_TYPE: return char_type_class;
1320 case ENUMERAL_TYPE: return enumeral_type_class;
1321 case BOOLEAN_TYPE: return boolean_type_class;
1322 case POINTER_TYPE: return pointer_type_class;
1323 case REFERENCE_TYPE: return reference_type_class;
1324 case OFFSET_TYPE: return offset_type_class;
1325 case REAL_TYPE: return real_type_class;
1326 case COMPLEX_TYPE: return complex_type_class;
1327 case FUNCTION_TYPE: return function_type_class;
1328 case METHOD_TYPE: return method_type_class;
1329 case RECORD_TYPE: return record_type_class;
1330 case UNION_TYPE:
1331 case QUAL_UNION_TYPE: return union_type_class;
1332 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1333 ? string_type_class : array_type_class);
1334 case SET_TYPE: return set_type_class;
1335 case FILE_TYPE: return file_type_class;
1336 case LANG_TYPE: return lang_type_class;
1337 default: return no_type_class;
1341 /* Expand a call to __builtin_classify_type with arguments found in
1342 ARGLIST. */
1344 static rtx
1345 expand_builtin_classify_type (tree arglist)
1347 if (arglist != 0)
1348 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1349 return GEN_INT (no_type_class);
1352 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1354 static rtx
1355 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1357 rtx tmp;
1359 if (arglist == 0)
1360 return const0_rtx;
1361 arglist = TREE_VALUE (arglist);
1363 /* We have taken care of the easy cases during constant folding. This
1364 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1365 get a chance to see if it can deduce whether ARGLIST is constant.
1366 If CSE isn't going to run, of course, don't bother waiting. */
1368 if (cse_not_expected)
1369 return const0_rtx;
1371 current_function_calls_constant_p = 1;
1373 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1374 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1375 return tmp;
1378 /* This helper macro, meant to be used in mathfn_built_in below,
1379 determines which among a set of three builtin math functions is
1380 appropriate for a given type mode. The `F' and `L' cases are
1381 automatically generated from the `double' case. */
1382 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1383 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1384 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1385 fcodel = BUILT_IN_MATHFN##L ; break;
1387 /* Return mathematic function equivalent to FN but operating directly
1388 on TYPE, if available. If we can't do the conversion, return zero. */
1389 tree
1390 mathfn_built_in (tree type, enum built_in_function fn)
1392 enum built_in_function fcode, fcodef, fcodel;
1394 switch (fn)
1396 CASE_MATHFN (BUILT_IN_ACOS)
1397 CASE_MATHFN (BUILT_IN_ACOSH)
1398 CASE_MATHFN (BUILT_IN_ASIN)
1399 CASE_MATHFN (BUILT_IN_ASINH)
1400 CASE_MATHFN (BUILT_IN_ATAN)
1401 CASE_MATHFN (BUILT_IN_ATAN2)
1402 CASE_MATHFN (BUILT_IN_ATANH)
1403 CASE_MATHFN (BUILT_IN_CBRT)
1404 CASE_MATHFN (BUILT_IN_CEIL)
1405 CASE_MATHFN (BUILT_IN_COPYSIGN)
1406 CASE_MATHFN (BUILT_IN_COS)
1407 CASE_MATHFN (BUILT_IN_COSH)
1408 CASE_MATHFN (BUILT_IN_DREM)
1409 CASE_MATHFN (BUILT_IN_ERF)
1410 CASE_MATHFN (BUILT_IN_ERFC)
1411 CASE_MATHFN (BUILT_IN_EXP)
1412 CASE_MATHFN (BUILT_IN_EXP10)
1413 CASE_MATHFN (BUILT_IN_EXP2)
1414 CASE_MATHFN (BUILT_IN_EXPM1)
1415 CASE_MATHFN (BUILT_IN_FABS)
1416 CASE_MATHFN (BUILT_IN_FDIM)
1417 CASE_MATHFN (BUILT_IN_FLOOR)
1418 CASE_MATHFN (BUILT_IN_FMA)
1419 CASE_MATHFN (BUILT_IN_FMAX)
1420 CASE_MATHFN (BUILT_IN_FMIN)
1421 CASE_MATHFN (BUILT_IN_FMOD)
1422 CASE_MATHFN (BUILT_IN_FREXP)
1423 CASE_MATHFN (BUILT_IN_GAMMA)
1424 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1425 CASE_MATHFN (BUILT_IN_HYPOT)
1426 CASE_MATHFN (BUILT_IN_ILOGB)
1427 CASE_MATHFN (BUILT_IN_INF)
1428 CASE_MATHFN (BUILT_IN_J0)
1429 CASE_MATHFN (BUILT_IN_J1)
1430 CASE_MATHFN (BUILT_IN_JN)
1431 CASE_MATHFN (BUILT_IN_LDEXP)
1432 CASE_MATHFN (BUILT_IN_LGAMMA)
1433 CASE_MATHFN (BUILT_IN_LLRINT)
1434 CASE_MATHFN (BUILT_IN_LLROUND)
1435 CASE_MATHFN (BUILT_IN_LOG)
1436 CASE_MATHFN (BUILT_IN_LOG10)
1437 CASE_MATHFN (BUILT_IN_LOG1P)
1438 CASE_MATHFN (BUILT_IN_LOG2)
1439 CASE_MATHFN (BUILT_IN_LOGB)
1440 CASE_MATHFN (BUILT_IN_LRINT)
1441 CASE_MATHFN (BUILT_IN_LROUND)
1442 CASE_MATHFN (BUILT_IN_MODF)
1443 CASE_MATHFN (BUILT_IN_NAN)
1444 CASE_MATHFN (BUILT_IN_NANS)
1445 CASE_MATHFN (BUILT_IN_NEARBYINT)
1446 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1447 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1448 CASE_MATHFN (BUILT_IN_POW)
1449 CASE_MATHFN (BUILT_IN_POW10)
1450 CASE_MATHFN (BUILT_IN_REMAINDER)
1451 CASE_MATHFN (BUILT_IN_REMQUO)
1452 CASE_MATHFN (BUILT_IN_RINT)
1453 CASE_MATHFN (BUILT_IN_ROUND)
1454 CASE_MATHFN (BUILT_IN_SCALB)
1455 CASE_MATHFN (BUILT_IN_SCALBLN)
1456 CASE_MATHFN (BUILT_IN_SCALBN)
1457 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1458 CASE_MATHFN (BUILT_IN_SIN)
1459 CASE_MATHFN (BUILT_IN_SINCOS)
1460 CASE_MATHFN (BUILT_IN_SINH)
1461 CASE_MATHFN (BUILT_IN_SQRT)
1462 CASE_MATHFN (BUILT_IN_TAN)
1463 CASE_MATHFN (BUILT_IN_TANH)
1464 CASE_MATHFN (BUILT_IN_TGAMMA)
1465 CASE_MATHFN (BUILT_IN_TRUNC)
1466 CASE_MATHFN (BUILT_IN_Y0)
1467 CASE_MATHFN (BUILT_IN_Y1)
1468 CASE_MATHFN (BUILT_IN_YN)
1470 default:
1471 return 0;
1474 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1475 return implicit_built_in_decls[fcode];
1476 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1477 return implicit_built_in_decls[fcodef];
1478 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1479 return implicit_built_in_decls[fcodel];
1480 else
1481 return 0;
1484 /* If errno must be maintained, expand the RTL to check if the result,
1485 TARGET, of a built-in function call, EXP, is NaN, and if so set
1486 errno to EDOM. */
1488 static void
1489 expand_errno_check (tree exp, rtx target)
1491 rtx lab = gen_label_rtx ();
1493 /* Test the result; if it is NaN, set errno=EDOM because
1494 the argument was not in the domain. */
1495 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1496 0, lab);
1498 #ifdef TARGET_EDOM
1499 /* If this built-in doesn't throw an exception, set errno directly. */
1500 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1502 #ifdef GEN_ERRNO_RTX
1503 rtx errno_rtx = GEN_ERRNO_RTX;
1504 #else
1505 rtx errno_rtx
1506 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1507 #endif
1508 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1509 emit_label (lab);
1510 return;
1512 #endif
1514 /* We can't set errno=EDOM directly; let the library call do it.
1515 Pop the arguments right away in case the call gets deleted. */
1516 NO_DEFER_POP;
1517 expand_call (exp, target, 0);
1518 OK_DEFER_POP;
1519 emit_label (lab);
1523 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1524 Return 0 if a normal call should be emitted rather than expanding the
1525 function in-line. EXP is the expression that is a call to the builtin
1526 function; if convenient, the result should be placed in TARGET.
1527 SUBTARGET may be used as the target for computing one of EXP's operands. */
1529 static rtx
1530 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1532 optab builtin_optab;
1533 rtx op0, insns, before_call;
1534 tree fndecl = get_callee_fndecl (exp);
1535 tree arglist = TREE_OPERAND (exp, 1);
1536 enum machine_mode mode;
1537 bool errno_set = false;
1538 tree arg, narg;
1540 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1541 return 0;
1543 arg = TREE_VALUE (arglist);
1545 switch (DECL_FUNCTION_CODE (fndecl))
1547 case BUILT_IN_SQRT:
1548 case BUILT_IN_SQRTF:
1549 case BUILT_IN_SQRTL:
1550 errno_set = ! tree_expr_nonnegative_p (arg);
1551 builtin_optab = sqrt_optab;
1552 break;
1553 case BUILT_IN_EXP:
1554 case BUILT_IN_EXPF:
1555 case BUILT_IN_EXPL:
1556 errno_set = true; builtin_optab = exp_optab; break;
1557 case BUILT_IN_EXP10:
1558 case BUILT_IN_EXP10F:
1559 case BUILT_IN_EXP10L:
1560 case BUILT_IN_POW10:
1561 case BUILT_IN_POW10F:
1562 case BUILT_IN_POW10L:
1563 errno_set = true; builtin_optab = exp10_optab; break;
1564 case BUILT_IN_EXP2:
1565 case BUILT_IN_EXP2F:
1566 case BUILT_IN_EXP2L:
1567 errno_set = true; builtin_optab = exp2_optab; break;
1568 case BUILT_IN_LOG:
1569 case BUILT_IN_LOGF:
1570 case BUILT_IN_LOGL:
1571 errno_set = true; builtin_optab = log_optab; break;
1572 case BUILT_IN_LOG10:
1573 case BUILT_IN_LOG10F:
1574 case BUILT_IN_LOG10L:
1575 errno_set = true; builtin_optab = log10_optab; break;
1576 case BUILT_IN_LOG2:
1577 case BUILT_IN_LOG2F:
1578 case BUILT_IN_LOG2L:
1579 errno_set = true; builtin_optab = log2_optab; break;
1580 case BUILT_IN_TAN:
1581 case BUILT_IN_TANF:
1582 case BUILT_IN_TANL:
1583 builtin_optab = tan_optab; break;
1584 case BUILT_IN_ATAN:
1585 case BUILT_IN_ATANF:
1586 case BUILT_IN_ATANL:
1587 builtin_optab = atan_optab; break;
1588 case BUILT_IN_FLOOR:
1589 case BUILT_IN_FLOORF:
1590 case BUILT_IN_FLOORL:
1591 builtin_optab = floor_optab; break;
1592 case BUILT_IN_CEIL:
1593 case BUILT_IN_CEILF:
1594 case BUILT_IN_CEILL:
1595 builtin_optab = ceil_optab; break;
1596 case BUILT_IN_TRUNC:
1597 case BUILT_IN_TRUNCF:
1598 case BUILT_IN_TRUNCL:
1599 builtin_optab = btrunc_optab; break;
1600 case BUILT_IN_ROUND:
1601 case BUILT_IN_ROUNDF:
1602 case BUILT_IN_ROUNDL:
1603 builtin_optab = round_optab; break;
1604 case BUILT_IN_NEARBYINT:
1605 case BUILT_IN_NEARBYINTF:
1606 case BUILT_IN_NEARBYINTL:
1607 builtin_optab = nearbyint_optab; break;
1608 default:
1609 abort ();
1612 /* Make a suitable register to place result in. */
1613 mode = TYPE_MODE (TREE_TYPE (exp));
1615 if (! flag_errno_math || ! HONOR_NANS (mode))
1616 errno_set = false;
1618 /* Before working hard, check whether the instruction is available. */
1619 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1621 target = gen_reg_rtx (mode);
1623 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1624 need to expand the argument again. This way, we will not perform
1625 side-effects more the once. */
1626 narg = save_expr (arg);
1627 if (narg != arg)
1629 arglist = build_tree_list (NULL_TREE, arg);
1630 exp = build_function_call_expr (fndecl, arglist);
1633 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1635 emit_queue ();
1636 start_sequence ();
1638 /* Compute into TARGET.
1639 Set TARGET to wherever the result comes back. */
1640 target = expand_unop (mode, builtin_optab, op0, target, 0);
1642 if (target != 0)
1644 if (errno_set)
1645 expand_errno_check (exp, target);
1647 /* Output the entire sequence. */
1648 insns = get_insns ();
1649 end_sequence ();
1650 emit_insn (insns);
1651 return target;
1654 /* If we were unable to expand via the builtin, stop the sequence
1655 (without outputting the insns) and call to the library function
1656 with the stabilized argument list. */
1657 end_sequence ();
1660 before_call = get_last_insn ();
1662 target = expand_call (exp, target, target == const0_rtx);
1664 /* If this is a sqrt operation and we don't care about errno, try to
1665 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1666 This allows the semantics of the libcall to be visible to the RTL
1667 optimizers. */
1668 if (builtin_optab == sqrt_optab && !errno_set)
1670 /* Search backwards through the insns emitted by expand_call looking
1671 for the instruction with the REG_RETVAL note. */
1672 rtx last = get_last_insn ();
1673 while (last != before_call)
1675 if (find_reg_note (last, REG_RETVAL, NULL))
1677 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1678 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1679 two elements, i.e. symbol_ref(sqrt) and the operand. */
1680 if (note
1681 && GET_CODE (note) == EXPR_LIST
1682 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1683 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1684 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1686 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1687 /* Check operand is a register with expected mode. */
1688 if (operand
1689 && GET_CODE (operand) == REG
1690 && GET_MODE (operand) == mode)
1692 /* Replace the REG_EQUAL note with a SQRT rtx. */
1693 rtx equiv = gen_rtx_SQRT (mode, operand);
1694 set_unique_reg_note (last, REG_EQUAL, equiv);
1697 break;
1699 last = PREV_INSN (last);
1703 return target;
1706 /* Expand a call to the builtin binary math functions (pow and atan2).
1707 Return 0 if a normal call should be emitted rather than expanding the
1708 function in-line. EXP is the expression that is a call to the builtin
1709 function; if convenient, the result should be placed in TARGET.
1710 SUBTARGET may be used as the target for computing one of EXP's
1711 operands. */
1713 static rtx
1714 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1716 optab builtin_optab;
1717 rtx op0, op1, insns;
1718 tree fndecl = get_callee_fndecl (exp);
1719 tree arglist = TREE_OPERAND (exp, 1);
1720 tree arg0, arg1, temp, narg;
1721 enum machine_mode mode;
1722 bool errno_set = true;
1723 bool stable = true;
1725 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1726 return 0;
1728 arg0 = TREE_VALUE (arglist);
1729 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1731 switch (DECL_FUNCTION_CODE (fndecl))
1733 case BUILT_IN_POW:
1734 case BUILT_IN_POWF:
1735 case BUILT_IN_POWL:
1736 builtin_optab = pow_optab; break;
1737 case BUILT_IN_ATAN2:
1738 case BUILT_IN_ATAN2F:
1739 case BUILT_IN_ATAN2L:
1740 builtin_optab = atan2_optab; break;
1741 default:
1742 abort ();
1745 /* Make a suitable register to place result in. */
1746 mode = TYPE_MODE (TREE_TYPE (exp));
1748 /* Before working hard, check whether the instruction is available. */
1749 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1750 return 0;
1752 target = gen_reg_rtx (mode);
1754 if (! flag_errno_math || ! HONOR_NANS (mode))
1755 errno_set = false;
1757 /* Alway stabilize the argument list. */
1758 narg = save_expr (arg1);
1759 if (narg != arg1)
1761 temp = build_tree_list (NULL_TREE, narg);
1762 stable = false;
1764 else
1765 temp = TREE_CHAIN (arglist);
1767 narg = save_expr (arg0);
1768 if (narg != arg0)
1770 arglist = tree_cons (NULL_TREE, narg, temp);
1771 stable = false;
1773 else if (! stable)
1774 arglist = tree_cons (NULL_TREE, arg0, temp);
1776 if (! stable)
1777 exp = build_function_call_expr (fndecl, arglist);
1779 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1780 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1782 emit_queue ();
1783 start_sequence ();
1785 /* Compute into TARGET.
1786 Set TARGET to wherever the result comes back. */
1787 target = expand_binop (mode, builtin_optab, op0, op1,
1788 target, 0, OPTAB_DIRECT);
1790 /* If we were unable to expand via the builtin, stop the sequence
1791 (without outputting the insns) and call to the library function
1792 with the stabilized argument list. */
1793 if (target == 0)
1795 end_sequence ();
1796 return expand_call (exp, target, target == const0_rtx);
1799 if (errno_set)
1800 expand_errno_check (exp, target);
1802 /* Output the entire sequence. */
1803 insns = get_insns ();
1804 end_sequence ();
1805 emit_insn (insns);
1807 return target;
1810 /* Expand a call to the builtin sin and cos math functions.
1811 Return 0 if a normal call should be emitted rather than expanding the
1812 function in-line. EXP is the expression that is a call to the builtin
1813 function; if convenient, the result should be placed in TARGET.
1814 SUBTARGET may be used as the target for computing one of EXP's
1815 operands. */
1817 static rtx
1818 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1820 optab builtin_optab;
1821 rtx op0, insns, before_call;
1822 tree fndecl = get_callee_fndecl (exp);
1823 tree arglist = TREE_OPERAND (exp, 1);
1824 enum machine_mode mode;
1825 bool errno_set = false;
1826 tree arg, narg;
1828 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1829 return 0;
1831 arg = TREE_VALUE (arglist);
1833 switch (DECL_FUNCTION_CODE (fndecl))
1835 case BUILT_IN_SIN:
1836 case BUILT_IN_SINF:
1837 case BUILT_IN_SINL:
1838 case BUILT_IN_COS:
1839 case BUILT_IN_COSF:
1840 case BUILT_IN_COSL:
1841 builtin_optab = sincos_optab; break;
1842 default:
1843 abort ();
1846 /* Make a suitable register to place result in. */
1847 mode = TYPE_MODE (TREE_TYPE (exp));
1849 if (! flag_errno_math || ! HONOR_NANS (mode))
1850 errno_set = false;
1852 /* Check if sincos insn is available, otherwise fallback
1853 to sin or cos insn. */
1854 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
1855 switch (DECL_FUNCTION_CODE (fndecl))
1857 case BUILT_IN_SIN:
1858 case BUILT_IN_SINF:
1859 case BUILT_IN_SINL:
1860 builtin_optab = sin_optab; break;
1861 case BUILT_IN_COS:
1862 case BUILT_IN_COSF:
1863 case BUILT_IN_COSL:
1864 builtin_optab = cos_optab; break;
1865 default:
1866 abort();
1870 /* Before working hard, check whether the instruction is available. */
1871 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1873 target = gen_reg_rtx (mode);
1875 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1876 need to expand the argument again. This way, we will not perform
1877 side-effects more the once. */
1878 narg = save_expr (arg);
1879 if (narg != arg)
1881 arglist = build_tree_list (NULL_TREE, arg);
1882 exp = build_function_call_expr (fndecl, arglist);
1885 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1887 emit_queue ();
1888 start_sequence ();
1890 /* Compute into TARGET.
1891 Set TARGET to wherever the result comes back. */
1892 if (builtin_optab == sincos_optab)
1894 switch (DECL_FUNCTION_CODE (fndecl))
1896 case BUILT_IN_SIN:
1897 case BUILT_IN_SINF:
1898 case BUILT_IN_SINL:
1899 if (! expand_twoval_unop(builtin_optab, 0, target, op0, 0))
1900 abort();
1901 break;
1902 case BUILT_IN_COS:
1903 case BUILT_IN_COSF:
1904 case BUILT_IN_COSL:
1905 if (! expand_twoval_unop(builtin_optab, target, 0, op0, 0))
1906 abort();
1907 break;
1908 default:
1909 abort();
1912 else
1914 target = expand_unop (mode, builtin_optab, op0, target, 0);
1917 if (target != 0)
1919 if (errno_set)
1920 expand_errno_check (exp, target);
1922 /* Output the entire sequence. */
1923 insns = get_insns ();
1924 end_sequence ();
1925 emit_insn (insns);
1926 return target;
1929 /* If we were unable to expand via the builtin, stop the sequence
1930 (without outputting the insns) and call to the library function
1931 with the stabilized argument list. */
1932 end_sequence ();
1935 before_call = get_last_insn ();
1937 target = expand_call (exp, target, target == const0_rtx);
1939 return target;
1942 /* To evaluate powi(x,n), the floating point value x raised to the
1943 constant integer exponent n, we use a hybrid algorithm that
1944 combines the "window method" with look-up tables. For an
1945 introduction to exponentiation algorithms and "addition chains",
1946 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1947 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1948 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1949 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1951 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1952 multiplications to inline before calling the system library's pow
1953 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1954 so this default never requires calling pow, powf or powl. */
1956 #ifndef POWI_MAX_MULTS
1957 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1958 #endif
1960 /* The size of the "optimal power tree" lookup table. All
1961 exponents less than this value are simply looked up in the
1962 powi_table below. This threshold is also used to size the
1963 cache of pseudo registers that hold intermediate results. */
1964 #define POWI_TABLE_SIZE 256
1966 /* The size, in bits of the window, used in the "window method"
1967 exponentiation algorithm. This is equivalent to a radix of
1968 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1969 #define POWI_WINDOW_SIZE 3
1971 /* The following table is an efficient representation of an
1972 "optimal power tree". For each value, i, the corresponding
1973 value, j, in the table states than an optimal evaluation
1974 sequence for calculating pow(x,i) can be found by evaluating
1975 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1976 100 integers is given in Knuth's "Seminumerical algorithms". */
1978 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1980 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1981 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1982 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1983 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1984 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1985 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1986 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1987 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1988 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1989 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1990 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1991 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1992 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1993 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1994 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1995 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1996 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1997 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1998 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1999 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2000 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2001 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2002 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2003 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2004 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2005 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2006 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2007 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2008 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2009 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2010 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2011 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2015 /* Return the number of multiplications required to calculate
2016 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2017 subroutine of powi_cost. CACHE is an array indicating
2018 which exponents have already been calculated. */
2020 static int
2021 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2023 /* If we've already calculated this exponent, then this evaluation
2024 doesn't require any additional multiplications. */
2025 if (cache[n])
2026 return 0;
2028 cache[n] = true;
2029 return powi_lookup_cost (n - powi_table[n], cache)
2030 + powi_lookup_cost (powi_table[n], cache) + 1;
2033 /* Return the number of multiplications required to calculate
2034 powi(x,n) for an arbitrary x, given the exponent N. This
2035 function needs to be kept in sync with expand_powi below. */
2037 static int
2038 powi_cost (HOST_WIDE_INT n)
2040 bool cache[POWI_TABLE_SIZE];
2041 unsigned HOST_WIDE_INT digit;
2042 unsigned HOST_WIDE_INT val;
2043 int result;
2045 if (n == 0)
2046 return 0;
2048 /* Ignore the reciprocal when calculating the cost. */
2049 val = (n < 0) ? -n : n;
2051 /* Initialize the exponent cache. */
2052 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2053 cache[1] = true;
2055 result = 0;
2057 while (val >= POWI_TABLE_SIZE)
2059 if (val & 1)
2061 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2062 result += powi_lookup_cost (digit, cache)
2063 + POWI_WINDOW_SIZE + 1;
2064 val >>= POWI_WINDOW_SIZE;
2066 else
2068 val >>= 1;
2069 result++;
2073 return result + powi_lookup_cost (val, cache);
2076 /* Recursive subroutine of expand_powi. This function takes the array,
2077 CACHE, of already calculated exponents and an exponent N and returns
2078 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2080 static rtx
2081 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2083 unsigned HOST_WIDE_INT digit;
2084 rtx target, result;
2085 rtx op0, op1;
2087 if (n < POWI_TABLE_SIZE)
2089 if (cache[n])
2090 return cache[n];
2092 target = gen_reg_rtx (mode);
2093 cache[n] = target;
2095 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2096 op1 = expand_powi_1 (mode, powi_table[n], cache);
2098 else if (n & 1)
2100 target = gen_reg_rtx (mode);
2101 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2102 op0 = expand_powi_1 (mode, n - digit, cache);
2103 op1 = expand_powi_1 (mode, digit, cache);
2105 else
2107 target = gen_reg_rtx (mode);
2108 op0 = expand_powi_1 (mode, n >> 1, cache);
2109 op1 = op0;
2112 result = expand_mult (mode, op0, op1, target, 0);
2113 if (result != target)
2114 emit_move_insn (target, result);
2115 return target;
2118 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2119 floating point operand in mode MODE, and N is the exponent. This
2120 function needs to be kept in sync with powi_cost above. */
2122 static rtx
2123 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2125 unsigned HOST_WIDE_INT val;
2126 rtx cache[POWI_TABLE_SIZE];
2127 rtx result;
2129 if (n == 0)
2130 return CONST1_RTX (mode);
2132 val = (n < 0) ? -n : n;
2134 memset (cache, 0, sizeof (cache));
2135 cache[1] = x;
2137 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2139 /* If the original exponent was negative, reciprocate the result. */
2140 if (n < 0)
2141 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2142 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2144 return result;
2147 /* Expand a call to the pow built-in mathematical function. Return 0 if
2148 a normal call should be emitted rather than expanding the function
2149 in-line. EXP is the expression that is a call to the builtin
2150 function; if convenient, the result should be placed in TARGET. */
2152 static rtx
2153 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2155 tree arglist = TREE_OPERAND (exp, 1);
2156 tree arg0, arg1;
2158 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2159 return 0;
2161 arg0 = TREE_VALUE (arglist);
2162 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2164 if (TREE_CODE (arg1) == REAL_CST
2165 && ! TREE_CONSTANT_OVERFLOW (arg1))
2167 REAL_VALUE_TYPE cint;
2168 REAL_VALUE_TYPE c;
2169 HOST_WIDE_INT n;
2171 c = TREE_REAL_CST (arg1);
2172 n = real_to_integer (&c);
2173 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2174 if (real_identical (&c, &cint))
2176 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2177 Otherwise, check the number of multiplications required.
2178 Note that pow never sets errno for an integer exponent. */
2179 if ((n >= -1 && n <= 2)
2180 || (flag_unsafe_math_optimizations
2181 && ! optimize_size
2182 && powi_cost (n) <= POWI_MAX_MULTS))
2184 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2185 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2186 op = force_reg (mode, op);
2187 return expand_powi (op, mode, n);
2192 if (! flag_unsafe_math_optimizations)
2193 return NULL_RTX;
2194 return expand_builtin_mathfn_2 (exp, target, subtarget);
2197 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2198 if we failed the caller should emit a normal call, otherwise
2199 try to get the result in TARGET, if convenient. */
2201 static rtx
2202 expand_builtin_strlen (tree arglist, rtx target,
2203 enum machine_mode target_mode)
2205 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2206 return 0;
2207 else
2209 rtx pat;
2210 tree len, src = TREE_VALUE (arglist);
2211 rtx result, src_reg, char_rtx, before_strlen;
2212 enum machine_mode insn_mode = target_mode, char_mode;
2213 enum insn_code icode = CODE_FOR_nothing;
2214 int align;
2216 /* If the length can be computed at compile-time, return it. */
2217 len = c_strlen (src, 0);
2218 if (len)
2219 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2221 /* If the length can be computed at compile-time and is constant
2222 integer, but there are side-effects in src, evaluate
2223 src for side-effects, then return len.
2224 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2225 can be optimized into: i++; x = 3; */
2226 len = c_strlen (src, 1);
2227 if (len && TREE_CODE (len) == INTEGER_CST)
2229 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2230 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2233 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2235 /* If SRC is not a pointer type, don't do this operation inline. */
2236 if (align == 0)
2237 return 0;
2239 /* Bail out if we can't compute strlen in the right mode. */
2240 while (insn_mode != VOIDmode)
2242 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2243 if (icode != CODE_FOR_nothing)
2244 break;
2246 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2248 if (insn_mode == VOIDmode)
2249 return 0;
2251 /* Make a place to write the result of the instruction. */
2252 result = target;
2253 if (! (result != 0
2254 && GET_CODE (result) == REG
2255 && GET_MODE (result) == insn_mode
2256 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2257 result = gen_reg_rtx (insn_mode);
2259 /* Make a place to hold the source address. We will not expand
2260 the actual source until we are sure that the expansion will
2261 not fail -- there are trees that cannot be expanded twice. */
2262 src_reg = gen_reg_rtx (Pmode);
2264 /* Mark the beginning of the strlen sequence so we can emit the
2265 source operand later. */
2266 before_strlen = get_last_insn ();
2268 char_rtx = const0_rtx;
2269 char_mode = insn_data[(int) icode].operand[2].mode;
2270 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2271 char_mode))
2272 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2274 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2275 char_rtx, GEN_INT (align));
2276 if (! pat)
2277 return 0;
2278 emit_insn (pat);
2280 /* Now that we are assured of success, expand the source. */
2281 start_sequence ();
2282 pat = memory_address (BLKmode,
2283 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2284 if (pat != src_reg)
2285 emit_move_insn (src_reg, pat);
2286 pat = get_insns ();
2287 end_sequence ();
2289 if (before_strlen)
2290 emit_insn_after (pat, before_strlen);
2291 else
2292 emit_insn_before (pat, get_insns ());
2294 /* Return the value in the proper mode for this function. */
2295 if (GET_MODE (result) == target_mode)
2296 target = result;
2297 else if (target != 0)
2298 convert_move (target, result, 0);
2299 else
2300 target = convert_to_mode (target_mode, result, 0);
2302 return target;
2306 /* Expand a call to the strstr builtin. Return 0 if we failed the
2307 caller should emit a normal call, otherwise try to get the result
2308 in TARGET, if convenient (and in mode MODE if that's convenient). */
2310 static rtx
2311 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2313 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2314 return 0;
2315 else
2317 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2318 tree fn;
2319 const char *p1, *p2;
2321 p2 = c_getstr (s2);
2322 if (p2 == NULL)
2323 return 0;
2325 p1 = c_getstr (s1);
2326 if (p1 != NULL)
2328 const char *r = strstr (p1, p2);
2330 if (r == NULL)
2331 return const0_rtx;
2333 /* Return an offset into the constant string argument. */
2334 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2335 s1, convert (TREE_TYPE (s1),
2336 ssize_int (r - p1)))),
2337 target, mode, EXPAND_NORMAL);
2340 if (p2[0] == '\0')
2341 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2343 if (p2[1] != '\0')
2344 return 0;
2346 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2347 if (!fn)
2348 return 0;
2350 /* New argument list transforming strstr(s1, s2) to
2351 strchr(s1, s2[0]). */
2352 arglist =
2353 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2354 arglist = tree_cons (NULL_TREE, s1, arglist);
2355 return expand_expr (build_function_call_expr (fn, arglist),
2356 target, mode, EXPAND_NORMAL);
2360 /* Expand a call to the strchr builtin. Return 0 if we failed the
2361 caller should emit a normal call, otherwise try to get the result
2362 in TARGET, if convenient (and in mode MODE if that's convenient). */
2364 static rtx
2365 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2367 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2368 return 0;
2369 else
2371 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2372 const char *p1;
2374 if (TREE_CODE (s2) != INTEGER_CST)
2375 return 0;
2377 p1 = c_getstr (s1);
2378 if (p1 != NULL)
2380 char c;
2381 const char *r;
2383 if (target_char_cast (s2, &c))
2384 return 0;
2386 r = strchr (p1, c);
2388 if (r == NULL)
2389 return const0_rtx;
2391 /* Return an offset into the constant string argument. */
2392 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2393 s1, convert (TREE_TYPE (s1),
2394 ssize_int (r - p1)))),
2395 target, mode, EXPAND_NORMAL);
2398 /* FIXME: Should use here strchrM optab so that ports can optimize
2399 this. */
2400 return 0;
2404 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2405 caller should emit a normal call, otherwise try to get the result
2406 in TARGET, if convenient (and in mode MODE if that's convenient). */
2408 static rtx
2409 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2411 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2412 return 0;
2413 else
2415 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2416 tree fn;
2417 const char *p1;
2419 if (TREE_CODE (s2) != INTEGER_CST)
2420 return 0;
2422 p1 = c_getstr (s1);
2423 if (p1 != NULL)
2425 char c;
2426 const char *r;
2428 if (target_char_cast (s2, &c))
2429 return 0;
2431 r = strrchr (p1, c);
2433 if (r == NULL)
2434 return const0_rtx;
2436 /* Return an offset into the constant string argument. */
2437 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2438 s1, convert (TREE_TYPE (s1),
2439 ssize_int (r - p1)))),
2440 target, mode, EXPAND_NORMAL);
2443 if (! integer_zerop (s2))
2444 return 0;
2446 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2447 if (!fn)
2448 return 0;
2450 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2451 return expand_expr (build_function_call_expr (fn, arglist),
2452 target, mode, EXPAND_NORMAL);
2456 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2457 caller should emit a normal call, otherwise try to get the result
2458 in TARGET, if convenient (and in mode MODE if that's convenient). */
2460 static rtx
2461 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2463 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2464 return 0;
2465 else
2467 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2468 tree fn;
2469 const char *p1, *p2;
2471 p2 = c_getstr (s2);
2472 if (p2 == NULL)
2473 return 0;
2475 p1 = c_getstr (s1);
2476 if (p1 != NULL)
2478 const char *r = strpbrk (p1, p2);
2480 if (r == NULL)
2481 return const0_rtx;
2483 /* Return an offset into the constant string argument. */
2484 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2485 s1, convert (TREE_TYPE (s1),
2486 ssize_int (r - p1)))),
2487 target, mode, EXPAND_NORMAL);
2490 if (p2[0] == '\0')
2492 /* strpbrk(x, "") == NULL.
2493 Evaluate and ignore the arguments in case they had
2494 side-effects. */
2495 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2496 return const0_rtx;
2499 if (p2[1] != '\0')
2500 return 0; /* Really call strpbrk. */
2502 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2503 if (!fn)
2504 return 0;
2506 /* New argument list transforming strpbrk(s1, s2) to
2507 strchr(s1, s2[0]). */
2508 arglist =
2509 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2510 arglist = tree_cons (NULL_TREE, s1, arglist);
2511 return expand_expr (build_function_call_expr (fn, arglist),
2512 target, mode, EXPAND_NORMAL);
2516 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2517 bytes from constant string DATA + OFFSET and return it as target
2518 constant. */
2520 static rtx
2521 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2522 enum machine_mode mode)
2524 const char *str = (const char *) data;
2526 if (offset < 0
2527 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2528 > strlen (str) + 1))
2529 abort (); /* Attempt to read past the end of constant string. */
2531 return c_readstr (str + offset, mode);
2534 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2535 Return 0 if we failed, the caller should emit a normal call,
2536 otherwise try to get the result in TARGET, if convenient (and in
2537 mode MODE if that's convenient). */
2538 static rtx
2539 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2541 if (!validate_arglist (arglist,
2542 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2543 return 0;
2544 else
2546 tree dest = TREE_VALUE (arglist);
2547 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2548 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2549 const char *src_str;
2550 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2551 unsigned int dest_align
2552 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2553 rtx dest_mem, src_mem, dest_addr, len_rtx;
2555 /* If DEST is not a pointer type, call the normal function. */
2556 if (dest_align == 0)
2557 return 0;
2559 /* If the LEN parameter is zero, return DEST. */
2560 if (integer_zerop (len))
2562 /* Evaluate and ignore SRC in case it has side-effects. */
2563 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2564 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2567 /* If SRC and DEST are the same (and not volatile), return DEST. */
2568 if (operand_equal_p (src, dest, 0))
2570 /* Evaluate and ignore LEN in case it has side-effects. */
2571 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2572 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2575 /* If either SRC is not a pointer type, don't do this
2576 operation in-line. */
2577 if (src_align == 0)
2578 return 0;
2580 dest_mem = get_memory_rtx (dest);
2581 set_mem_align (dest_mem, dest_align);
2582 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2583 src_str = c_getstr (src);
2585 /* If SRC is a string constant and block move would be done
2586 by pieces, we can avoid loading the string from memory
2587 and only stored the computed constants. */
2588 if (src_str
2589 && GET_CODE (len_rtx) == CONST_INT
2590 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2591 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2592 (void *) src_str, dest_align))
2594 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2595 builtin_memcpy_read_str,
2596 (void *) src_str, dest_align, 0);
2597 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2598 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2599 return dest_mem;
2602 src_mem = get_memory_rtx (src);
2603 set_mem_align (src_mem, src_align);
2605 /* Copy word part most expediently. */
2606 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2607 BLOCK_OP_NORMAL);
2609 if (dest_addr == 0)
2611 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2612 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2614 return dest_addr;
2618 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2619 Return 0 if we failed the caller should emit a normal call,
2620 otherwise try to get the result in TARGET, if convenient (and in
2621 mode MODE if that's convenient). If ENDP is 0 return the
2622 destination pointer, if ENDP is 1 return the end pointer ala
2623 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2624 stpcpy. */
2626 static rtx
2627 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2628 int endp)
2630 if (!validate_arglist (arglist,
2631 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2632 return 0;
2633 /* If return value is ignored, transform mempcpy into memcpy. */
2634 else if (target == const0_rtx)
2636 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2638 if (!fn)
2639 return 0;
2641 return expand_expr (build_function_call_expr (fn, arglist),
2642 target, mode, EXPAND_NORMAL);
2644 else
2646 tree dest = TREE_VALUE (arglist);
2647 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2648 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2649 const char *src_str;
2650 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2651 unsigned int dest_align
2652 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2653 rtx dest_mem, src_mem, len_rtx;
2655 /* If DEST is not a pointer type, call the normal function. */
2656 if (dest_align == 0)
2657 return 0;
2659 /* If SRC and DEST are the same (and not volatile), do nothing. */
2660 if (operand_equal_p (src, dest, 0))
2662 tree expr;
2664 if (endp == 0)
2666 /* Evaluate and ignore LEN in case it has side-effects. */
2667 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2668 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2671 if (endp == 2)
2672 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2673 integer_one_node));
2674 len = convert (TREE_TYPE (dest), len);
2675 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2676 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2679 /* If LEN is not constant, call the normal function. */
2680 if (! host_integerp (len, 1))
2681 return 0;
2683 /* If the LEN parameter is zero, return DEST. */
2684 if (tree_low_cst (len, 1) == 0)
2686 /* Evaluate and ignore SRC in case it has side-effects. */
2687 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2688 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2691 /* If either SRC is not a pointer type, don't do this
2692 operation in-line. */
2693 if (src_align == 0)
2694 return 0;
2696 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2697 src_str = c_getstr (src);
2699 /* If SRC is a string constant and block move would be done
2700 by pieces, we can avoid loading the string from memory
2701 and only stored the computed constants. */
2702 if (src_str
2703 && GET_CODE (len_rtx) == CONST_INT
2704 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2705 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2706 (void *) src_str, dest_align))
2708 dest_mem = get_memory_rtx (dest);
2709 set_mem_align (dest_mem, dest_align);
2710 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2711 builtin_memcpy_read_str,
2712 (void *) src_str, dest_align, endp);
2713 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2714 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2715 return dest_mem;
2718 if (GET_CODE (len_rtx) == CONST_INT
2719 && can_move_by_pieces (INTVAL (len_rtx),
2720 MIN (dest_align, src_align)))
2722 dest_mem = get_memory_rtx (dest);
2723 set_mem_align (dest_mem, dest_align);
2724 src_mem = get_memory_rtx (src);
2725 set_mem_align (src_mem, src_align);
2726 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2727 MIN (dest_align, src_align), endp);
2728 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2729 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2730 return dest_mem;
2733 return 0;
2737 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2738 if we failed the caller should emit a normal call. */
2740 static rtx
2741 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2743 if (!validate_arglist (arglist,
2744 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2745 return 0;
2746 else
2748 tree dest = TREE_VALUE (arglist);
2749 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2750 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2752 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2753 unsigned int dest_align
2754 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2756 /* If DEST is not a pointer type, call the normal function. */
2757 if (dest_align == 0)
2758 return 0;
2760 /* If the LEN parameter is zero, return DEST. */
2761 if (integer_zerop (len))
2763 /* Evaluate and ignore SRC in case it has side-effects. */
2764 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2765 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2768 /* If SRC and DEST are the same (and not volatile), return DEST. */
2769 if (operand_equal_p (src, dest, 0))
2771 /* Evaluate and ignore LEN in case it has side-effects. */
2772 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2773 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2776 /* If either SRC is not a pointer type, don't do this
2777 operation in-line. */
2778 if (src_align == 0)
2779 return 0;
2781 /* If src is categorized for a readonly section we can use
2782 normal memcpy. */
2783 if (readonly_data_expr (src))
2785 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2786 if (!fn)
2787 return 0;
2788 return expand_expr (build_function_call_expr (fn, arglist),
2789 target, mode, EXPAND_NORMAL);
2792 /* Otherwise, call the normal function. */
2793 return 0;
2797 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2798 if we failed the caller should emit a normal call. */
2800 static rtx
2801 expand_builtin_bcopy (tree arglist)
2803 tree src, dest, size, newarglist;
2805 if (!validate_arglist (arglist,
2806 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2807 return NULL_RTX;
2809 src = TREE_VALUE (arglist);
2810 dest = TREE_VALUE (TREE_CHAIN (arglist));
2811 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2813 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2814 memmove(ptr y, ptr x, size_t z). This is done this way
2815 so that if it isn't expanded inline, we fallback to
2816 calling bcopy instead of memmove. */
2818 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2819 newarglist = tree_cons (NULL_TREE, src, newarglist);
2820 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2822 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2825 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2826 if we failed the caller should emit a normal call, otherwise try to get
2827 the result in TARGET, if convenient (and in mode MODE if that's
2828 convenient). */
2830 static rtx
2831 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2833 tree fn, len, src, dst;
2835 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2836 return 0;
2838 src = TREE_VALUE (TREE_CHAIN (arglist));
2839 dst = TREE_VALUE (arglist);
2841 /* If SRC and DST are equal (and not volatile), return DST. */
2842 if (operand_equal_p (src, dst, 0))
2843 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2845 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2846 if (!fn)
2847 return 0;
2849 len = c_strlen (src, 1);
2850 if (len == 0 || TREE_SIDE_EFFECTS (len))
2851 return 0;
2853 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2854 arglist = build_tree_list (NULL_TREE, len);
2855 arglist = tree_cons (NULL_TREE, src, arglist);
2856 arglist = tree_cons (NULL_TREE, dst, arglist);
2857 return expand_expr (build_function_call_expr (fn, arglist),
2858 target, mode, EXPAND_NORMAL);
2861 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2862 Return 0 if we failed the caller should emit a normal call,
2863 otherwise try to get the result in TARGET, if convenient (and in
2864 mode MODE if that's convenient). */
2866 static rtx
2867 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2869 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2870 return 0;
2871 else
2873 tree dst, src, len;
2875 /* If return value is ignored, transform stpcpy into strcpy. */
2876 if (target == const0_rtx)
2878 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2879 if (!fn)
2880 return 0;
2882 return expand_expr (build_function_call_expr (fn, arglist),
2883 target, mode, EXPAND_NORMAL);
2886 /* Ensure we get an actual string whose length can be evaluated at
2887 compile-time, not an expression containing a string. This is
2888 because the latter will potentially produce pessimized code
2889 when used to produce the return value. */
2890 src = TREE_VALUE (TREE_CHAIN (arglist));
2891 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2892 return 0;
2894 dst = TREE_VALUE (arglist);
2895 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2896 arglist = build_tree_list (NULL_TREE, len);
2897 arglist = tree_cons (NULL_TREE, src, arglist);
2898 arglist = tree_cons (NULL_TREE, dst, arglist);
2899 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2903 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2904 bytes from constant string DATA + OFFSET and return it as target
2905 constant. */
2907 static rtx
2908 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2909 enum machine_mode mode)
2911 const char *str = (const char *) data;
2913 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2914 return const0_rtx;
2916 return c_readstr (str + offset, mode);
2919 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2920 if we failed the caller should emit a normal call. */
2922 static rtx
2923 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2925 if (!validate_arglist (arglist,
2926 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2927 return 0;
2928 else
2930 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2931 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2932 tree fn;
2934 /* We must be passed a constant len parameter. */
2935 if (TREE_CODE (len) != INTEGER_CST)
2936 return 0;
2938 /* If the len parameter is zero, return the dst parameter. */
2939 if (integer_zerop (len))
2941 /* Evaluate and ignore the src argument in case it has
2942 side-effects. */
2943 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2944 VOIDmode, EXPAND_NORMAL);
2945 /* Return the dst parameter. */
2946 return expand_expr (TREE_VALUE (arglist), target, mode,
2947 EXPAND_NORMAL);
2950 /* Now, we must be passed a constant src ptr parameter. */
2951 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2952 return 0;
2954 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2956 /* We're required to pad with trailing zeros if the requested
2957 len is greater than strlen(s2)+1. In that case try to
2958 use store_by_pieces, if it fails, punt. */
2959 if (tree_int_cst_lt (slen, len))
2961 tree dest = TREE_VALUE (arglist);
2962 unsigned int dest_align
2963 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2964 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2965 rtx dest_mem;
2967 if (!p || dest_align == 0 || !host_integerp (len, 1)
2968 || !can_store_by_pieces (tree_low_cst (len, 1),
2969 builtin_strncpy_read_str,
2970 (void *) p, dest_align))
2971 return 0;
2973 dest_mem = get_memory_rtx (dest);
2974 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2975 builtin_strncpy_read_str,
2976 (void *) p, dest_align, 0);
2977 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2978 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2979 return dest_mem;
2982 /* OK transform into builtin memcpy. */
2983 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2984 if (!fn)
2985 return 0;
2986 return expand_expr (build_function_call_expr (fn, arglist),
2987 target, mode, EXPAND_NORMAL);
2991 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2992 bytes from constant string DATA + OFFSET and return it as target
2993 constant. */
2995 static rtx
2996 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2997 enum machine_mode mode)
2999 const char *c = (const char *) data;
3000 char *p = alloca (GET_MODE_SIZE (mode));
3002 memset (p, *c, GET_MODE_SIZE (mode));
3004 return c_readstr (p, mode);
3007 /* Callback routine for store_by_pieces. Return the RTL of a register
3008 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3009 char value given in the RTL register data. For example, if mode is
3010 4 bytes wide, return the RTL for 0x01010101*data. */
3012 static rtx
3013 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3014 enum machine_mode mode)
3016 rtx target, coeff;
3017 size_t size;
3018 char *p;
3020 size = GET_MODE_SIZE (mode);
3021 if (size == 1)
3022 return (rtx) data;
3024 p = alloca (size);
3025 memset (p, 1, size);
3026 coeff = c_readstr (p, mode);
3028 target = convert_to_mode (mode, (rtx) data, 1);
3029 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3030 return force_reg (mode, target);
3033 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3034 if we failed the caller should emit a normal call, otherwise try to get
3035 the result in TARGET, if convenient (and in mode MODE if that's
3036 convenient). */
3038 static rtx
3039 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3041 if (!validate_arglist (arglist,
3042 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3043 return 0;
3044 else
3046 tree dest = TREE_VALUE (arglist);
3047 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3048 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3049 char c;
3051 unsigned int dest_align
3052 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3053 rtx dest_mem, dest_addr, len_rtx;
3055 /* If DEST is not a pointer type, don't do this
3056 operation in-line. */
3057 if (dest_align == 0)
3058 return 0;
3060 /* If the LEN parameter is zero, return DEST. */
3061 if (integer_zerop (len))
3063 /* Evaluate and ignore VAL in case it has side-effects. */
3064 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3065 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3068 if (TREE_CODE (val) != INTEGER_CST)
3070 rtx val_rtx;
3072 if (!host_integerp (len, 1))
3073 return 0;
3075 if (optimize_size && tree_low_cst (len, 1) > 1)
3076 return 0;
3078 /* Assume that we can memset by pieces if we can store the
3079 * the coefficients by pieces (in the required modes).
3080 * We can't pass builtin_memset_gen_str as that emits RTL. */
3081 c = 1;
3082 if (!can_store_by_pieces (tree_low_cst (len, 1),
3083 builtin_memset_read_str,
3084 &c, dest_align))
3085 return 0;
3087 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3088 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3089 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3090 val_rtx);
3091 dest_mem = get_memory_rtx (dest);
3092 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3093 builtin_memset_gen_str,
3094 val_rtx, dest_align, 0);
3095 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3096 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3097 return dest_mem;
3100 if (target_char_cast (val, &c))
3101 return 0;
3103 if (c)
3105 if (!host_integerp (len, 1))
3106 return 0;
3107 if (!can_store_by_pieces (tree_low_cst (len, 1),
3108 builtin_memset_read_str, &c,
3109 dest_align))
3110 return 0;
3112 dest_mem = get_memory_rtx (dest);
3113 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3114 builtin_memset_read_str,
3115 &c, dest_align, 0);
3116 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3117 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3118 return dest_mem;
3121 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3123 dest_mem = get_memory_rtx (dest);
3124 set_mem_align (dest_mem, dest_align);
3125 dest_addr = clear_storage (dest_mem, len_rtx);
3127 if (dest_addr == 0)
3129 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3130 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3133 return dest_addr;
3137 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3138 if we failed the caller should emit a normal call. */
3140 static rtx
3141 expand_builtin_bzero (tree arglist)
3143 tree dest, size, newarglist;
3145 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3146 return NULL_RTX;
3148 dest = TREE_VALUE (arglist);
3149 size = TREE_VALUE (TREE_CHAIN (arglist));
3151 /* New argument list transforming bzero(ptr x, int y) to
3152 memset(ptr x, int 0, size_t y). This is done this way
3153 so that if it isn't expanded inline, we fallback to
3154 calling bzero instead of memset. */
3156 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3157 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3158 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3160 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3163 /* Expand expression EXP, which is a call to the memcmp built-in function.
3164 ARGLIST is the argument list for this call. Return 0 if we failed and the
3165 caller should emit a normal call, otherwise try to get the result in
3166 TARGET, if convenient (and in mode MODE, if that's convenient). */
3168 static rtx
3169 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3170 enum machine_mode mode)
3172 tree arg1, arg2, len;
3173 const char *p1, *p2;
3175 if (!validate_arglist (arglist,
3176 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3177 return 0;
3179 arg1 = TREE_VALUE (arglist);
3180 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3181 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3183 /* If the len parameter is zero, return zero. */
3184 if (integer_zerop (len))
3186 /* Evaluate and ignore arg1 and arg2 in case they have
3187 side-effects. */
3188 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3189 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3190 return const0_rtx;
3193 /* If both arguments are equal (and not volatile), return zero. */
3194 if (operand_equal_p (arg1, arg2, 0))
3196 /* Evaluate and ignore len in case it has side-effects. */
3197 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3198 return const0_rtx;
3201 p1 = c_getstr (arg1);
3202 p2 = c_getstr (arg2);
3204 /* If all arguments are constant, and the value of len is not greater
3205 than the lengths of arg1 and arg2, evaluate at compile-time. */
3206 if (host_integerp (len, 1) && p1 && p2
3207 && compare_tree_int (len, strlen (p1) + 1) <= 0
3208 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3210 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3212 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3215 /* If len parameter is one, return an expression corresponding to
3216 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3217 if (integer_onep (len))
3219 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3220 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3221 tree ind1 =
3222 fold (build1 (CONVERT_EXPR, integer_type_node,
3223 build1 (INDIRECT_REF, cst_uchar_node,
3224 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3225 tree ind2 =
3226 fold (build1 (CONVERT_EXPR, integer_type_node,
3227 build1 (INDIRECT_REF, cst_uchar_node,
3228 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3229 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3230 return expand_expr (result, target, mode, EXPAND_NORMAL);
3233 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3235 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3236 rtx result;
3237 rtx insn;
3239 int arg1_align
3240 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3241 int arg2_align
3242 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3243 enum machine_mode insn_mode;
3245 #ifdef HAVE_cmpmemsi
3246 if (HAVE_cmpmemsi)
3247 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3248 else
3249 #endif
3250 #ifdef HAVE_cmpstrsi
3251 if (HAVE_cmpstrsi)
3252 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3253 else
3254 #endif
3255 return 0;
3257 /* If we don't have POINTER_TYPE, call the function. */
3258 if (arg1_align == 0 || arg2_align == 0)
3259 return 0;
3261 /* Make a place to write the result of the instruction. */
3262 result = target;
3263 if (! (result != 0
3264 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3265 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3266 result = gen_reg_rtx (insn_mode);
3268 arg1_rtx = get_memory_rtx (arg1);
3269 arg2_rtx = get_memory_rtx (arg2);
3270 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3271 #ifdef HAVE_cmpmemsi
3272 if (HAVE_cmpmemsi)
3273 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3274 GEN_INT (MIN (arg1_align, arg2_align)));
3275 else
3276 #endif
3277 #ifdef HAVE_cmpstrsi
3278 if (HAVE_cmpstrsi)
3279 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3280 GEN_INT (MIN (arg1_align, arg2_align)));
3281 else
3282 #endif
3283 abort ();
3285 if (insn)
3286 emit_insn (insn);
3287 else
3288 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3289 TYPE_MODE (integer_type_node), 3,
3290 XEXP (arg1_rtx, 0), Pmode,
3291 XEXP (arg2_rtx, 0), Pmode,
3292 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3293 TYPE_UNSIGNED (sizetype)),
3294 TYPE_MODE (sizetype));
3296 /* Return the value in the proper mode for this function. */
3297 mode = TYPE_MODE (TREE_TYPE (exp));
3298 if (GET_MODE (result) == mode)
3299 return result;
3300 else if (target != 0)
3302 convert_move (target, result, 0);
3303 return target;
3305 else
3306 return convert_to_mode (mode, result, 0);
3308 #endif
3310 return 0;
3313 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3314 if we failed the caller should emit a normal call, otherwise try to get
3315 the result in TARGET, if convenient. */
3317 static rtx
3318 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3320 tree arglist = TREE_OPERAND (exp, 1);
3321 tree arg1, arg2;
3322 const char *p1, *p2;
3324 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3325 return 0;
3327 arg1 = TREE_VALUE (arglist);
3328 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3330 /* If both arguments are equal (and not volatile), return zero. */
3331 if (operand_equal_p (arg1, arg2, 0))
3332 return const0_rtx;
3334 p1 = c_getstr (arg1);
3335 p2 = c_getstr (arg2);
3337 if (p1 && p2)
3339 const int i = strcmp (p1, p2);
3340 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3343 /* If either arg is "", return an expression corresponding to
3344 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3345 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3347 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3348 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3349 tree ind1 =
3350 fold (build1 (CONVERT_EXPR, integer_type_node,
3351 build1 (INDIRECT_REF, cst_uchar_node,
3352 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3353 tree ind2 =
3354 fold (build1 (CONVERT_EXPR, integer_type_node,
3355 build1 (INDIRECT_REF, cst_uchar_node,
3356 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3357 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3358 return expand_expr (result, target, mode, EXPAND_NORMAL);
3361 #ifdef HAVE_cmpstrsi
3362 if (HAVE_cmpstrsi)
3364 tree len, len1, len2;
3365 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3366 rtx result, insn;
3367 tree fndecl;
3369 int arg1_align
3370 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3371 int arg2_align
3372 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3373 enum machine_mode insn_mode
3374 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3376 len1 = c_strlen (arg1, 1);
3377 len2 = c_strlen (arg2, 1);
3379 if (len1)
3380 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3381 if (len2)
3382 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3384 /* If we don't have a constant length for the first, use the length
3385 of the second, if we know it. We don't require a constant for
3386 this case; some cost analysis could be done if both are available
3387 but neither is constant. For now, assume they're equally cheap,
3388 unless one has side effects. If both strings have constant lengths,
3389 use the smaller. */
3391 if (!len1)
3392 len = len2;
3393 else if (!len2)
3394 len = len1;
3395 else if (TREE_SIDE_EFFECTS (len1))
3396 len = len2;
3397 else if (TREE_SIDE_EFFECTS (len2))
3398 len = len1;
3399 else if (TREE_CODE (len1) != INTEGER_CST)
3400 len = len2;
3401 else if (TREE_CODE (len2) != INTEGER_CST)
3402 len = len1;
3403 else if (tree_int_cst_lt (len1, len2))
3404 len = len1;
3405 else
3406 len = len2;
3408 /* If both arguments have side effects, we cannot optimize. */
3409 if (!len || TREE_SIDE_EFFECTS (len))
3410 return 0;
3412 /* If we don't have POINTER_TYPE, call the function. */
3413 if (arg1_align == 0 || arg2_align == 0)
3414 return 0;
3416 /* Make a place to write the result of the instruction. */
3417 result = target;
3418 if (! (result != 0
3419 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3420 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3421 result = gen_reg_rtx (insn_mode);
3423 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3424 arg1 = save_expr (arg1);
3425 arg2 = save_expr (arg2);
3427 arg1_rtx = get_memory_rtx (arg1);
3428 arg2_rtx = get_memory_rtx (arg2);
3429 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3430 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3431 GEN_INT (MIN (arg1_align, arg2_align)));
3432 if (insn)
3434 emit_insn (insn);
3436 /* Return the value in the proper mode for this function. */
3437 mode = TYPE_MODE (TREE_TYPE (exp));
3438 if (GET_MODE (result) == mode)
3439 return result;
3440 if (target == 0)
3441 return convert_to_mode (mode, result, 0);
3442 convert_move (target, result, 0);
3443 return target;
3446 /* Expand the library call ourselves using a stabilized argument
3447 list to avoid re-evaluating the function's arguments twice. */
3448 arglist = build_tree_list (NULL_TREE, arg2);
3449 arglist = tree_cons (NULL_TREE, arg1, arglist);
3450 fndecl = get_callee_fndecl (exp);
3451 exp = build_function_call_expr (fndecl, arglist);
3452 return expand_call (exp, target, target == const0_rtx);
3454 #endif
3455 return 0;
3458 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3459 if we failed the caller should emit a normal call, otherwise try to get
3460 the result in TARGET, if convenient. */
3462 static rtx
3463 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3465 tree arglist = TREE_OPERAND (exp, 1);
3466 tree arg1, arg2, arg3;
3467 const char *p1, *p2;
3469 if (!validate_arglist (arglist,
3470 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3471 return 0;
3473 arg1 = TREE_VALUE (arglist);
3474 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3475 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3477 /* If the len parameter is zero, return zero. */
3478 if (integer_zerop (arg3))
3480 /* Evaluate and ignore arg1 and arg2 in case they have
3481 side-effects. */
3482 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3483 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3484 return const0_rtx;
3487 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3488 if (operand_equal_p (arg1, arg2, 0))
3490 /* Evaluate and ignore arg3 in case it has side-effects. */
3491 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3492 return const0_rtx;
3495 p1 = c_getstr (arg1);
3496 p2 = c_getstr (arg2);
3498 /* If all arguments are constant, evaluate at compile-time. */
3499 if (host_integerp (arg3, 1) && p1 && p2)
3501 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3502 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3505 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3506 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3507 if (host_integerp (arg3, 1)
3508 && (tree_low_cst (arg3, 1) == 1
3509 || (tree_low_cst (arg3, 1) > 1
3510 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3512 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3513 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3514 tree ind1 =
3515 fold (build1 (CONVERT_EXPR, integer_type_node,
3516 build1 (INDIRECT_REF, cst_uchar_node,
3517 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3518 tree ind2 =
3519 fold (build1 (CONVERT_EXPR, integer_type_node,
3520 build1 (INDIRECT_REF, cst_uchar_node,
3521 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3522 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3523 return expand_expr (result, target, mode, EXPAND_NORMAL);
3526 /* If c_strlen can determine an expression for one of the string
3527 lengths, and it doesn't have side effects, then emit cmpstrsi
3528 using length MIN(strlen(string)+1, arg3). */
3529 #ifdef HAVE_cmpstrsi
3530 if (HAVE_cmpstrsi)
3532 tree len, len1, len2;
3533 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3534 rtx result, insn;
3535 tree fndecl;
3537 int arg1_align
3538 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3539 int arg2_align
3540 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3541 enum machine_mode insn_mode
3542 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3544 len1 = c_strlen (arg1, 1);
3545 len2 = c_strlen (arg2, 1);
3547 if (len1)
3548 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3549 if (len2)
3550 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3552 /* If we don't have a constant length for the first, use the length
3553 of the second, if we know it. We don't require a constant for
3554 this case; some cost analysis could be done if both are available
3555 but neither is constant. For now, assume they're equally cheap,
3556 unless one has side effects. If both strings have constant lengths,
3557 use the smaller. */
3559 if (!len1)
3560 len = len2;
3561 else if (!len2)
3562 len = len1;
3563 else if (TREE_SIDE_EFFECTS (len1))
3564 len = len2;
3565 else if (TREE_SIDE_EFFECTS (len2))
3566 len = len1;
3567 else if (TREE_CODE (len1) != INTEGER_CST)
3568 len = len2;
3569 else if (TREE_CODE (len2) != INTEGER_CST)
3570 len = len1;
3571 else if (tree_int_cst_lt (len1, len2))
3572 len = len1;
3573 else
3574 len = len2;
3576 /* If both arguments have side effects, we cannot optimize. */
3577 if (!len || TREE_SIDE_EFFECTS (len))
3578 return 0;
3580 /* The actual new length parameter is MIN(len,arg3). */
3581 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3583 /* If we don't have POINTER_TYPE, call the function. */
3584 if (arg1_align == 0 || arg2_align == 0)
3585 return 0;
3587 /* Make a place to write the result of the instruction. */
3588 result = target;
3589 if (! (result != 0
3590 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3591 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3592 result = gen_reg_rtx (insn_mode);
3594 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3595 arg1 = save_expr (arg1);
3596 arg2 = save_expr (arg2);
3597 len = save_expr (len);
3599 arg1_rtx = get_memory_rtx (arg1);
3600 arg2_rtx = get_memory_rtx (arg2);
3601 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3602 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3603 GEN_INT (MIN (arg1_align, arg2_align)));
3604 if (insn)
3606 emit_insn (insn);
3608 /* Return the value in the proper mode for this function. */
3609 mode = TYPE_MODE (TREE_TYPE (exp));
3610 if (GET_MODE (result) == mode)
3611 return result;
3612 if (target == 0)
3613 return convert_to_mode (mode, result, 0);
3614 convert_move (target, result, 0);
3615 return target;
3618 /* Expand the library call ourselves using a stabilized argument
3619 list to avoid re-evaluating the function's arguments twice. */
3620 arglist = build_tree_list (NULL_TREE, len);
3621 arglist = tree_cons (NULL_TREE, arg2, arglist);
3622 arglist = tree_cons (NULL_TREE, arg1, arglist);
3623 fndecl = get_callee_fndecl (exp);
3624 exp = build_function_call_expr (fndecl, arglist);
3625 return expand_call (exp, target, target == const0_rtx);
3627 #endif
3628 return 0;
3631 /* Expand expression EXP, which is a call to the strcat builtin.
3632 Return 0 if we failed the caller should emit a normal call,
3633 otherwise try to get the result in TARGET, if convenient. */
3635 static rtx
3636 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3638 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3639 return 0;
3640 else
3642 tree dst = TREE_VALUE (arglist),
3643 src = TREE_VALUE (TREE_CHAIN (arglist));
3644 const char *p = c_getstr (src);
3646 if (p)
3648 /* If the string length is zero, return the dst parameter. */
3649 if (*p == '\0')
3650 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3651 else if (!optimize_size)
3653 /* Otherwise if !optimize_size, see if we can store by
3654 pieces into (dst + strlen(dst)). */
3655 tree newdst, arglist,
3656 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3658 /* This is the length argument. */
3659 arglist = build_tree_list (NULL_TREE,
3660 fold (size_binop (PLUS_EXPR,
3661 c_strlen (src, 0),
3662 ssize_int (1))));
3663 /* Prepend src argument. */
3664 arglist = tree_cons (NULL_TREE, src, arglist);
3666 /* We're going to use dst more than once. */
3667 dst = save_expr (dst);
3669 /* Create strlen (dst). */
3670 newdst =
3671 fold (build_function_call_expr (strlen_fn,
3672 build_tree_list (NULL_TREE,
3673 dst)));
3674 /* Create (dst + strlen (dst)). */
3675 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3677 /* Prepend the new dst argument. */
3678 arglist = tree_cons (NULL_TREE, newdst, arglist);
3680 /* We don't want to get turned into a memcpy if the
3681 target is const0_rtx, i.e. when the return value
3682 isn't used. That would produce pessimized code so
3683 pass in a target of zero, it should never actually be
3684 used. If this was successful return the original
3685 dst, not the result of mempcpy. */
3686 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3687 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3688 else
3689 return 0;
3693 return 0;
3697 /* Expand expression EXP, which is a call to the strncat builtin.
3698 Return 0 if we failed the caller should emit a normal call,
3699 otherwise try to get the result in TARGET, if convenient. */
3701 static rtx
3702 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3704 if (!validate_arglist (arglist,
3705 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3706 return 0;
3707 else
3709 tree dst = TREE_VALUE (arglist),
3710 src = TREE_VALUE (TREE_CHAIN (arglist)),
3711 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3712 const char *p = c_getstr (src);
3714 /* If the requested length is zero, or the src parameter string
3715 length is zero, return the dst parameter. */
3716 if (integer_zerop (len) || (p && *p == '\0'))
3718 /* Evaluate and ignore the src and len parameters in case
3719 they have side-effects. */
3720 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3721 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3722 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3725 /* If the requested len is greater than or equal to the string
3726 length, call strcat. */
3727 if (TREE_CODE (len) == INTEGER_CST && p
3728 && compare_tree_int (len, strlen (p)) >= 0)
3730 tree newarglist
3731 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3732 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3734 /* If the replacement _DECL isn't initialized, don't do the
3735 transformation. */
3736 if (!fn)
3737 return 0;
3739 return expand_expr (build_function_call_expr (fn, newarglist),
3740 target, mode, EXPAND_NORMAL);
3742 return 0;
3746 /* Expand expression EXP, which is a call to the strspn builtin.
3747 Return 0 if we failed the caller should emit a normal call,
3748 otherwise try to get the result in TARGET, if convenient. */
3750 static rtx
3751 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3753 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3754 return 0;
3755 else
3757 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3758 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3760 /* If both arguments are constants, evaluate at compile-time. */
3761 if (p1 && p2)
3763 const size_t r = strspn (p1, p2);
3764 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3767 /* If either argument is "", return 0. */
3768 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3770 /* Evaluate and ignore both arguments in case either one has
3771 side-effects. */
3772 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3773 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3774 return const0_rtx;
3776 return 0;
3780 /* Expand expression EXP, which is a call to the strcspn builtin.
3781 Return 0 if we failed the caller should emit a normal call,
3782 otherwise try to get the result in TARGET, if convenient. */
3784 static rtx
3785 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3787 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3788 return 0;
3789 else
3791 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3792 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3794 /* If both arguments are constants, evaluate at compile-time. */
3795 if (p1 && p2)
3797 const size_t r = strcspn (p1, p2);
3798 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3801 /* If the first argument is "", return 0. */
3802 if (p1 && *p1 == '\0')
3804 /* Evaluate and ignore argument s2 in case it has
3805 side-effects. */
3806 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3807 return const0_rtx;
3810 /* If the second argument is "", return __builtin_strlen(s1). */
3811 if (p2 && *p2 == '\0')
3813 tree newarglist = build_tree_list (NULL_TREE, s1),
3814 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3816 /* If the replacement _DECL isn't initialized, don't do the
3817 transformation. */
3818 if (!fn)
3819 return 0;
3821 return expand_expr (build_function_call_expr (fn, newarglist),
3822 target, mode, EXPAND_NORMAL);
3824 return 0;
3828 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3829 if that's convenient. */
3832 expand_builtin_saveregs (void)
3834 rtx val, seq;
3836 /* Don't do __builtin_saveregs more than once in a function.
3837 Save the result of the first call and reuse it. */
3838 if (saveregs_value != 0)
3839 return saveregs_value;
3841 /* When this function is called, it means that registers must be
3842 saved on entry to this function. So we migrate the call to the
3843 first insn of this function. */
3845 start_sequence ();
3847 /* Do whatever the machine needs done in this case. */
3848 val = targetm.calls.expand_builtin_saveregs ();
3850 seq = get_insns ();
3851 end_sequence ();
3853 saveregs_value = val;
3855 /* Put the insns after the NOTE that starts the function. If this
3856 is inside a start_sequence, make the outer-level insn chain current, so
3857 the code is placed at the start of the function. */
3858 push_topmost_sequence ();
3859 emit_insn_after (seq, get_insns ());
3860 pop_topmost_sequence ();
3862 return val;
3865 /* __builtin_args_info (N) returns word N of the arg space info
3866 for the current function. The number and meanings of words
3867 is controlled by the definition of CUMULATIVE_ARGS. */
3869 static rtx
3870 expand_builtin_args_info (tree arglist)
3872 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3873 int *word_ptr = (int *) &current_function_args_info;
3875 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3876 abort ();
3878 if (arglist != 0)
3880 if (!host_integerp (TREE_VALUE (arglist), 0))
3881 error ("argument of `__builtin_args_info' must be constant");
3882 else
3884 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3886 if (wordnum < 0 || wordnum >= nwords)
3887 error ("argument of `__builtin_args_info' out of range");
3888 else
3889 return GEN_INT (word_ptr[wordnum]);
3892 else
3893 error ("missing argument in `__builtin_args_info'");
3895 return const0_rtx;
3898 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3900 static rtx
3901 expand_builtin_next_arg (tree arglist)
3903 tree fntype = TREE_TYPE (current_function_decl);
3905 if (TYPE_ARG_TYPES (fntype) == 0
3906 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3907 == void_type_node))
3909 error ("`va_start' used in function with fixed args");
3910 return const0_rtx;
3913 if (arglist)
3915 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3916 tree arg = TREE_VALUE (arglist);
3918 /* Strip off all nops for the sake of the comparison. This
3919 is not quite the same as STRIP_NOPS. It does more.
3920 We must also strip off INDIRECT_EXPR for C++ reference
3921 parameters. */
3922 while (TREE_CODE (arg) == NOP_EXPR
3923 || TREE_CODE (arg) == CONVERT_EXPR
3924 || TREE_CODE (arg) == NON_LVALUE_EXPR
3925 || TREE_CODE (arg) == INDIRECT_REF)
3926 arg = TREE_OPERAND (arg, 0);
3927 if (arg != last_parm)
3928 warning ("second parameter of `va_start' not last named argument");
3930 else
3931 /* Evidently an out of date version of <stdarg.h>; can't validate
3932 va_start's second argument, but can still work as intended. */
3933 warning ("`__builtin_next_arg' called without an argument");
3935 return expand_binop (Pmode, add_optab,
3936 current_function_internal_arg_pointer,
3937 current_function_arg_offset_rtx,
3938 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3941 /* Make it easier for the backends by protecting the valist argument
3942 from multiple evaluations. */
3944 static tree
3945 stabilize_va_list (tree valist, int needs_lvalue)
3947 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3949 if (TREE_SIDE_EFFECTS (valist))
3950 valist = save_expr (valist);
3952 /* For this case, the backends will be expecting a pointer to
3953 TREE_TYPE (va_list_type_node), but it's possible we've
3954 actually been given an array (an actual va_list_type_node).
3955 So fix it. */
3956 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3958 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3959 tree p2 = build_pointer_type (va_list_type_node);
3961 valist = build1 (ADDR_EXPR, p2, valist);
3962 valist = fold (build1 (NOP_EXPR, p1, valist));
3965 else
3967 tree pt;
3969 if (! needs_lvalue)
3971 if (! TREE_SIDE_EFFECTS (valist))
3972 return valist;
3974 pt = build_pointer_type (va_list_type_node);
3975 valist = fold (build1 (ADDR_EXPR, pt, valist));
3976 TREE_SIDE_EFFECTS (valist) = 1;
3979 if (TREE_SIDE_EFFECTS (valist))
3980 valist = save_expr (valist);
3981 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3982 valist));
3985 return valist;
3988 /* The "standard" definition of va_list is void*. */
3990 tree
3991 std_build_builtin_va_list (void)
3993 return ptr_type_node;
3996 /* The "standard" implementation of va_start: just assign `nextarg' to
3997 the variable. */
3999 void
4000 std_expand_builtin_va_start (tree valist, rtx nextarg)
4002 tree t;
4004 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4005 make_tree (ptr_type_node, nextarg));
4006 TREE_SIDE_EFFECTS (t) = 1;
4008 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4011 /* Expand ARGLIST, from a call to __builtin_va_start. */
4013 static rtx
4014 expand_builtin_va_start (tree arglist)
4016 rtx nextarg;
4017 tree chain, valist;
4019 chain = TREE_CHAIN (arglist);
4021 if (TREE_CHAIN (chain))
4022 error ("too many arguments to function `va_start'");
4024 nextarg = expand_builtin_next_arg (chain);
4025 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4027 #ifdef EXPAND_BUILTIN_VA_START
4028 EXPAND_BUILTIN_VA_START (valist, nextarg);
4029 #else
4030 std_expand_builtin_va_start (valist, nextarg);
4031 #endif
4033 return const0_rtx;
4036 /* The "standard" implementation of va_arg: read the value from the
4037 current (padded) address and increment by the (padded) size. */
4040 std_expand_builtin_va_arg (tree valist, tree type)
4042 tree addr_tree, t, type_size = NULL;
4043 tree align, alignm1;
4044 tree rounded_size;
4045 rtx addr;
4046 HOST_WIDE_INT boundary;
4048 /* Compute the rounded size of the type. */
4049 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4050 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4051 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4053 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4054 requires greater alignment, we must perform dynamic alignment. */
4056 if (boundary > PARM_BOUNDARY)
4058 if (!PAD_VARARGS_DOWN)
4060 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4061 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4062 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4063 TREE_SIDE_EFFECTS (t) = 1;
4064 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4066 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4067 build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4068 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4069 TREE_SIDE_EFFECTS (t) = 1;
4070 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4072 if (type == error_mark_node
4073 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4074 || TREE_OVERFLOW (type_size))
4075 rounded_size = size_zero_node;
4076 else
4077 rounded_size = fold (build (MULT_EXPR, sizetype,
4078 fold (build (TRUNC_DIV_EXPR, sizetype,
4079 fold (build (PLUS_EXPR, sizetype,
4080 type_size, alignm1)),
4081 align)),
4082 align));
4084 /* Get AP. */
4085 addr_tree = valist;
4086 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4088 /* Small args are padded downward. */
4089 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4090 fold (build (COND_EXPR, sizetype,
4091 fold (build (GT_EXPR, sizetype,
4092 rounded_size,
4093 align)),
4094 size_zero_node,
4095 fold (build (MINUS_EXPR, sizetype,
4096 rounded_size,
4097 type_size))))));
4100 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4101 addr = copy_to_reg (addr);
4103 /* Compute new value for AP. */
4104 if (! integer_zerop (rounded_size))
4106 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4107 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4108 rounded_size));
4109 TREE_SIDE_EFFECTS (t) = 1;
4110 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4113 return addr;
4116 /* Expand __builtin_va_arg, which is not really a builtin function, but
4117 a very special sort of operator. */
4120 expand_builtin_va_arg (tree valist, tree type)
4122 rtx addr, result;
4123 tree promoted_type, want_va_type, have_va_type;
4125 /* Verify that valist is of the proper type. */
4127 want_va_type = va_list_type_node;
4128 have_va_type = TREE_TYPE (valist);
4129 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4131 /* If va_list is an array type, the argument may have decayed
4132 to a pointer type, e.g. by being passed to another function.
4133 In that case, unwrap both types so that we can compare the
4134 underlying records. */
4135 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4136 || TREE_CODE (have_va_type) == POINTER_TYPE)
4138 want_va_type = TREE_TYPE (want_va_type);
4139 have_va_type = TREE_TYPE (have_va_type);
4142 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4144 error ("first argument to `va_arg' not of type `va_list'");
4145 addr = const0_rtx;
4148 /* Generate a diagnostic for requesting data of a type that cannot
4149 be passed through `...' due to type promotion at the call site. */
4150 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4151 != type)
4153 const char *name = "<anonymous type>", *pname = 0;
4154 static bool gave_help;
4156 if (TYPE_NAME (type))
4158 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4159 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4160 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4161 && DECL_NAME (TYPE_NAME (type)))
4162 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4164 if (TYPE_NAME (promoted_type))
4166 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4167 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4168 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4169 && DECL_NAME (TYPE_NAME (promoted_type)))
4170 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4173 /* Unfortunately, this is merely undefined, rather than a constraint
4174 violation, so we cannot make this an error. If this call is never
4175 executed, the program is still strictly conforming. */
4176 warning ("`%s' is promoted to `%s' when passed through `...'",
4177 name, pname);
4178 if (! gave_help)
4180 gave_help = true;
4181 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4182 pname, name);
4185 /* We can, however, treat "undefined" any way we please.
4186 Call abort to encourage the user to fix the program. */
4187 inform ("if this code is reached, the program will abort");
4188 expand_builtin_trap ();
4190 /* This is dead code, but go ahead and finish so that the
4191 mode of the result comes out right. */
4192 addr = const0_rtx;
4194 else
4196 /* Make it easier for the backends by protecting the valist argument
4197 from multiple evaluations. */
4198 valist = stabilize_va_list (valist, 0);
4200 #ifdef EXPAND_BUILTIN_VA_ARG
4201 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4202 #else
4203 addr = std_expand_builtin_va_arg (valist, type);
4204 #endif
4207 addr = convert_memory_address (Pmode, addr);
4209 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4210 set_mem_alias_set (result, get_varargs_alias_set ());
4212 return result;
4215 /* Expand ARGLIST, from a call to __builtin_va_end. */
4217 static rtx
4218 expand_builtin_va_end (tree arglist)
4220 tree valist = TREE_VALUE (arglist);
4222 /* Evaluate for side effects, if needed. I hate macros that don't
4223 do that. */
4224 if (TREE_SIDE_EFFECTS (valist))
4225 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4227 return const0_rtx;
4230 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4231 builtin rather than just as an assignment in stdarg.h because of the
4232 nastiness of array-type va_list types. */
4234 static rtx
4235 expand_builtin_va_copy (tree arglist)
4237 tree dst, src, t;
4239 dst = TREE_VALUE (arglist);
4240 src = TREE_VALUE (TREE_CHAIN (arglist));
4242 dst = stabilize_va_list (dst, 1);
4243 src = stabilize_va_list (src, 0);
4245 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4247 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4248 TREE_SIDE_EFFECTS (t) = 1;
4249 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4251 else
4253 rtx dstb, srcb, size;
4255 /* Evaluate to pointers. */
4256 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4257 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4258 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4259 VOIDmode, EXPAND_NORMAL);
4261 dstb = convert_memory_address (Pmode, dstb);
4262 srcb = convert_memory_address (Pmode, srcb);
4264 /* "Dereference" to BLKmode memories. */
4265 dstb = gen_rtx_MEM (BLKmode, dstb);
4266 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4267 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4268 srcb = gen_rtx_MEM (BLKmode, srcb);
4269 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4270 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4272 /* Copy. */
4273 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4276 return const0_rtx;
4279 /* Expand a call to one of the builtin functions __builtin_frame_address or
4280 __builtin_return_address. */
4282 static rtx
4283 expand_builtin_frame_address (tree fndecl, tree arglist)
4285 /* The argument must be a nonnegative integer constant.
4286 It counts the number of frames to scan up the stack.
4287 The value is the return address saved in that frame. */
4288 if (arglist == 0)
4289 /* Warning about missing arg was already issued. */
4290 return const0_rtx;
4291 else if (! host_integerp (TREE_VALUE (arglist), 1))
4293 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4294 error ("invalid arg to `__builtin_frame_address'");
4295 else
4296 error ("invalid arg to `__builtin_return_address'");
4297 return const0_rtx;
4299 else
4301 rtx tem
4302 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4303 tree_low_cst (TREE_VALUE (arglist), 1),
4304 hard_frame_pointer_rtx);
4306 /* Some ports cannot access arbitrary stack frames. */
4307 if (tem == NULL)
4309 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4310 warning ("unsupported arg to `__builtin_frame_address'");
4311 else
4312 warning ("unsupported arg to `__builtin_return_address'");
4313 return const0_rtx;
4316 /* For __builtin_frame_address, return what we've got. */
4317 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4318 return tem;
4320 if (GET_CODE (tem) != REG
4321 && ! CONSTANT_P (tem))
4322 tem = copy_to_mode_reg (Pmode, tem);
4323 return tem;
4327 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4328 we failed and the caller should emit a normal call, otherwise try to get
4329 the result in TARGET, if convenient. */
4331 static rtx
4332 expand_builtin_alloca (tree arglist, rtx target)
4334 rtx op0;
4335 rtx result;
4337 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4338 return 0;
4340 /* Compute the argument. */
4341 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4343 /* Allocate the desired space. */
4344 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4345 result = convert_memory_address (ptr_mode, result);
4347 return result;
4350 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4351 Return 0 if a normal call should be emitted rather than expanding the
4352 function in-line. If convenient, the result should be placed in TARGET.
4353 SUBTARGET may be used as the target for computing one of EXP's operands. */
4355 static rtx
4356 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4357 rtx subtarget, optab op_optab)
4359 rtx op0;
4360 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4361 return 0;
4363 /* Compute the argument. */
4364 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4365 /* Compute op, into TARGET if possible.
4366 Set TARGET to wherever the result comes back. */
4367 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4368 op_optab, op0, target, 1);
4369 if (target == 0)
4370 abort ();
4372 return convert_to_mode (target_mode, target, 0);
4375 /* If the string passed to fputs is a constant and is one character
4376 long, we attempt to transform this call into __builtin_fputc(). */
4378 static rtx
4379 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4381 tree len, fn;
4382 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4383 : implicit_built_in_decls[BUILT_IN_FPUTC];
4384 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4385 : implicit_built_in_decls[BUILT_IN_FWRITE];
4387 /* If the return value is used, or the replacement _DECL isn't
4388 initialized, don't do the transformation. */
4389 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4390 return 0;
4392 /* Verify the arguments in the original call. */
4393 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4394 return 0;
4396 /* Get the length of the string passed to fputs. If the length
4397 can't be determined, punt. */
4398 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4399 || TREE_CODE (len) != INTEGER_CST)
4400 return 0;
4402 switch (compare_tree_int (len, 1))
4404 case -1: /* length is 0, delete the call entirely . */
4406 /* Evaluate and ignore the argument in case it has
4407 side-effects. */
4408 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4409 VOIDmode, EXPAND_NORMAL);
4410 return const0_rtx;
4412 case 0: /* length is 1, call fputc. */
4414 const char *p = c_getstr (TREE_VALUE (arglist));
4416 if (p != NULL)
4418 /* New argument list transforming fputs(string, stream) to
4419 fputc(string[0], stream). */
4420 arglist =
4421 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4422 arglist =
4423 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4424 fn = fn_fputc;
4425 break;
4428 /* Fall through. */
4429 case 1: /* length is greater than 1, call fwrite. */
4431 tree string_arg;
4433 /* If optimizing for size keep fputs. */
4434 if (optimize_size)
4435 return 0;
4436 string_arg = TREE_VALUE (arglist);
4437 /* New argument list transforming fputs(string, stream) to
4438 fwrite(string, 1, len, stream). */
4439 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4440 arglist = tree_cons (NULL_TREE, len, arglist);
4441 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4442 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4443 fn = fn_fwrite;
4444 break;
4446 default:
4447 abort ();
4450 return expand_expr (build_function_call_expr (fn, arglist),
4451 const0_rtx, VOIDmode, EXPAND_NORMAL);
4454 /* Expand a call to __builtin_expect. We return our argument and emit a
4455 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4456 a non-jump context. */
4458 static rtx
4459 expand_builtin_expect (tree arglist, rtx target)
4461 tree exp, c;
4462 rtx note, rtx_c;
4464 if (arglist == NULL_TREE
4465 || TREE_CHAIN (arglist) == NULL_TREE)
4466 return const0_rtx;
4467 exp = TREE_VALUE (arglist);
4468 c = TREE_VALUE (TREE_CHAIN (arglist));
4470 if (TREE_CODE (c) != INTEGER_CST)
4472 error ("second arg to `__builtin_expect' must be a constant");
4473 c = integer_zero_node;
4476 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4478 /* Don't bother with expected value notes for integral constants. */
4479 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4481 /* We do need to force this into a register so that we can be
4482 moderately sure to be able to correctly interpret the branch
4483 condition later. */
4484 target = force_reg (GET_MODE (target), target);
4486 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4488 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4489 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4492 return target;
4495 /* Like expand_builtin_expect, except do this in a jump context. This is
4496 called from do_jump if the conditional is a __builtin_expect. Return either
4497 a list of insns to emit the jump or NULL if we cannot optimize
4498 __builtin_expect. We need to optimize this at jump time so that machines
4499 like the PowerPC don't turn the test into a SCC operation, and then jump
4500 based on the test being 0/1. */
4503 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4505 tree arglist = TREE_OPERAND (exp, 1);
4506 tree arg0 = TREE_VALUE (arglist);
4507 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4508 rtx ret = NULL_RTX;
4510 /* Only handle __builtin_expect (test, 0) and
4511 __builtin_expect (test, 1). */
4512 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4513 && (integer_zerop (arg1) || integer_onep (arg1)))
4515 rtx insn, drop_through_label, temp;
4517 /* Expand the jump insns. */
4518 start_sequence ();
4519 do_jump (arg0, if_false_label, if_true_label);
4520 ret = get_insns ();
4522 drop_through_label = get_last_insn ();
4523 if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4524 drop_through_label = prev_nonnote_insn (drop_through_label);
4525 if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4526 drop_through_label = NULL_RTX;
4527 end_sequence ();
4529 if (! if_true_label)
4530 if_true_label = drop_through_label;
4531 if (! if_false_label)
4532 if_false_label = drop_through_label;
4534 /* Go through and add the expect's to each of the conditional jumps. */
4535 insn = ret;
4536 while (insn != NULL_RTX)
4538 rtx next = NEXT_INSN (insn);
4540 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4542 rtx ifelse = SET_SRC (pc_set (insn));
4543 rtx then_dest = XEXP (ifelse, 1);
4544 rtx else_dest = XEXP (ifelse, 2);
4545 int taken = -1;
4547 /* First check if we recognize any of the labels. */
4548 if (GET_CODE (then_dest) == LABEL_REF
4549 && XEXP (then_dest, 0) == if_true_label)
4550 taken = 1;
4551 else if (GET_CODE (then_dest) == LABEL_REF
4552 && XEXP (then_dest, 0) == if_false_label)
4553 taken = 0;
4554 else if (GET_CODE (else_dest) == LABEL_REF
4555 && XEXP (else_dest, 0) == if_false_label)
4556 taken = 1;
4557 else if (GET_CODE (else_dest) == LABEL_REF
4558 && XEXP (else_dest, 0) == if_true_label)
4559 taken = 0;
4560 /* Otherwise check where we drop through. */
4561 else if (else_dest == pc_rtx)
4563 if (next && GET_CODE (next) == NOTE)
4564 next = next_nonnote_insn (next);
4566 if (next && GET_CODE (next) == JUMP_INSN
4567 && any_uncondjump_p (next))
4568 temp = XEXP (SET_SRC (pc_set (next)), 0);
4569 else
4570 temp = next;
4572 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4573 else that can't possibly match either target label. */
4574 if (temp == if_false_label)
4575 taken = 1;
4576 else if (temp == if_true_label)
4577 taken = 0;
4579 else if (then_dest == pc_rtx)
4581 if (next && GET_CODE (next) == NOTE)
4582 next = next_nonnote_insn (next);
4584 if (next && GET_CODE (next) == JUMP_INSN
4585 && any_uncondjump_p (next))
4586 temp = XEXP (SET_SRC (pc_set (next)), 0);
4587 else
4588 temp = next;
4590 if (temp == if_false_label)
4591 taken = 0;
4592 else if (temp == if_true_label)
4593 taken = 1;
4596 if (taken != -1)
4598 /* If the test is expected to fail, reverse the
4599 probabilities. */
4600 if (integer_zerop (arg1))
4601 taken = 1 - taken;
4602 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4606 insn = next;
4610 return ret;
4613 void
4614 expand_builtin_trap (void)
4616 #ifdef HAVE_trap
4617 if (HAVE_trap)
4618 emit_insn (gen_trap ());
4619 else
4620 #endif
4621 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4622 emit_barrier ();
4625 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4626 Return 0 if a normal call should be emitted rather than expanding
4627 the function inline. If convenient, the result should be placed
4628 in TARGET. SUBTARGET may be used as the target for computing
4629 the operand. */
4631 static rtx
4632 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4634 enum machine_mode mode;
4635 tree arg;
4636 rtx op0;
4638 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4639 return 0;
4641 arg = TREE_VALUE (arglist);
4642 mode = TYPE_MODE (TREE_TYPE (arg));
4643 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4644 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4647 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4648 Return 0 if a normal call should be emitted rather than expanding
4649 the function inline. If convenient, the result should be placed
4650 in target. */
4652 static rtx
4653 expand_builtin_cabs (tree arglist, rtx target)
4655 enum machine_mode mode;
4656 tree arg;
4657 rtx op0;
4659 if (arglist == 0 || TREE_CHAIN (arglist))
4660 return 0;
4661 arg = TREE_VALUE (arglist);
4662 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4663 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4664 return 0;
4666 mode = TYPE_MODE (TREE_TYPE (arg));
4667 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4668 return expand_complex_abs (mode, op0, target, 0);
4671 /* Create a new constant string literal and return a char* pointer to it.
4672 The STRING_CST value is the LEN characters at STR. */
4673 static tree
4674 build_string_literal (int len, const char *str)
4676 tree t, elem, index, type;
4678 t = build_string (len, str);
4679 elem = build_type_variant (char_type_node, 1, 0);
4680 index = build_index_type (build_int_2 (len - 1, 0));
4681 type = build_array_type (elem, index);
4682 TREE_TYPE (t) = type;
4683 TREE_CONSTANT (t) = 1;
4684 TREE_READONLY (t) = 1;
4685 TREE_STATIC (t) = 1;
4687 type = build_pointer_type (type);
4688 t = build1 (ADDR_EXPR, type, t);
4690 type = build_pointer_type (elem);
4691 t = build1 (NOP_EXPR, type, t);
4692 return t;
4695 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4696 Return 0 if a normal call should be emitted rather than transforming
4697 the function inline. If convenient, the result should be placed in
4698 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4699 call. */
4700 static rtx
4701 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4702 bool unlocked)
4704 tree fn_putchar = unlocked
4705 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4706 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4707 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4708 : implicit_built_in_decls[BUILT_IN_PUTS];
4709 const char *fmt_str;
4710 tree fn, fmt, arg;
4712 /* If the return value is used, don't do the transformation. */
4713 if (target != const0_rtx)
4714 return 0;
4716 /* Verify the required arguments in the original call. */
4717 if (! arglist)
4718 return 0;
4719 fmt = TREE_VALUE (arglist);
4720 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4721 return 0;
4722 arglist = TREE_CHAIN (arglist);
4724 /* Check whether the format is a literal string constant. */
4725 fmt_str = c_getstr (fmt);
4726 if (fmt_str == NULL)
4727 return 0;
4729 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4730 if (strcmp (fmt_str, "%s\n") == 0)
4732 if (! arglist
4733 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4734 || TREE_CHAIN (arglist))
4735 return 0;
4736 fn = fn_puts;
4738 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4739 else if (strcmp (fmt_str, "%c") == 0)
4741 if (! arglist
4742 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4743 || TREE_CHAIN (arglist))
4744 return 0;
4745 fn = fn_putchar;
4747 else
4749 /* We can't handle anything else with % args or %% ... yet. */
4750 if (strchr (fmt_str, '%'))
4751 return 0;
4753 if (arglist)
4754 return 0;
4756 /* If the format specifier was "", printf does nothing. */
4757 if (fmt_str[0] == '\0')
4758 return const0_rtx;
4759 /* If the format specifier has length of 1, call putchar. */
4760 if (fmt_str[1] == '\0')
4762 /* Given printf("c"), (where c is any one character,)
4763 convert "c"[0] to an int and pass that to the replacement
4764 function. */
4765 arg = build_int_2 (fmt_str[0], 0);
4766 arglist = build_tree_list (NULL_TREE, arg);
4767 fn = fn_putchar;
4769 else
4771 /* If the format specifier was "string\n", call puts("string"). */
4772 size_t len = strlen (fmt_str);
4773 if (fmt_str[len - 1] == '\n')
4775 /* Create a NUL-terminated string that's one char shorter
4776 than the original, stripping off the trailing '\n'. */
4777 char *newstr = alloca (len);
4778 memcpy (newstr, fmt_str, len - 1);
4779 newstr[len - 1] = 0;
4781 arg = build_string_literal (len, newstr);
4782 arglist = build_tree_list (NULL_TREE, arg);
4783 fn = fn_puts;
4785 else
4786 /* We'd like to arrange to call fputs(string,stdout) here,
4787 but we need stdout and don't have a way to get it yet. */
4788 return 0;
4792 if (!fn)
4793 return 0;
4794 return expand_expr (build_function_call_expr (fn, arglist),
4795 target, mode, EXPAND_NORMAL);
4798 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4799 Return 0 if a normal call should be emitted rather than transforming
4800 the function inline. If convenient, the result should be placed in
4801 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4802 call. */
4803 static rtx
4804 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4805 bool unlocked)
4807 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4808 : implicit_built_in_decls[BUILT_IN_FPUTC];
4809 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4810 : implicit_built_in_decls[BUILT_IN_FPUTS];
4811 const char *fmt_str;
4812 tree fn, fmt, fp, arg;
4814 /* If the return value is used, don't do the transformation. */
4815 if (target != const0_rtx)
4816 return 0;
4818 /* Verify the required arguments in the original call. */
4819 if (! arglist)
4820 return 0;
4821 fp = TREE_VALUE (arglist);
4822 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4823 return 0;
4824 arglist = TREE_CHAIN (arglist);
4825 if (! arglist)
4826 return 0;
4827 fmt = TREE_VALUE (arglist);
4828 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4829 return 0;
4830 arglist = TREE_CHAIN (arglist);
4832 /* Check whether the format is a literal string constant. */
4833 fmt_str = c_getstr (fmt);
4834 if (fmt_str == NULL)
4835 return 0;
4837 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4838 if (strcmp (fmt_str, "%s") == 0)
4840 if (! arglist
4841 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4842 || TREE_CHAIN (arglist))
4843 return 0;
4844 arg = TREE_VALUE (arglist);
4845 arglist = build_tree_list (NULL_TREE, fp);
4846 arglist = tree_cons (NULL_TREE, arg, arglist);
4847 fn = fn_fputs;
4849 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4850 else if (strcmp (fmt_str, "%c") == 0)
4852 if (! arglist
4853 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4854 || TREE_CHAIN (arglist))
4855 return 0;
4856 arg = TREE_VALUE (arglist);
4857 arglist = build_tree_list (NULL_TREE, fp);
4858 arglist = tree_cons (NULL_TREE, arg, arglist);
4859 fn = fn_fputc;
4861 else
4863 /* We can't handle anything else with % args or %% ... yet. */
4864 if (strchr (fmt_str, '%'))
4865 return 0;
4867 if (arglist)
4868 return 0;
4870 /* If the format specifier was "", fprintf does nothing. */
4871 if (fmt_str[0] == '\0')
4873 /* Evaluate and ignore FILE* argument for side-effects. */
4874 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4875 return const0_rtx;
4878 /* When "string" doesn't contain %, replace all cases of
4879 fprintf(stream,string) with fputs(string,stream). The fputs
4880 builtin will take care of special cases like length == 1. */
4881 arglist = build_tree_list (NULL_TREE, fp);
4882 arglist = tree_cons (NULL_TREE, fmt, arglist);
4883 fn = fn_fputs;
4886 if (!fn)
4887 return 0;
4888 return expand_expr (build_function_call_expr (fn, arglist),
4889 target, mode, EXPAND_NORMAL);
4892 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4893 a normal call should be emitted rather than expanding the function
4894 inline. If convenient, the result should be placed in TARGET with
4895 mode MODE. */
4897 static rtx
4898 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4900 tree orig_arglist, dest, fmt;
4901 const char *fmt_str;
4903 orig_arglist = arglist;
4905 /* Verify the required arguments in the original call. */
4906 if (! arglist)
4907 return 0;
4908 dest = TREE_VALUE (arglist);
4909 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4910 return 0;
4911 arglist = TREE_CHAIN (arglist);
4912 if (! arglist)
4913 return 0;
4914 fmt = TREE_VALUE (arglist);
4915 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4916 return 0;
4917 arglist = TREE_CHAIN (arglist);
4919 /* Check whether the format is a literal string constant. */
4920 fmt_str = c_getstr (fmt);
4921 if (fmt_str == NULL)
4922 return 0;
4924 /* If the format doesn't contain % args or %%, use strcpy. */
4925 if (strchr (fmt_str, '%') == 0)
4927 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4928 tree exp;
4930 if (arglist || ! fn)
4931 return 0;
4932 expand_expr (build_function_call_expr (fn, orig_arglist),
4933 const0_rtx, VOIDmode, EXPAND_NORMAL);
4934 if (target == const0_rtx)
4935 return const0_rtx;
4936 exp = build_int_2 (strlen (fmt_str), 0);
4937 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4938 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4940 /* If the format is "%s", use strcpy if the result isn't used. */
4941 else if (strcmp (fmt_str, "%s") == 0)
4943 tree fn, arg, len;
4944 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4946 if (! fn)
4947 return 0;
4949 if (! arglist || TREE_CHAIN (arglist))
4950 return 0;
4951 arg = TREE_VALUE (arglist);
4952 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4953 return 0;
4955 if (target != const0_rtx)
4957 len = c_strlen (arg, 1);
4958 if (! len || TREE_CODE (len) != INTEGER_CST)
4959 return 0;
4961 else
4962 len = NULL_TREE;
4964 arglist = build_tree_list (NULL_TREE, arg);
4965 arglist = tree_cons (NULL_TREE, dest, arglist);
4966 expand_expr (build_function_call_expr (fn, arglist),
4967 const0_rtx, VOIDmode, EXPAND_NORMAL);
4969 if (target == const0_rtx)
4970 return const0_rtx;
4971 return expand_expr (len, target, mode, EXPAND_NORMAL);
4974 return 0;
4977 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4978 Return NULL_RTX if a normal call should be emitted rather than expanding
4979 the function in-line. EXP is the expression that is a call to the builtin
4980 function; if convenient, the result should be placed in TARGET. */
4982 static rtx
4983 expand_builtin_signbit (tree exp, rtx target)
4985 const struct real_format *fmt;
4986 enum machine_mode fmode, imode, rmode;
4987 HOST_WIDE_INT hi, lo;
4988 tree arg, arglist;
4989 int bitpos;
4990 rtx temp;
4992 arglist = TREE_OPERAND (exp, 1);
4993 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4994 return 0;
4996 arg = TREE_VALUE (arglist);
4997 fmode = TYPE_MODE (TREE_TYPE (arg));
4998 rmode = TYPE_MODE (TREE_TYPE (exp));
4999 fmt = REAL_MODE_FORMAT (fmode);
5001 /* For floating point formats without a sign bit, implement signbit
5002 as "ARG < 0.0". */
5003 if (fmt->signbit < 0)
5005 /* But we can't do this if the format supports signed zero. */
5006 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5007 return 0;
5009 arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
5010 build_real (TREE_TYPE (arg), dconst0)));
5011 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5014 imode = int_mode_for_mode (fmode);
5015 if (imode == BLKmode)
5016 return 0;
5018 bitpos = fmt->signbit;
5019 /* Handle targets with different FP word orders. */
5020 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5022 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5023 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5024 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5027 /* If the sign bit is not in the lowpart and the floating point format
5028 is wider than an integer, check that is twice the size of an integer
5029 so that we can use gen_highpart below. */
5030 if (bitpos >= GET_MODE_BITSIZE (rmode)
5031 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5032 return 0;
5034 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5035 temp = gen_lowpart (imode, temp);
5037 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5039 if (BITS_BIG_ENDIAN)
5040 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5041 temp = copy_to_mode_reg (imode, temp);
5042 temp = extract_bit_field (temp, 1, bitpos, 1,
5043 NULL_RTX, rmode, rmode,
5044 GET_MODE_SIZE (imode));
5046 else
5048 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5049 temp = gen_lowpart (rmode, temp);
5050 if (bitpos < HOST_BITS_PER_WIDE_INT)
5052 hi = 0;
5053 lo = (HOST_WIDE_INT) 1 << bitpos;
5055 else
5057 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5058 lo = 0;
5061 temp = force_reg (rmode, temp);
5062 temp = expand_binop (rmode, and_optab, temp,
5063 immed_double_const (lo, hi, rmode),
5064 target, 1, OPTAB_LIB_WIDEN);
5066 return temp;
5069 /* Expand an expression EXP that calls a built-in function,
5070 with result going to TARGET if that's convenient
5071 (and in mode MODE if that's convenient).
5072 SUBTARGET may be used as the target for computing one of EXP's operands.
5073 IGNORE is nonzero if the value is to be ignored. */
5076 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5077 int ignore)
5079 tree fndecl = get_callee_fndecl (exp);
5080 tree arglist = TREE_OPERAND (exp, 1);
5081 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5082 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5084 /* Perform postincrements before expanding builtin functions. */
5085 emit_queue ();
5087 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5088 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5090 /* When not optimizing, generate calls to library functions for a certain
5091 set of builtins. */
5092 if (!optimize
5093 && !CALLED_AS_BUILT_IN (fndecl)
5094 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5095 && fcode != BUILT_IN_ALLOCA)
5096 return expand_call (exp, target, ignore);
5098 /* The built-in function expanders test for target == const0_rtx
5099 to determine whether the function's result will be ignored. */
5100 if (ignore)
5101 target = const0_rtx;
5103 /* If the result of a pure or const built-in function is ignored, and
5104 none of its arguments are volatile, we can avoid expanding the
5105 built-in call and just evaluate the arguments for side-effects. */
5106 if (target == const0_rtx
5107 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5109 bool volatilep = false;
5110 tree arg;
5112 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5113 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5115 volatilep = true;
5116 break;
5119 if (! volatilep)
5121 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5122 expand_expr (TREE_VALUE (arg), const0_rtx,
5123 VOIDmode, EXPAND_NORMAL);
5124 return const0_rtx;
5128 switch (fcode)
5130 case BUILT_IN_ABS:
5131 case BUILT_IN_LABS:
5132 case BUILT_IN_LLABS:
5133 case BUILT_IN_IMAXABS:
5134 /* build_function_call changes these into ABS_EXPR. */
5135 abort ();
5137 case BUILT_IN_FABS:
5138 case BUILT_IN_FABSF:
5139 case BUILT_IN_FABSL:
5140 target = expand_builtin_fabs (arglist, target, subtarget);
5141 if (target)
5142 return target;
5143 break;
5145 case BUILT_IN_CABS:
5146 case BUILT_IN_CABSF:
5147 case BUILT_IN_CABSL:
5148 if (flag_unsafe_math_optimizations)
5150 target = expand_builtin_cabs (arglist, target);
5151 if (target)
5152 return target;
5154 break;
5156 case BUILT_IN_CONJ:
5157 case BUILT_IN_CONJF:
5158 case BUILT_IN_CONJL:
5159 case BUILT_IN_CREAL:
5160 case BUILT_IN_CREALF:
5161 case BUILT_IN_CREALL:
5162 case BUILT_IN_CIMAG:
5163 case BUILT_IN_CIMAGF:
5164 case BUILT_IN_CIMAGL:
5165 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5166 and IMAGPART_EXPR. */
5167 abort ();
5169 case BUILT_IN_EXP:
5170 case BUILT_IN_EXPF:
5171 case BUILT_IN_EXPL:
5172 case BUILT_IN_EXP10:
5173 case BUILT_IN_EXP10F:
5174 case BUILT_IN_EXP10L:
5175 case BUILT_IN_POW10:
5176 case BUILT_IN_POW10F:
5177 case BUILT_IN_POW10L:
5178 case BUILT_IN_EXP2:
5179 case BUILT_IN_EXP2F:
5180 case BUILT_IN_EXP2L:
5181 case BUILT_IN_LOG:
5182 case BUILT_IN_LOGF:
5183 case BUILT_IN_LOGL:
5184 case BUILT_IN_LOG10:
5185 case BUILT_IN_LOG10F:
5186 case BUILT_IN_LOG10L:
5187 case BUILT_IN_LOG2:
5188 case BUILT_IN_LOG2F:
5189 case BUILT_IN_LOG2L:
5190 case BUILT_IN_TAN:
5191 case BUILT_IN_TANF:
5192 case BUILT_IN_TANL:
5193 case BUILT_IN_ATAN:
5194 case BUILT_IN_ATANF:
5195 case BUILT_IN_ATANL:
5196 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5197 because of possible accuracy problems. */
5198 if (! flag_unsafe_math_optimizations)
5199 break;
5200 case BUILT_IN_SQRT:
5201 case BUILT_IN_SQRTF:
5202 case BUILT_IN_SQRTL:
5203 case BUILT_IN_FLOOR:
5204 case BUILT_IN_FLOORF:
5205 case BUILT_IN_FLOORL:
5206 case BUILT_IN_CEIL:
5207 case BUILT_IN_CEILF:
5208 case BUILT_IN_CEILL:
5209 case BUILT_IN_TRUNC:
5210 case BUILT_IN_TRUNCF:
5211 case BUILT_IN_TRUNCL:
5212 case BUILT_IN_ROUND:
5213 case BUILT_IN_ROUNDF:
5214 case BUILT_IN_ROUNDL:
5215 case BUILT_IN_NEARBYINT:
5216 case BUILT_IN_NEARBYINTF:
5217 case BUILT_IN_NEARBYINTL:
5218 target = expand_builtin_mathfn (exp, target, subtarget);
5219 if (target)
5220 return target;
5221 break;
5223 case BUILT_IN_POW:
5224 case BUILT_IN_POWF:
5225 case BUILT_IN_POWL:
5226 target = expand_builtin_pow (exp, target, subtarget);
5227 if (target)
5228 return target;
5229 break;
5231 case BUILT_IN_ATAN2:
5232 case BUILT_IN_ATAN2F:
5233 case BUILT_IN_ATAN2L:
5234 if (! flag_unsafe_math_optimizations)
5235 break;
5236 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5237 if (target)
5238 return target;
5239 break;
5241 case BUILT_IN_SIN:
5242 case BUILT_IN_SINF:
5243 case BUILT_IN_SINL:
5244 case BUILT_IN_COS:
5245 case BUILT_IN_COSF:
5246 case BUILT_IN_COSL:
5247 if (! flag_unsafe_math_optimizations)
5248 break;
5249 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5250 if (target)
5251 return target;
5252 break;
5254 case BUILT_IN_APPLY_ARGS:
5255 return expand_builtin_apply_args ();
5257 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5258 FUNCTION with a copy of the parameters described by
5259 ARGUMENTS, and ARGSIZE. It returns a block of memory
5260 allocated on the stack into which is stored all the registers
5261 that might possibly be used for returning the result of a
5262 function. ARGUMENTS is the value returned by
5263 __builtin_apply_args. ARGSIZE is the number of bytes of
5264 arguments that must be copied. ??? How should this value be
5265 computed? We'll also need a safe worst case value for varargs
5266 functions. */
5267 case BUILT_IN_APPLY:
5268 if (!validate_arglist (arglist, POINTER_TYPE,
5269 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5270 && !validate_arglist (arglist, REFERENCE_TYPE,
5271 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5272 return const0_rtx;
5273 else
5275 int i;
5276 tree t;
5277 rtx ops[3];
5279 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5280 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5282 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5285 /* __builtin_return (RESULT) causes the function to return the
5286 value described by RESULT. RESULT is address of the block of
5287 memory returned by __builtin_apply. */
5288 case BUILT_IN_RETURN:
5289 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5290 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5291 NULL_RTX, VOIDmode, 0));
5292 return const0_rtx;
5294 case BUILT_IN_SAVEREGS:
5295 return expand_builtin_saveregs ();
5297 case BUILT_IN_ARGS_INFO:
5298 return expand_builtin_args_info (arglist);
5300 /* Return the address of the first anonymous stack arg. */
5301 case BUILT_IN_NEXT_ARG:
5302 return expand_builtin_next_arg (arglist);
5304 case BUILT_IN_CLASSIFY_TYPE:
5305 return expand_builtin_classify_type (arglist);
5307 case BUILT_IN_CONSTANT_P:
5308 return expand_builtin_constant_p (arglist, target_mode);
5310 case BUILT_IN_FRAME_ADDRESS:
5311 case BUILT_IN_RETURN_ADDRESS:
5312 return expand_builtin_frame_address (fndecl, arglist);
5314 /* Returns the address of the area where the structure is returned.
5315 0 otherwise. */
5316 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5317 if (arglist != 0
5318 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5319 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5320 return const0_rtx;
5321 else
5322 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5324 case BUILT_IN_ALLOCA:
5325 target = expand_builtin_alloca (arglist, target);
5326 if (target)
5327 return target;
5328 break;
5330 case BUILT_IN_FFS:
5331 case BUILT_IN_FFSL:
5332 case BUILT_IN_FFSLL:
5333 target = expand_builtin_unop (target_mode, arglist, target,
5334 subtarget, ffs_optab);
5335 if (target)
5336 return target;
5337 break;
5339 case BUILT_IN_CLZ:
5340 case BUILT_IN_CLZL:
5341 case BUILT_IN_CLZLL:
5342 target = expand_builtin_unop (target_mode, arglist, target,
5343 subtarget, clz_optab);
5344 if (target)
5345 return target;
5346 break;
5348 case BUILT_IN_CTZ:
5349 case BUILT_IN_CTZL:
5350 case BUILT_IN_CTZLL:
5351 target = expand_builtin_unop (target_mode, arglist, target,
5352 subtarget, ctz_optab);
5353 if (target)
5354 return target;
5355 break;
5357 case BUILT_IN_POPCOUNT:
5358 case BUILT_IN_POPCOUNTL:
5359 case BUILT_IN_POPCOUNTLL:
5360 target = expand_builtin_unop (target_mode, arglist, target,
5361 subtarget, popcount_optab);
5362 if (target)
5363 return target;
5364 break;
5366 case BUILT_IN_PARITY:
5367 case BUILT_IN_PARITYL:
5368 case BUILT_IN_PARITYLL:
5369 target = expand_builtin_unop (target_mode, arglist, target,
5370 subtarget, parity_optab);
5371 if (target)
5372 return target;
5373 break;
5375 case BUILT_IN_STRLEN:
5376 target = expand_builtin_strlen (arglist, target, target_mode);
5377 if (target)
5378 return target;
5379 break;
5381 case BUILT_IN_STRCPY:
5382 target = expand_builtin_strcpy (arglist, target, mode);
5383 if (target)
5384 return target;
5385 break;
5387 case BUILT_IN_STRNCPY:
5388 target = expand_builtin_strncpy (arglist, target, mode);
5389 if (target)
5390 return target;
5391 break;
5393 case BUILT_IN_STPCPY:
5394 target = expand_builtin_stpcpy (arglist, target, mode);
5395 if (target)
5396 return target;
5397 break;
5399 case BUILT_IN_STRCAT:
5400 target = expand_builtin_strcat (arglist, target, mode);
5401 if (target)
5402 return target;
5403 break;
5405 case BUILT_IN_STRNCAT:
5406 target = expand_builtin_strncat (arglist, target, mode);
5407 if (target)
5408 return target;
5409 break;
5411 case BUILT_IN_STRSPN:
5412 target = expand_builtin_strspn (arglist, target, mode);
5413 if (target)
5414 return target;
5415 break;
5417 case BUILT_IN_STRCSPN:
5418 target = expand_builtin_strcspn (arglist, target, mode);
5419 if (target)
5420 return target;
5421 break;
5423 case BUILT_IN_STRSTR:
5424 target = expand_builtin_strstr (arglist, target, mode);
5425 if (target)
5426 return target;
5427 break;
5429 case BUILT_IN_STRPBRK:
5430 target = expand_builtin_strpbrk (arglist, target, mode);
5431 if (target)
5432 return target;
5433 break;
5435 case BUILT_IN_INDEX:
5436 case BUILT_IN_STRCHR:
5437 target = expand_builtin_strchr (arglist, target, mode);
5438 if (target)
5439 return target;
5440 break;
5442 case BUILT_IN_RINDEX:
5443 case BUILT_IN_STRRCHR:
5444 target = expand_builtin_strrchr (arglist, target, mode);
5445 if (target)
5446 return target;
5447 break;
5449 case BUILT_IN_MEMCPY:
5450 target = expand_builtin_memcpy (arglist, target, mode);
5451 if (target)
5452 return target;
5453 break;
5455 case BUILT_IN_MEMPCPY:
5456 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5457 if (target)
5458 return target;
5459 break;
5461 case BUILT_IN_MEMMOVE:
5462 target = expand_builtin_memmove (arglist, target, mode);
5463 if (target)
5464 return target;
5465 break;
5467 case BUILT_IN_BCOPY:
5468 target = expand_builtin_bcopy (arglist);
5469 if (target)
5470 return target;
5471 break;
5473 case BUILT_IN_MEMSET:
5474 target = expand_builtin_memset (arglist, target, mode);
5475 if (target)
5476 return target;
5477 break;
5479 case BUILT_IN_BZERO:
5480 target = expand_builtin_bzero (arglist);
5481 if (target)
5482 return target;
5483 break;
5485 case BUILT_IN_STRCMP:
5486 target = expand_builtin_strcmp (exp, target, mode);
5487 if (target)
5488 return target;
5489 break;
5491 case BUILT_IN_STRNCMP:
5492 target = expand_builtin_strncmp (exp, target, mode);
5493 if (target)
5494 return target;
5495 break;
5497 case BUILT_IN_BCMP:
5498 case BUILT_IN_MEMCMP:
5499 target = expand_builtin_memcmp (exp, arglist, target, mode);
5500 if (target)
5501 return target;
5502 break;
5504 case BUILT_IN_SETJMP:
5505 target = expand_builtin_setjmp (arglist, target);
5506 if (target)
5507 return target;
5508 break;
5510 /* __builtin_longjmp is passed a pointer to an array of five words.
5511 It's similar to the C library longjmp function but works with
5512 __builtin_setjmp above. */
5513 case BUILT_IN_LONGJMP:
5514 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5515 break;
5516 else
5518 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5519 VOIDmode, 0);
5520 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5521 NULL_RTX, VOIDmode, 0);
5523 if (value != const1_rtx)
5525 error ("__builtin_longjmp second argument must be 1");
5526 return const0_rtx;
5529 expand_builtin_longjmp (buf_addr, value);
5530 return const0_rtx;
5533 case BUILT_IN_TRAP:
5534 expand_builtin_trap ();
5535 return const0_rtx;
5537 case BUILT_IN_PRINTF:
5538 target = expand_builtin_printf (arglist, target, mode, false);
5539 if (target)
5540 return target;
5541 break;
5543 case BUILT_IN_PRINTF_UNLOCKED:
5544 target = expand_builtin_printf (arglist, target, mode, true);
5545 if (target)
5546 return target;
5547 break;
5549 case BUILT_IN_FPUTS:
5550 target = expand_builtin_fputs (arglist, target, false);
5551 if (target)
5552 return target;
5553 break;
5555 case BUILT_IN_FPUTS_UNLOCKED:
5556 target = expand_builtin_fputs (arglist, target, true);
5557 if (target)
5558 return target;
5559 break;
5561 case BUILT_IN_FPRINTF:
5562 target = expand_builtin_fprintf (arglist, target, mode, false);
5563 if (target)
5564 return target;
5565 break;
5567 case BUILT_IN_FPRINTF_UNLOCKED:
5568 target = expand_builtin_fprintf (arglist, target, mode, true);
5569 if (target)
5570 return target;
5571 break;
5573 case BUILT_IN_SPRINTF:
5574 target = expand_builtin_sprintf (arglist, target, mode);
5575 if (target)
5576 return target;
5577 break;
5579 case BUILT_IN_SIGNBIT:
5580 case BUILT_IN_SIGNBITF:
5581 case BUILT_IN_SIGNBITL:
5582 target = expand_builtin_signbit (exp, target);
5583 if (target)
5584 return target;
5585 break;
5587 /* Various hooks for the DWARF 2 __throw routine. */
5588 case BUILT_IN_UNWIND_INIT:
5589 expand_builtin_unwind_init ();
5590 return const0_rtx;
5591 case BUILT_IN_DWARF_CFA:
5592 return virtual_cfa_rtx;
5593 #ifdef DWARF2_UNWIND_INFO
5594 case BUILT_IN_DWARF_SP_COLUMN:
5595 return expand_builtin_dwarf_sp_column ();
5596 case BUILT_IN_INIT_DWARF_REG_SIZES:
5597 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5598 return const0_rtx;
5599 #endif
5600 case BUILT_IN_FROB_RETURN_ADDR:
5601 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5602 case BUILT_IN_EXTRACT_RETURN_ADDR:
5603 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5604 case BUILT_IN_EH_RETURN:
5605 expand_builtin_eh_return (TREE_VALUE (arglist),
5606 TREE_VALUE (TREE_CHAIN (arglist)));
5607 return const0_rtx;
5608 #ifdef EH_RETURN_DATA_REGNO
5609 case BUILT_IN_EH_RETURN_DATA_REGNO:
5610 return expand_builtin_eh_return_data_regno (arglist);
5611 #endif
5612 case BUILT_IN_EXTEND_POINTER:
5613 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5615 case BUILT_IN_VA_START:
5616 case BUILT_IN_STDARG_START:
5617 return expand_builtin_va_start (arglist);
5618 case BUILT_IN_VA_END:
5619 return expand_builtin_va_end (arglist);
5620 case BUILT_IN_VA_COPY:
5621 return expand_builtin_va_copy (arglist);
5622 case BUILT_IN_EXPECT:
5623 return expand_builtin_expect (arglist, target);
5624 case BUILT_IN_PREFETCH:
5625 expand_builtin_prefetch (arglist);
5626 return const0_rtx;
5629 default: /* just do library call, if unknown builtin */
5630 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5631 error ("built-in function `%s' not currently supported",
5632 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5635 /* The switch statement above can drop through to cause the function
5636 to be called normally. */
5637 return expand_call (exp, target, ignore);
5640 /* Determine whether a tree node represents a call to a built-in
5641 function. If the tree T is a call to a built-in function with
5642 the right number of arguments of the appropriate types, return
5643 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5644 Otherwise the return value is END_BUILTINS. */
5646 enum built_in_function
5647 builtin_mathfn_code (tree t)
5649 tree fndecl, arglist, parmlist;
5650 tree argtype, parmtype;
5652 if (TREE_CODE (t) != CALL_EXPR
5653 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5654 return END_BUILTINS;
5656 fndecl = get_callee_fndecl (t);
5657 if (fndecl == NULL_TREE
5658 || TREE_CODE (fndecl) != FUNCTION_DECL
5659 || ! DECL_BUILT_IN (fndecl)
5660 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5661 return END_BUILTINS;
5663 arglist = TREE_OPERAND (t, 1);
5664 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5665 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5667 /* If a function doesn't take a variable number of arguments,
5668 the last element in the list will have type `void'. */
5669 parmtype = TREE_VALUE (parmlist);
5670 if (VOID_TYPE_P (parmtype))
5672 if (arglist)
5673 return END_BUILTINS;
5674 return DECL_FUNCTION_CODE (fndecl);
5677 if (! arglist)
5678 return END_BUILTINS;
5680 argtype = TREE_TYPE (TREE_VALUE (arglist));
5682 if (SCALAR_FLOAT_TYPE_P (parmtype))
5684 if (! SCALAR_FLOAT_TYPE_P (argtype))
5685 return END_BUILTINS;
5687 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5689 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5690 return END_BUILTINS;
5692 else if (POINTER_TYPE_P (parmtype))
5694 if (! POINTER_TYPE_P (argtype))
5695 return END_BUILTINS;
5697 else if (INTEGRAL_TYPE_P (parmtype))
5699 if (! INTEGRAL_TYPE_P (argtype))
5700 return END_BUILTINS;
5702 else
5703 return END_BUILTINS;
5705 arglist = TREE_CHAIN (arglist);
5708 /* Variable-length argument list. */
5709 return DECL_FUNCTION_CODE (fndecl);
5712 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5713 constant. ARGLIST is the argument list of the call. */
5715 static tree
5716 fold_builtin_constant_p (tree arglist)
5718 if (arglist == 0)
5719 return 0;
5721 arglist = TREE_VALUE (arglist);
5723 /* We return 1 for a numeric type that's known to be a constant
5724 value at compile-time or for an aggregate type that's a
5725 literal constant. */
5726 STRIP_NOPS (arglist);
5728 /* If we know this is a constant, emit the constant of one. */
5729 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5730 || (TREE_CODE (arglist) == CONSTRUCTOR
5731 && TREE_CONSTANT (arglist))
5732 || (TREE_CODE (arglist) == ADDR_EXPR
5733 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5734 return integer_one_node;
5736 /* If this expression has side effects, show we don't know it to be a
5737 constant. Likewise if it's a pointer or aggregate type since in
5738 those case we only want literals, since those are only optimized
5739 when generating RTL, not later.
5740 And finally, if we are compiling an initializer, not code, we
5741 need to return a definite result now; there's not going to be any
5742 more optimization done. */
5743 if (TREE_SIDE_EFFECTS (arglist)
5744 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5745 || POINTER_TYPE_P (TREE_TYPE (arglist))
5746 || cfun == 0)
5747 return integer_zero_node;
5749 return 0;
5752 /* Fold a call to __builtin_classify_type. */
5754 static tree
5755 fold_builtin_classify_type (tree arglist)
5757 if (arglist == 0)
5758 return build_int_2 (no_type_class, 0);
5760 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5763 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5765 static tree
5766 fold_builtin_inf (tree type, int warn)
5768 REAL_VALUE_TYPE real;
5770 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5771 warning ("target format does not support infinity");
5773 real_inf (&real);
5774 return build_real (type, real);
5777 /* Fold a call to __builtin_nan or __builtin_nans. */
5779 static tree
5780 fold_builtin_nan (tree arglist, tree type, int quiet)
5782 REAL_VALUE_TYPE real;
5783 const char *str;
5785 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5786 return 0;
5787 str = c_getstr (TREE_VALUE (arglist));
5788 if (!str)
5789 return 0;
5791 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5792 return 0;
5794 return build_real (type, real);
5797 /* Return true if the floating point expression T has an integer value.
5798 We also allow +Inf, -Inf and NaN to be considered integer values. */
5800 static bool
5801 integer_valued_real_p (tree t)
5803 switch (TREE_CODE (t))
5805 case FLOAT_EXPR:
5806 return true;
5808 case ABS_EXPR:
5809 case SAVE_EXPR:
5810 case NON_LVALUE_EXPR:
5811 return integer_valued_real_p (TREE_OPERAND (t, 0));
5813 case COMPOUND_EXPR:
5814 case MODIFY_EXPR:
5815 case BIND_EXPR:
5816 return integer_valued_real_p (TREE_OPERAND (t, 1));
5818 case PLUS_EXPR:
5819 case MINUS_EXPR:
5820 case MULT_EXPR:
5821 case MIN_EXPR:
5822 case MAX_EXPR:
5823 return integer_valued_real_p (TREE_OPERAND (t, 0))
5824 && integer_valued_real_p (TREE_OPERAND (t, 1));
5826 case COND_EXPR:
5827 return integer_valued_real_p (TREE_OPERAND (t, 1))
5828 && integer_valued_real_p (TREE_OPERAND (t, 2));
5830 case REAL_CST:
5831 if (! TREE_CONSTANT_OVERFLOW (t))
5833 REAL_VALUE_TYPE c, cint;
5835 c = TREE_REAL_CST (t);
5836 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5837 return real_identical (&c, &cint);
5840 case NOP_EXPR:
5842 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5843 if (TREE_CODE (type) == INTEGER_TYPE)
5844 return true;
5845 if (TREE_CODE (type) == REAL_TYPE)
5846 return integer_valued_real_p (TREE_OPERAND (t, 0));
5847 break;
5850 case CALL_EXPR:
5851 switch (builtin_mathfn_code (t))
5853 case BUILT_IN_CEIL:
5854 case BUILT_IN_CEILF:
5855 case BUILT_IN_CEILL:
5856 case BUILT_IN_FLOOR:
5857 case BUILT_IN_FLOORF:
5858 case BUILT_IN_FLOORL:
5859 case BUILT_IN_NEARBYINT:
5860 case BUILT_IN_NEARBYINTF:
5861 case BUILT_IN_NEARBYINTL:
5862 case BUILT_IN_RINT:
5863 case BUILT_IN_RINTF:
5864 case BUILT_IN_RINTL:
5865 case BUILT_IN_ROUND:
5866 case BUILT_IN_ROUNDF:
5867 case BUILT_IN_ROUNDL:
5868 case BUILT_IN_TRUNC:
5869 case BUILT_IN_TRUNCF:
5870 case BUILT_IN_TRUNCL:
5871 return true;
5873 default:
5874 break;
5876 break;
5878 default:
5879 break;
5881 return false;
5884 /* EXP is assumed to be builtin call where truncation can be propagated
5885 across (for instance floor((double)f) == (double)floorf (f).
5886 Do the transformation. */
5888 static tree
5889 fold_trunc_transparent_mathfn (tree exp)
5891 tree fndecl = get_callee_fndecl (exp);
5892 tree arglist = TREE_OPERAND (exp, 1);
5893 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5894 tree arg;
5896 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5897 return 0;
5899 arg = TREE_VALUE (arglist);
5900 /* Integer rounding functions are idempotent. */
5901 if (fcode == builtin_mathfn_code (arg))
5902 return arg;
5904 /* If argument is already integer valued, and we don't need to worry
5905 about setting errno, there's no need to perform rounding. */
5906 if (! flag_errno_math && integer_valued_real_p (arg))
5907 return arg;
5909 if (optimize)
5911 tree arg0 = strip_float_extensions (arg);
5912 tree ftype = TREE_TYPE (exp);
5913 tree newtype = TREE_TYPE (arg0);
5914 tree decl;
5916 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5917 && (decl = mathfn_built_in (newtype, fcode)))
5919 arglist =
5920 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5921 return convert (ftype,
5922 build_function_call_expr (decl, arglist));
5925 return 0;
5928 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5929 function's DECL, ARGLIST is the argument list and TYPE is the return
5930 type. Return NULL_TREE if no simplification can be made. */
5932 static tree
5933 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5935 tree arg;
5937 if (!arglist || TREE_CHAIN (arglist))
5938 return NULL_TREE;
5940 arg = TREE_VALUE (arglist);
5941 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5942 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5943 return NULL_TREE;
5945 /* Evaluate cabs of a constant at compile-time. */
5946 if (flag_unsafe_math_optimizations
5947 && TREE_CODE (arg) == COMPLEX_CST
5948 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5949 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5950 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5951 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5953 REAL_VALUE_TYPE r, i;
5955 r = TREE_REAL_CST (TREE_REALPART (arg));
5956 i = TREE_REAL_CST (TREE_IMAGPART (arg));
5958 real_arithmetic (&r, MULT_EXPR, &r, &r);
5959 real_arithmetic (&i, MULT_EXPR, &i, &i);
5960 real_arithmetic (&r, PLUS_EXPR, &r, &i);
5961 if (real_sqrt (&r, TYPE_MODE (type), &r)
5962 || ! flag_trapping_math)
5963 return build_real (type, r);
5966 /* If either part is zero, cabs is fabs of the other. */
5967 if (TREE_CODE (arg) == COMPLEX_EXPR
5968 && real_zerop (TREE_OPERAND (arg, 0)))
5969 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5970 if (TREE_CODE (arg) == COMPLEX_EXPR
5971 && real_zerop (TREE_OPERAND (arg, 1)))
5972 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5974 if (flag_unsafe_math_optimizations)
5976 enum built_in_function fcode;
5977 tree sqrtfn;
5979 fcode = DECL_FUNCTION_CODE (fndecl);
5980 if (fcode == BUILT_IN_CABS)
5981 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5982 else if (fcode == BUILT_IN_CABSF)
5983 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5984 else if (fcode == BUILT_IN_CABSL)
5985 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5986 else
5987 sqrtfn = NULL_TREE;
5989 if (sqrtfn != NULL_TREE)
5991 tree rpart, ipart, result, arglist;
5993 arg = save_expr (arg);
5995 rpart = fold (build1 (REALPART_EXPR, type, arg));
5996 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5998 rpart = save_expr (rpart);
5999 ipart = save_expr (ipart);
6001 result = fold (build (PLUS_EXPR, type,
6002 fold (build (MULT_EXPR, type,
6003 rpart, rpart)),
6004 fold (build (MULT_EXPR, type,
6005 ipart, ipart))));
6007 arglist = build_tree_list (NULL_TREE, result);
6008 return build_function_call_expr (sqrtfn, arglist);
6012 return NULL_TREE;
6015 /* Fold function call to builtin trunc, truncf or truncl. Return
6016 NULL_TREE if no simplification can be made. */
6018 static tree
6019 fold_builtin_trunc (tree exp)
6021 tree arglist = TREE_OPERAND (exp, 1);
6022 tree arg;
6024 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6025 return 0;
6027 /* Optimize trunc of constant value. */
6028 arg = TREE_VALUE (arglist);
6029 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6031 REAL_VALUE_TYPE r, x;
6032 tree type = TREE_TYPE (exp);
6034 x = TREE_REAL_CST (arg);
6035 real_trunc (&r, TYPE_MODE (type), &x);
6036 return build_real (type, r);
6039 return fold_trunc_transparent_mathfn (exp);
6042 /* Fold function call to builtin floor, floorf or floorl. Return
6043 NULL_TREE if no simplification can be made. */
6045 static tree
6046 fold_builtin_floor (tree exp)
6048 tree arglist = TREE_OPERAND (exp, 1);
6049 tree arg;
6051 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6052 return 0;
6054 /* Optimize floor of constant value. */
6055 arg = TREE_VALUE (arglist);
6056 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6058 REAL_VALUE_TYPE x;
6060 x = TREE_REAL_CST (arg);
6061 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6063 tree type = TREE_TYPE (exp);
6064 REAL_VALUE_TYPE r;
6066 real_floor (&r, TYPE_MODE (type), &x);
6067 return build_real (type, r);
6071 return fold_trunc_transparent_mathfn (exp);
6074 /* Fold function call to builtin ceil, ceilf or ceill. Return
6075 NULL_TREE if no simplification can be made. */
6077 static tree
6078 fold_builtin_ceil (tree exp)
6080 tree arglist = TREE_OPERAND (exp, 1);
6081 tree arg;
6083 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6084 return 0;
6086 /* Optimize ceil of constant value. */
6087 arg = TREE_VALUE (arglist);
6088 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6090 REAL_VALUE_TYPE x;
6092 x = TREE_REAL_CST (arg);
6093 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6095 tree type = TREE_TYPE (exp);
6096 REAL_VALUE_TYPE r;
6098 real_ceil (&r, TYPE_MODE (type), &x);
6099 return build_real (type, r);
6103 return fold_trunc_transparent_mathfn (exp);
6106 /* Fold function call to builtin round, roundf or roundl. Return
6107 NULL_TREE if no simplification can be made. */
6109 static tree
6110 fold_builtin_round (tree exp)
6112 tree arglist = TREE_OPERAND (exp, 1);
6113 tree arg;
6115 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6116 return 0;
6118 /* Optimize ceil of constant value. */
6119 arg = TREE_VALUE (arglist);
6120 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6122 REAL_VALUE_TYPE x;
6124 x = TREE_REAL_CST (arg);
6125 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6127 tree type = TREE_TYPE (exp);
6128 REAL_VALUE_TYPE r;
6130 real_round (&r, TYPE_MODE (type), &x);
6131 return build_real (type, r);
6135 return fold_trunc_transparent_mathfn (exp);
6138 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6139 and their long and long long variants (i.e. ffsl and ffsll).
6140 Return NULL_TREE if no simplification can be made. */
6142 static tree
6143 fold_builtin_bitop (tree exp)
6145 tree fndecl = get_callee_fndecl (exp);
6146 tree arglist = TREE_OPERAND (exp, 1);
6147 tree arg;
6149 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6150 return NULL_TREE;
6152 /* Optimize for constant argument. */
6153 arg = TREE_VALUE (arglist);
6154 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6156 HOST_WIDE_INT hi, width, result;
6157 unsigned HOST_WIDE_INT lo;
6158 tree type, t;
6160 type = TREE_TYPE (arg);
6161 width = TYPE_PRECISION (type);
6162 lo = TREE_INT_CST_LOW (arg);
6164 /* Clear all the bits that are beyond the type's precision. */
6165 if (width > HOST_BITS_PER_WIDE_INT)
6167 hi = TREE_INT_CST_HIGH (arg);
6168 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6169 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6171 else
6173 hi = 0;
6174 if (width < HOST_BITS_PER_WIDE_INT)
6175 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6178 switch (DECL_FUNCTION_CODE (fndecl))
6180 case BUILT_IN_FFS:
6181 case BUILT_IN_FFSL:
6182 case BUILT_IN_FFSLL:
6183 if (lo != 0)
6184 result = exact_log2 (lo & -lo) + 1;
6185 else if (hi != 0)
6186 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6187 else
6188 result = 0;
6189 break;
6191 case BUILT_IN_CLZ:
6192 case BUILT_IN_CLZL:
6193 case BUILT_IN_CLZLL:
6194 if (hi != 0)
6195 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6196 else if (lo != 0)
6197 result = width - floor_log2 (lo) - 1;
6198 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6199 result = width;
6200 break;
6202 case BUILT_IN_CTZ:
6203 case BUILT_IN_CTZL:
6204 case BUILT_IN_CTZLL:
6205 if (lo != 0)
6206 result = exact_log2 (lo & -lo);
6207 else if (hi != 0)
6208 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6209 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6210 result = width;
6211 break;
6213 case BUILT_IN_POPCOUNT:
6214 case BUILT_IN_POPCOUNTL:
6215 case BUILT_IN_POPCOUNTLL:
6216 result = 0;
6217 while (lo)
6218 result++, lo &= lo - 1;
6219 while (hi)
6220 result++, hi &= hi - 1;
6221 break;
6223 case BUILT_IN_PARITY:
6224 case BUILT_IN_PARITYL:
6225 case BUILT_IN_PARITYLL:
6226 result = 0;
6227 while (lo)
6228 result++, lo &= lo - 1;
6229 while (hi)
6230 result++, hi &= hi - 1;
6231 result &= 1;
6232 break;
6234 default:
6235 abort();
6238 t = build_int_2 (result, 0);
6239 TREE_TYPE (t) = TREE_TYPE (exp);
6240 return t;
6243 return NULL_TREE;
6246 /* Return true if EXPR is the real constant contained in VALUE. */
6248 static bool
6249 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6251 STRIP_NOPS (expr);
6253 return ((TREE_CODE (expr) == REAL_CST
6254 && ! TREE_CONSTANT_OVERFLOW (expr)
6255 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6256 || (TREE_CODE (expr) == COMPLEX_CST
6257 && real_dconstp (TREE_REALPART (expr), value)
6258 && real_zerop (TREE_IMAGPART (expr))));
6261 /* A subroutine of fold_builtin to fold the various logarithmic
6262 functions. EXP is the CALL_EXPR of a call to a builtin logN
6263 function. VALUE is the base of the logN function. */
6265 static tree
6266 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6268 tree arglist = TREE_OPERAND (exp, 1);
6270 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6272 tree fndecl = get_callee_fndecl (exp);
6273 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6274 tree arg = TREE_VALUE (arglist);
6275 const enum built_in_function fcode = builtin_mathfn_code (arg);
6277 /* Optimize logN(1.0) = 0.0. */
6278 if (real_onep (arg))
6279 return build_real (type, dconst0);
6281 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6282 exactly, then only do this if flag_unsafe_math_optimizations. */
6283 if (exact_real_truncate (TYPE_MODE (type), value)
6284 || flag_unsafe_math_optimizations)
6286 const REAL_VALUE_TYPE value_truncate =
6287 real_value_truncate (TYPE_MODE (type), *value);
6288 if (real_dconstp (arg, &value_truncate))
6289 return build_real (type, dconst1);
6292 /* Special case, optimize logN(expN(x)) = x. */
6293 if (flag_unsafe_math_optimizations
6294 && ((value == &dconste
6295 && (fcode == BUILT_IN_EXP
6296 || fcode == BUILT_IN_EXPF
6297 || fcode == BUILT_IN_EXPL))
6298 || (value == &dconst2
6299 && (fcode == BUILT_IN_EXP2
6300 || fcode == BUILT_IN_EXP2F
6301 || fcode == BUILT_IN_EXP2L))
6302 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6303 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6305 /* Optimize logN(func()) for various exponential functions. We
6306 want to determine the value "x" and the power "exponent" in
6307 order to transform logN(x**exponent) into exponent*logN(x). */
6308 if (flag_unsafe_math_optimizations)
6310 tree exponent = 0, x = 0;
6312 switch (fcode)
6314 case BUILT_IN_EXP:
6315 case BUILT_IN_EXPF:
6316 case BUILT_IN_EXPL:
6317 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6318 x = build_real (type,
6319 real_value_truncate (TYPE_MODE (type), dconste));
6320 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6321 break;
6322 case BUILT_IN_EXP2:
6323 case BUILT_IN_EXP2F:
6324 case BUILT_IN_EXP2L:
6325 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6326 x = build_real (type, dconst2);
6327 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6328 break;
6329 case BUILT_IN_EXP10:
6330 case BUILT_IN_EXP10F:
6331 case BUILT_IN_EXP10L:
6332 case BUILT_IN_POW10:
6333 case BUILT_IN_POW10F:
6334 case BUILT_IN_POW10L:
6335 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6336 x = build_real (type, dconst10);
6337 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6338 break;
6339 case BUILT_IN_SQRT:
6340 case BUILT_IN_SQRTF:
6341 case BUILT_IN_SQRTL:
6342 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6343 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6344 exponent = build_real (type, dconsthalf);
6345 break;
6346 case BUILT_IN_CBRT:
6347 case BUILT_IN_CBRTF:
6348 case BUILT_IN_CBRTL:
6349 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6350 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6351 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6352 dconstthird));
6353 break;
6354 case BUILT_IN_POW:
6355 case BUILT_IN_POWF:
6356 case BUILT_IN_POWL:
6357 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6358 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6359 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6360 break;
6361 default:
6362 break;
6365 /* Now perform the optimization. */
6366 if (x && exponent)
6368 tree logfn;
6369 arglist = build_tree_list (NULL_TREE, x);
6370 logfn = build_function_call_expr (fndecl, arglist);
6371 return fold (build (MULT_EXPR, type, exponent, logfn));
6376 return 0;
6379 /* A subroutine of fold_builtin to fold the various exponent
6380 functions. EXP is the CALL_EXPR of a call to a builtin function.
6381 VALUE is the value which will be raised to a power. */
6383 static tree
6384 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6386 tree arglist = TREE_OPERAND (exp, 1);
6388 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6390 tree fndecl = get_callee_fndecl (exp);
6391 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6392 tree arg = TREE_VALUE (arglist);
6394 /* Optimize exp*(0.0) = 1.0. */
6395 if (real_zerop (arg))
6396 return build_real (type, dconst1);
6398 /* Optimize expN(1.0) = N. */
6399 if (real_onep (arg))
6401 REAL_VALUE_TYPE cst;
6403 real_convert (&cst, TYPE_MODE (type), value);
6404 return build_real (type, cst);
6407 /* Attempt to evaluate expN(integer) at compile-time. */
6408 if (flag_unsafe_math_optimizations
6409 && TREE_CODE (arg) == REAL_CST
6410 && ! TREE_CONSTANT_OVERFLOW (arg))
6412 REAL_VALUE_TYPE cint;
6413 REAL_VALUE_TYPE c;
6414 HOST_WIDE_INT n;
6416 c = TREE_REAL_CST (arg);
6417 n = real_to_integer (&c);
6418 real_from_integer (&cint, VOIDmode, n,
6419 n < 0 ? -1 : 0, 0);
6420 if (real_identical (&c, &cint))
6422 REAL_VALUE_TYPE x;
6424 real_powi (&x, TYPE_MODE (type), value, n);
6425 return build_real (type, x);
6429 /* Optimize expN(logN(x)) = x. */
6430 if (flag_unsafe_math_optimizations)
6432 const enum built_in_function fcode = builtin_mathfn_code (arg);
6434 if ((value == &dconste
6435 && (fcode == BUILT_IN_LOG
6436 || fcode == BUILT_IN_LOGF
6437 || fcode == BUILT_IN_LOGL))
6438 || (value == &dconst2
6439 && (fcode == BUILT_IN_LOG2
6440 || fcode == BUILT_IN_LOG2F
6441 || fcode == BUILT_IN_LOG2L))
6442 || (value == &dconst10
6443 && (fcode == BUILT_IN_LOG10
6444 || fcode == BUILT_IN_LOG10F
6445 || fcode == BUILT_IN_LOG10L)))
6446 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6450 return 0;
6453 /* Fold function call to builtin memcpy. Return
6454 NULL_TREE if no simplification can be made. */
6456 static tree
6457 fold_builtin_memcpy (tree exp)
6459 tree arglist = TREE_OPERAND (exp, 1);
6460 tree dest, src, len;
6462 if (!validate_arglist (arglist,
6463 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6464 return 0;
6466 dest = TREE_VALUE (arglist);
6467 src = TREE_VALUE (TREE_CHAIN (arglist));
6468 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6470 /* If the LEN parameter is zero, return DEST. */
6471 if (integer_zerop (len))
6472 return omit_one_operand (TREE_TYPE (exp), dest, src);
6474 /* If SRC and DEST are the same (and not volatile), return DEST. */
6475 if (operand_equal_p (src, dest, 0))
6476 return omit_one_operand (TREE_TYPE (exp), dest, len);
6478 return 0;
6481 /* Fold function call to builtin mempcpy. Return
6482 NULL_TREE if no simplification can be made. */
6484 static tree
6485 fold_builtin_mempcpy (tree exp)
6487 tree arglist = TREE_OPERAND (exp, 1);
6488 tree dest, src, len;
6490 if (!validate_arglist (arglist,
6491 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6492 return 0;
6494 dest = TREE_VALUE (arglist);
6495 src = TREE_VALUE (TREE_CHAIN (arglist));
6496 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6498 /* If the LEN parameter is zero, return DEST. */
6499 if (integer_zerop (len))
6500 return omit_one_operand (TREE_TYPE (exp), dest, src);
6502 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6503 if (operand_equal_p (src, dest, 0))
6505 tree temp = convert (TREE_TYPE (dest), len);
6506 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6507 return convert (TREE_TYPE (exp), temp);
6510 return 0;
6513 /* Fold function call to builtin memmove. Return
6514 NULL_TREE if no simplification can be made. */
6516 static tree
6517 fold_builtin_memmove (tree exp)
6519 tree arglist = TREE_OPERAND (exp, 1);
6520 tree dest, src, len;
6522 if (!validate_arglist (arglist,
6523 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6524 return 0;
6526 dest = TREE_VALUE (arglist);
6527 src = TREE_VALUE (TREE_CHAIN (arglist));
6528 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6530 /* If the LEN parameter is zero, return DEST. */
6531 if (integer_zerop (len))
6532 return omit_one_operand (TREE_TYPE (exp), dest, src);
6534 /* If SRC and DEST are the same (and not volatile), return DEST. */
6535 if (operand_equal_p (src, dest, 0))
6536 return omit_one_operand (TREE_TYPE (exp), dest, len);
6538 return 0;
6541 /* Fold function call to builtin strcpy. Return
6542 NULL_TREE if no simplification can be made. */
6544 static tree
6545 fold_builtin_strcpy (tree exp)
6547 tree arglist = TREE_OPERAND (exp, 1);
6548 tree dest, src;
6550 if (!validate_arglist (arglist,
6551 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6552 return 0;
6554 dest = TREE_VALUE (arglist);
6555 src = TREE_VALUE (TREE_CHAIN (arglist));
6557 /* If SRC and DEST are the same (and not volatile), return DEST. */
6558 if (operand_equal_p (src, dest, 0))
6559 return convert (TREE_TYPE (exp), dest);
6561 return 0;
6564 /* Fold function call to builtin strncpy. Return
6565 NULL_TREE if no simplification can be made. */
6567 static tree
6568 fold_builtin_strncpy (tree exp)
6570 tree arglist = TREE_OPERAND (exp, 1);
6571 tree dest, src, len;
6573 if (!validate_arglist (arglist,
6574 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6575 return 0;
6577 dest = TREE_VALUE (arglist);
6578 src = TREE_VALUE (TREE_CHAIN (arglist));
6579 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6581 /* If the LEN parameter is zero, return DEST. */
6582 if (integer_zerop (len))
6583 return omit_one_operand (TREE_TYPE (exp), dest, src);
6585 return 0;
6588 /* Fold function call to builtin memcmp. Return
6589 NULL_TREE if no simplification can be made. */
6591 static tree
6592 fold_builtin_memcmp (tree exp)
6594 tree arglist = TREE_OPERAND (exp, 1);
6595 tree arg1, arg2, len;
6597 if (!validate_arglist (arglist,
6598 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6599 return 0;
6601 arg1 = TREE_VALUE (arglist);
6602 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6603 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6605 /* If the LEN parameter is zero, return zero. */
6606 if (integer_zerop (len))
6608 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6609 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6612 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6613 if (operand_equal_p (arg1, arg2, 0))
6614 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6616 return 0;
6619 /* Fold function call to builtin strcmp. Return
6620 NULL_TREE if no simplification can be made. */
6622 static tree
6623 fold_builtin_strcmp (tree exp)
6625 tree arglist = TREE_OPERAND (exp, 1);
6626 tree arg1, arg2;
6627 const char *p1, *p2;
6629 if (!validate_arglist (arglist,
6630 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6631 return 0;
6633 arg1 = TREE_VALUE (arglist);
6634 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6636 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6637 if (operand_equal_p (arg1, arg2, 0))
6638 return convert (TREE_TYPE (exp), integer_zero_node);
6640 p1 = c_getstr (arg1);
6641 p2 = c_getstr (arg2);
6643 if (p1 && p2)
6645 tree temp;
6646 const int i = strcmp (p1, p2);
6647 if (i < 0)
6648 temp = integer_minus_one_node;
6649 else if (i > 0)
6650 temp = integer_one_node;
6651 else
6652 temp = integer_zero_node;
6653 return convert (TREE_TYPE (exp), temp);
6656 return 0;
6659 /* Fold function call to builtin strncmp. Return
6660 NULL_TREE if no simplification can be made. */
6662 static tree
6663 fold_builtin_strncmp (tree exp)
6665 tree arglist = TREE_OPERAND (exp, 1);
6666 tree arg1, arg2, len;
6667 const char *p1, *p2;
6669 if (!validate_arglist (arglist,
6670 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6671 return 0;
6673 arg1 = TREE_VALUE (arglist);
6674 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6675 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6677 /* If the LEN parameter is zero, return zero. */
6678 if (integer_zerop (len))
6680 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6681 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6684 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6685 if (operand_equal_p (arg1, arg2, 0))
6686 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6688 p1 = c_getstr (arg1);
6689 p2 = c_getstr (arg2);
6691 if (host_integerp (len, 1) && p1 && p2)
6693 tree temp;
6694 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6695 if (i < 0)
6696 temp = integer_minus_one_node;
6697 else if (i > 0)
6698 temp = integer_one_node;
6699 else
6700 temp = integer_zero_node;
6701 return convert (TREE_TYPE (exp), temp);
6704 return 0;
6707 /* Fold function call to builtin signbit, signbitf or signbitl. Return
6708 NULL_TREE if no simplification can be made. */
6710 static tree
6711 fold_builtin_signbit (tree exp)
6713 tree arglist = TREE_OPERAND (exp, 1);
6714 tree arg, temp;
6716 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6717 return NULL_TREE;
6719 arg = TREE_VALUE (arglist);
6721 /* If ARG is a compile-time constant, determine the result. */
6722 if (TREE_CODE (arg) == REAL_CST
6723 && !TREE_CONSTANT_OVERFLOW (arg))
6725 REAL_VALUE_TYPE c;
6727 c = TREE_REAL_CST (arg);
6728 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
6729 return convert (TREE_TYPE (exp), temp);
6732 /* If ARG is non-negative, the result is always zero. */
6733 if (tree_expr_nonnegative_p (arg))
6734 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
6736 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
6737 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
6738 return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
6739 build_real (TREE_TYPE (arg), dconst0)));
6741 return NULL_TREE;
6744 /* Fold a call to builtin isascii. */
6746 static tree
6747 fold_builtin_isascii (tree arglist)
6749 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6750 return 0;
6751 else
6753 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
6754 tree arg = TREE_VALUE (arglist);
6756 return fold (build (EQ_EXPR, integer_type_node,
6757 build (BIT_AND_EXPR, integer_type_node, arg,
6758 build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
6759 ~ (HOST_WIDE_INT) 0)),
6760 integer_zero_node));
6764 /* Fold a call to builtin toascii. */
6766 static tree
6767 fold_builtin_toascii (tree arglist)
6769 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6770 return 0;
6771 else
6773 /* Transform toascii(c) -> (c & 0x7f). */
6774 tree arg = TREE_VALUE (arglist);
6776 return fold (build (BIT_AND_EXPR, integer_type_node, arg,
6777 build_int_2 (0x7f, 0)));
6782 /* Used by constant folding to eliminate some builtin calls early. EXP is
6783 the CALL_EXPR of a call to a builtin function. */
6785 tree
6786 fold_builtin (tree exp)
6788 tree fndecl = get_callee_fndecl (exp);
6789 tree arglist = TREE_OPERAND (exp, 1);
6790 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6792 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6793 return 0;
6795 switch (DECL_FUNCTION_CODE (fndecl))
6797 case BUILT_IN_CONSTANT_P:
6798 return fold_builtin_constant_p (arglist);
6800 case BUILT_IN_CLASSIFY_TYPE:
6801 return fold_builtin_classify_type (arglist);
6803 case BUILT_IN_STRLEN:
6804 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6806 tree len = c_strlen (TREE_VALUE (arglist), 0);
6807 if (len)
6809 /* Convert from the internal "sizetype" type to "size_t". */
6810 if (size_type_node)
6811 len = convert (size_type_node, len);
6812 return len;
6815 break;
6817 case BUILT_IN_FABS:
6818 case BUILT_IN_FABSF:
6819 case BUILT_IN_FABSL:
6820 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6821 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6822 break;
6824 case BUILT_IN_CABS:
6825 case BUILT_IN_CABSF:
6826 case BUILT_IN_CABSL:
6827 return fold_builtin_cabs (fndecl, arglist, type);
6829 case BUILT_IN_SQRT:
6830 case BUILT_IN_SQRTF:
6831 case BUILT_IN_SQRTL:
6832 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6834 enum built_in_function fcode;
6835 tree arg = TREE_VALUE (arglist);
6837 /* Optimize sqrt of constant value. */
6838 if (TREE_CODE (arg) == REAL_CST
6839 && ! TREE_CONSTANT_OVERFLOW (arg))
6841 REAL_VALUE_TYPE r, x;
6843 x = TREE_REAL_CST (arg);
6844 if (real_sqrt (&r, TYPE_MODE (type), &x)
6845 || (!flag_trapping_math && !flag_errno_math))
6846 return build_real (type, r);
6849 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6850 fcode = builtin_mathfn_code (arg);
6851 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6853 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6854 arg = fold (build (MULT_EXPR, type,
6855 TREE_VALUE (TREE_OPERAND (arg, 1)),
6856 build_real (type, dconsthalf)));
6857 arglist = build_tree_list (NULL_TREE, arg);
6858 return build_function_call_expr (expfn, arglist);
6861 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6862 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6864 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6866 if (powfn)
6868 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6869 tree tree_root;
6870 /* The inner root was either sqrt or cbrt. */
6871 REAL_VALUE_TYPE dconstroot =
6872 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6874 /* Adjust for the outer root. */
6875 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6876 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6877 tree_root = build_real (type, dconstroot);
6878 arglist = tree_cons (NULL_TREE, arg0,
6879 build_tree_list (NULL_TREE, tree_root));
6880 return build_function_call_expr (powfn, arglist);
6884 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6885 if (flag_unsafe_math_optimizations
6886 && (fcode == BUILT_IN_POW
6887 || fcode == BUILT_IN_POWF
6888 || fcode == BUILT_IN_POWL))
6890 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6891 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6892 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6893 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6894 build_real (type, dconsthalf)));
6895 arglist = tree_cons (NULL_TREE, arg0,
6896 build_tree_list (NULL_TREE, narg1));
6897 return build_function_call_expr (powfn, arglist);
6900 break;
6902 case BUILT_IN_CBRT:
6903 case BUILT_IN_CBRTF:
6904 case BUILT_IN_CBRTL:
6905 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6907 tree arg = TREE_VALUE (arglist);
6908 const enum built_in_function fcode = builtin_mathfn_code (arg);
6910 /* Optimize cbrt of constant value. */
6911 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6912 return arg;
6914 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6915 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6917 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6918 const REAL_VALUE_TYPE third_trunc =
6919 real_value_truncate (TYPE_MODE (type), dconstthird);
6920 arg = fold (build (MULT_EXPR, type,
6921 TREE_VALUE (TREE_OPERAND (arg, 1)),
6922 build_real (type, third_trunc)));
6923 arglist = build_tree_list (NULL_TREE, arg);
6924 return build_function_call_expr (expfn, arglist);
6927 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6928 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6929 x is negative pow will error but cbrt won't. */
6930 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6932 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6934 if (powfn)
6936 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6937 tree tree_root;
6938 REAL_VALUE_TYPE dconstroot = dconstthird;
6940 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6941 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6942 tree_root = build_real (type, dconstroot);
6943 arglist = tree_cons (NULL_TREE, arg0,
6944 build_tree_list (NULL_TREE, tree_root));
6945 return build_function_call_expr (powfn, arglist);
6950 break;
6952 case BUILT_IN_SIN:
6953 case BUILT_IN_SINF:
6954 case BUILT_IN_SINL:
6955 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6957 tree arg = TREE_VALUE (arglist);
6959 /* Optimize sin(0.0) = 0.0. */
6960 if (real_zerop (arg))
6961 return arg;
6963 break;
6965 case BUILT_IN_COS:
6966 case BUILT_IN_COSF:
6967 case BUILT_IN_COSL:
6968 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6970 tree arg = TREE_VALUE (arglist);
6972 /* Optimize cos(0.0) = 1.0. */
6973 if (real_zerop (arg))
6974 return build_real (type, dconst1);
6976 /* Optimize cos(-x) into cos(x). */
6977 if (TREE_CODE (arg) == NEGATE_EXPR)
6979 tree arglist = build_tree_list (NULL_TREE,
6980 TREE_OPERAND (arg, 0));
6981 return build_function_call_expr (fndecl, arglist);
6984 break;
6986 case BUILT_IN_EXP:
6987 case BUILT_IN_EXPF:
6988 case BUILT_IN_EXPL:
6989 return fold_builtin_exponent (exp, &dconste);
6990 case BUILT_IN_EXP2:
6991 case BUILT_IN_EXP2F:
6992 case BUILT_IN_EXP2L:
6993 return fold_builtin_exponent (exp, &dconst2);
6994 case BUILT_IN_EXP10:
6995 case BUILT_IN_EXP10F:
6996 case BUILT_IN_EXP10L:
6997 case BUILT_IN_POW10:
6998 case BUILT_IN_POW10F:
6999 case BUILT_IN_POW10L:
7000 return fold_builtin_exponent (exp, &dconst10);
7001 case BUILT_IN_LOG:
7002 case BUILT_IN_LOGF:
7003 case BUILT_IN_LOGL:
7004 return fold_builtin_logarithm (exp, &dconste);
7005 break;
7006 case BUILT_IN_LOG2:
7007 case BUILT_IN_LOG2F:
7008 case BUILT_IN_LOG2L:
7009 return fold_builtin_logarithm (exp, &dconst2);
7010 break;
7011 case BUILT_IN_LOG10:
7012 case BUILT_IN_LOG10F:
7013 case BUILT_IN_LOG10L:
7014 return fold_builtin_logarithm (exp, &dconst10);
7015 break;
7017 case BUILT_IN_TAN:
7018 case BUILT_IN_TANF:
7019 case BUILT_IN_TANL:
7020 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7022 enum built_in_function fcode;
7023 tree arg = TREE_VALUE (arglist);
7025 /* Optimize tan(0.0) = 0.0. */
7026 if (real_zerop (arg))
7027 return arg;
7029 /* Optimize tan(atan(x)) = x. */
7030 fcode = builtin_mathfn_code (arg);
7031 if (flag_unsafe_math_optimizations
7032 && (fcode == BUILT_IN_ATAN
7033 || fcode == BUILT_IN_ATANF
7034 || fcode == BUILT_IN_ATANL))
7035 return TREE_VALUE (TREE_OPERAND (arg, 1));
7037 break;
7039 case BUILT_IN_ATAN:
7040 case BUILT_IN_ATANF:
7041 case BUILT_IN_ATANL:
7042 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7044 tree arg = TREE_VALUE (arglist);
7046 /* Optimize atan(0.0) = 0.0. */
7047 if (real_zerop (arg))
7048 return arg;
7050 /* Optimize atan(1.0) = pi/4. */
7051 if (real_onep (arg))
7053 REAL_VALUE_TYPE cst;
7055 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7056 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7057 return build_real (type, cst);
7060 break;
7062 case BUILT_IN_POW:
7063 case BUILT_IN_POWF:
7064 case BUILT_IN_POWL:
7065 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7067 enum built_in_function fcode;
7068 tree arg0 = TREE_VALUE (arglist);
7069 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7071 /* Optimize pow(1.0,y) = 1.0. */
7072 if (real_onep (arg0))
7073 return omit_one_operand (type, build_real (type, dconst1), arg1);
7075 if (TREE_CODE (arg1) == REAL_CST
7076 && ! TREE_CONSTANT_OVERFLOW (arg1))
7078 REAL_VALUE_TYPE c;
7079 c = TREE_REAL_CST (arg1);
7081 /* Optimize pow(x,0.0) = 1.0. */
7082 if (REAL_VALUES_EQUAL (c, dconst0))
7083 return omit_one_operand (type, build_real (type, dconst1),
7084 arg0);
7086 /* Optimize pow(x,1.0) = x. */
7087 if (REAL_VALUES_EQUAL (c, dconst1))
7088 return arg0;
7090 /* Optimize pow(x,-1.0) = 1.0/x. */
7091 if (REAL_VALUES_EQUAL (c, dconstm1))
7092 return fold (build (RDIV_EXPR, type,
7093 build_real (type, dconst1),
7094 arg0));
7096 /* Optimize pow(x,0.5) = sqrt(x). */
7097 if (flag_unsafe_math_optimizations
7098 && REAL_VALUES_EQUAL (c, dconsthalf))
7100 tree sqrtfn;
7102 fcode = DECL_FUNCTION_CODE (fndecl);
7103 if (fcode == BUILT_IN_POW)
7104 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
7105 else if (fcode == BUILT_IN_POWF)
7106 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
7107 else if (fcode == BUILT_IN_POWL)
7108 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
7109 else
7110 sqrtfn = NULL_TREE;
7112 if (sqrtfn != NULL_TREE)
7114 tree arglist = build_tree_list (NULL_TREE, arg0);
7115 return build_function_call_expr (sqrtfn, arglist);
7119 /* Attempt to evaluate pow at compile-time. */
7120 if (TREE_CODE (arg0) == REAL_CST
7121 && ! TREE_CONSTANT_OVERFLOW (arg0))
7123 REAL_VALUE_TYPE cint;
7124 HOST_WIDE_INT n;
7126 n = real_to_integer (&c);
7127 real_from_integer (&cint, VOIDmode, n,
7128 n < 0 ? -1 : 0, 0);
7129 if (real_identical (&c, &cint))
7131 REAL_VALUE_TYPE x;
7132 bool inexact;
7134 x = TREE_REAL_CST (arg0);
7135 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7136 if (flag_unsafe_math_optimizations || !inexact)
7137 return build_real (type, x);
7142 /* Optimize pow(expN(x),y) = expN(x*y). */
7143 fcode = builtin_mathfn_code (arg0);
7144 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7146 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7147 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7148 arg = fold (build (MULT_EXPR, type, arg, arg1));
7149 arglist = build_tree_list (NULL_TREE, arg);
7150 return build_function_call_expr (expfn, arglist);
7153 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7154 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7156 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7157 tree narg1 = fold (build (MULT_EXPR, type, arg1,
7158 build_real (type, dconsthalf)));
7160 arglist = tree_cons (NULL_TREE, narg0,
7161 build_tree_list (NULL_TREE, narg1));
7162 return build_function_call_expr (fndecl, arglist);
7165 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7166 if (flag_unsafe_math_optimizations
7167 && (fcode == BUILT_IN_POW
7168 || fcode == BUILT_IN_POWF
7169 || fcode == BUILT_IN_POWL))
7171 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7172 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7173 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
7174 arglist = tree_cons (NULL_TREE, arg00,
7175 build_tree_list (NULL_TREE, narg1));
7176 return build_function_call_expr (fndecl, arglist);
7179 break;
7181 case BUILT_IN_INF:
7182 case BUILT_IN_INFF:
7183 case BUILT_IN_INFL:
7184 return fold_builtin_inf (type, true);
7186 case BUILT_IN_HUGE_VAL:
7187 case BUILT_IN_HUGE_VALF:
7188 case BUILT_IN_HUGE_VALL:
7189 return fold_builtin_inf (type, false);
7191 case BUILT_IN_NAN:
7192 case BUILT_IN_NANF:
7193 case BUILT_IN_NANL:
7194 return fold_builtin_nan (arglist, type, true);
7196 case BUILT_IN_NANS:
7197 case BUILT_IN_NANSF:
7198 case BUILT_IN_NANSL:
7199 return fold_builtin_nan (arglist, type, false);
7201 case BUILT_IN_FLOOR:
7202 case BUILT_IN_FLOORF:
7203 case BUILT_IN_FLOORL:
7204 return fold_builtin_floor (exp);
7206 case BUILT_IN_CEIL:
7207 case BUILT_IN_CEILF:
7208 case BUILT_IN_CEILL:
7209 return fold_builtin_ceil (exp);
7211 case BUILT_IN_TRUNC:
7212 case BUILT_IN_TRUNCF:
7213 case BUILT_IN_TRUNCL:
7214 return fold_builtin_trunc (exp);
7216 case BUILT_IN_ROUND:
7217 case BUILT_IN_ROUNDF:
7218 case BUILT_IN_ROUNDL:
7219 return fold_builtin_round (exp);
7221 case BUILT_IN_NEARBYINT:
7222 case BUILT_IN_NEARBYINTF:
7223 case BUILT_IN_NEARBYINTL:
7224 case BUILT_IN_RINT:
7225 case BUILT_IN_RINTF:
7226 case BUILT_IN_RINTL:
7227 return fold_trunc_transparent_mathfn (exp);
7229 case BUILT_IN_FFS:
7230 case BUILT_IN_FFSL:
7231 case BUILT_IN_FFSLL:
7232 case BUILT_IN_CLZ:
7233 case BUILT_IN_CLZL:
7234 case BUILT_IN_CLZLL:
7235 case BUILT_IN_CTZ:
7236 case BUILT_IN_CTZL:
7237 case BUILT_IN_CTZLL:
7238 case BUILT_IN_POPCOUNT:
7239 case BUILT_IN_POPCOUNTL:
7240 case BUILT_IN_POPCOUNTLL:
7241 case BUILT_IN_PARITY:
7242 case BUILT_IN_PARITYL:
7243 case BUILT_IN_PARITYLL:
7244 return fold_builtin_bitop (exp);
7246 case BUILT_IN_MEMCPY:
7247 return fold_builtin_memcpy (exp);
7249 case BUILT_IN_MEMPCPY:
7250 return fold_builtin_mempcpy (exp);
7252 case BUILT_IN_MEMMOVE:
7253 return fold_builtin_memmove (exp);
7255 case BUILT_IN_STRCPY:
7256 return fold_builtin_strcpy (exp);
7258 case BUILT_IN_STRNCPY:
7259 return fold_builtin_strncpy (exp);
7261 case BUILT_IN_MEMCMP:
7262 return fold_builtin_memcmp (exp);
7264 case BUILT_IN_STRCMP:
7265 return fold_builtin_strcmp (exp);
7267 case BUILT_IN_STRNCMP:
7268 return fold_builtin_strncmp (exp);
7270 case BUILT_IN_SIGNBIT:
7271 case BUILT_IN_SIGNBITF:
7272 case BUILT_IN_SIGNBITL:
7273 return fold_builtin_signbit (exp);
7275 case BUILT_IN_ISASCII:
7276 return fold_builtin_isascii (arglist);
7278 case BUILT_IN_TOASCII:
7279 return fold_builtin_toascii (arglist);
7281 default:
7282 break;
7285 return 0;
7288 /* Conveniently construct a function call expression. */
7290 tree
7291 build_function_call_expr (tree fn, tree arglist)
7293 tree call_expr;
7295 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7296 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7297 call_expr, arglist);
7298 return fold (call_expr);
7301 /* This function validates the types of a function call argument list
7302 represented as a tree chain of parameters against a specified list
7303 of tree_codes. If the last specifier is a 0, that represents an
7304 ellipses, otherwise the last specifier must be a VOID_TYPE. */
7306 static int
7307 validate_arglist (tree arglist, ...)
7309 enum tree_code code;
7310 int res = 0;
7311 va_list ap;
7313 va_start (ap, arglist);
7317 code = va_arg (ap, enum tree_code);
7318 switch (code)
7320 case 0:
7321 /* This signifies an ellipses, any further arguments are all ok. */
7322 res = 1;
7323 goto end;
7324 case VOID_TYPE:
7325 /* This signifies an endlink, if no arguments remain, return
7326 true, otherwise return false. */
7327 res = arglist == 0;
7328 goto end;
7329 default:
7330 /* If no parameters remain or the parameter's code does not
7331 match the specified code, return false. Otherwise continue
7332 checking any remaining arguments. */
7333 if (arglist == 0
7334 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7335 goto end;
7336 break;
7338 arglist = TREE_CHAIN (arglist);
7340 while (1);
7342 /* We need gotos here since we can only have one VA_CLOSE in a
7343 function. */
7344 end: ;
7345 va_end (ap);
7347 return res;
7350 /* Default target-specific builtin expander that does nothing. */
7353 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7354 rtx target ATTRIBUTE_UNUSED,
7355 rtx subtarget ATTRIBUTE_UNUSED,
7356 enum machine_mode mode ATTRIBUTE_UNUSED,
7357 int ignore ATTRIBUTE_UNUSED)
7359 return NULL_RTX;
7362 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
7364 void
7365 purge_builtin_constant_p (void)
7367 rtx insn, set, arg, new, note;
7369 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7370 if (INSN_P (insn)
7371 && (set = single_set (insn)) != NULL_RTX
7372 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
7373 || (GET_CODE (arg) == SUBREG
7374 && (GET_CODE (arg = SUBREG_REG (arg))
7375 == CONSTANT_P_RTX))))
7377 arg = XEXP (arg, 0);
7378 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
7379 validate_change (insn, &SET_SRC (set), new, 0);
7381 /* Remove the REG_EQUAL note from the insn. */
7382 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
7383 remove_note (insn, note);
7387 /* Returns true is EXP represents data that would potentially reside
7388 in a readonly section. */
7390 static bool
7391 readonly_data_expr (tree exp)
7393 STRIP_NOPS (exp);
7395 if (TREE_CODE (exp) == ADDR_EXPR)
7396 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7397 else
7398 return false;