* config/i386/i386.md (*fscalexf4): Correct insn "mode"
[official-gcc.git] / gcc / builtins.c
blob612684262b563a650c5a4b55bce96512513abdf4
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_update_setjmp_buf (rtx);
88 static void expand_builtin_prefetch (tree);
89 static rtx expand_builtin_apply_args (void);
90 static rtx expand_builtin_apply_args_1 (void);
91 static rtx expand_builtin_apply (rtx, rtx, rtx);
92 static void expand_builtin_return (rtx);
93 static enum type_class type_to_class (tree);
94 static rtx expand_builtin_classify_type (tree);
95 static void expand_errno_check (tree, rtx);
96 static rtx expand_builtin_mathfn (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
98 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
99 static rtx expand_builtin_constant_p (tree, enum machine_mode);
100 static rtx expand_builtin_args_info (tree);
101 static rtx expand_builtin_next_arg (tree);
102 static rtx expand_builtin_va_start (tree);
103 static rtx expand_builtin_va_end (tree);
104 static rtx expand_builtin_va_copy (tree);
105 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
108 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
109 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
115 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_bcopy (tree);
117 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
119 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
121 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_bzero (tree);
125 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_alloca (tree, rtx);
131 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
132 static rtx expand_builtin_frame_address (tree, tree);
133 static rtx expand_builtin_fputs (tree, rtx, bool);
134 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
137 static tree stabilize_va_list (tree, int);
138 static rtx expand_builtin_expect (tree, rtx);
139 static tree fold_builtin_constant_p (tree);
140 static tree fold_builtin_classify_type (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_cabs (tree, rtx);
149 static rtx expand_builtin_signbit (tree, rtx);
150 static tree fold_builtin_cabs (tree, tree);
151 static tree fold_builtin_trunc (tree);
152 static tree fold_builtin_floor (tree);
153 static tree fold_builtin_ceil (tree);
154 static tree fold_builtin_round (tree);
155 static tree fold_builtin_bitop (tree);
156 static tree fold_builtin_memcpy (tree);
157 static tree fold_builtin_mempcpy (tree);
158 static tree fold_builtin_memmove (tree);
159 static tree fold_builtin_strcpy (tree);
160 static tree fold_builtin_strncpy (tree);
161 static tree fold_builtin_memcmp (tree);
162 static tree fold_builtin_strcmp (tree);
163 static tree fold_builtin_strncmp (tree);
164 static tree fold_builtin_signbit (tree);
166 /* Return the alignment in bits of EXP, a pointer valued expression.
167 But don't return more than MAX_ALIGN no matter what.
168 The alignment returned is, by default, the alignment of the thing that
169 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
171 Otherwise, look at the expression to see if we can do better, i.e., if the
172 expression is actually pointing at an object whose alignment is tighter. */
174 static int
175 get_pointer_alignment (tree exp, unsigned int max_align)
177 unsigned int align, inner;
179 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
180 return 0;
182 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
183 align = MIN (align, max_align);
185 while (1)
187 switch (TREE_CODE (exp))
189 case NOP_EXPR:
190 case CONVERT_EXPR:
191 case NON_LVALUE_EXPR:
192 exp = TREE_OPERAND (exp, 0);
193 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
194 return align;
196 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
197 align = MIN (inner, max_align);
198 break;
200 case PLUS_EXPR:
201 /* If sum of pointer + int, restrict our maximum alignment to that
202 imposed by the integer. If not, we can't do any better than
203 ALIGN. */
204 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
205 return align;
207 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
208 & (max_align / BITS_PER_UNIT - 1))
209 != 0)
210 max_align >>= 1;
212 exp = TREE_OPERAND (exp, 0);
213 break;
215 case ADDR_EXPR:
216 /* See what we are pointing at and look at its alignment. */
217 exp = TREE_OPERAND (exp, 0);
218 if (TREE_CODE (exp) == FUNCTION_DECL)
219 align = FUNCTION_BOUNDARY;
220 else if (DECL_P (exp))
221 align = DECL_ALIGN (exp);
222 #ifdef CONSTANT_ALIGNMENT
223 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
224 align = CONSTANT_ALIGNMENT (exp, align);
225 #endif
226 return MIN (align, max_align);
228 default:
229 return align;
234 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
235 way, because it could contain a zero byte in the middle.
236 TREE_STRING_LENGTH is the size of the character array, not the string.
238 ONLY_VALUE should be nonzero if the result is not going to be emitted
239 into the instruction stream and zero if it is going to be expanded.
240 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
241 is returned, otherwise NULL, since
242 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
243 evaluate the side-effects.
245 The value returned is of type `ssizetype'.
247 Unfortunately, string_constant can't access the values of const char
248 arrays with initializers, so neither can we do so here. */
250 static tree
251 c_strlen (tree src, int only_value)
253 tree offset_node;
254 HOST_WIDE_INT offset;
255 int max;
256 const char *ptr;
258 STRIP_NOPS (src);
259 if (TREE_CODE (src) == COND_EXPR
260 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
262 tree len1, len2;
264 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
265 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
266 if (tree_int_cst_equal (len1, len2))
267 return len1;
270 if (TREE_CODE (src) == COMPOUND_EXPR
271 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
272 return c_strlen (TREE_OPERAND (src, 1), only_value);
274 src = string_constant (src, &offset_node);
275 if (src == 0)
276 return 0;
278 max = TREE_STRING_LENGTH (src) - 1;
279 ptr = TREE_STRING_POINTER (src);
281 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
283 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
284 compute the offset to the following null if we don't know where to
285 start searching for it. */
286 int i;
288 for (i = 0; i < max; i++)
289 if (ptr[i] == 0)
290 return 0;
292 /* We don't know the starting offset, but we do know that the string
293 has no internal zero bytes. We can assume that the offset falls
294 within the bounds of the string; otherwise, the programmer deserves
295 what he gets. Subtract the offset from the length of the string,
296 and return that. This would perhaps not be valid if we were dealing
297 with named arrays in addition to literal string constants. */
299 return size_diffop (size_int (max), offset_node);
302 /* We have a known offset into the string. Start searching there for
303 a null character if we can represent it as a single HOST_WIDE_INT. */
304 if (offset_node == 0)
305 offset = 0;
306 else if (! host_integerp (offset_node, 0))
307 offset = -1;
308 else
309 offset = tree_low_cst (offset_node, 0);
311 /* If the offset is known to be out of bounds, warn, and call strlen at
312 runtime. */
313 if (offset < 0 || offset > max)
315 warning ("offset outside bounds of constant string");
316 return 0;
319 /* Use strlen to search for the first zero byte. Since any strings
320 constructed with build_string will have nulls appended, we win even
321 if we get handed something like (char[4])"abcd".
323 Since OFFSET is our starting index into the string, no further
324 calculation is needed. */
325 return ssize_int (strlen (ptr + offset));
328 /* Return a char pointer for a C string if it is a string constant
329 or sum of string constant and integer constant. */
331 static const char *
332 c_getstr (tree src)
334 tree offset_node;
336 src = string_constant (src, &offset_node);
337 if (src == 0)
338 return 0;
340 if (offset_node == 0)
341 return TREE_STRING_POINTER (src);
342 else if (!host_integerp (offset_node, 1)
343 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
344 return 0;
346 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
349 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
350 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
352 static rtx
353 c_readstr (const char *str, enum machine_mode mode)
355 HOST_WIDE_INT c[2];
356 HOST_WIDE_INT ch;
357 unsigned int i, j;
359 if (GET_MODE_CLASS (mode) != MODE_INT)
360 abort ();
361 c[0] = 0;
362 c[1] = 0;
363 ch = 1;
364 for (i = 0; i < GET_MODE_SIZE (mode); i++)
366 j = i;
367 if (WORDS_BIG_ENDIAN)
368 j = GET_MODE_SIZE (mode) - i - 1;
369 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
370 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
371 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
372 j *= BITS_PER_UNIT;
373 if (j > 2 * HOST_BITS_PER_WIDE_INT)
374 abort ();
375 if (ch)
376 ch = (unsigned char) str[i];
377 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
379 return immed_double_const (c[0], c[1], mode);
382 /* Cast a target constant CST to target CHAR and if that value fits into
383 host char type, return zero and put that value into variable pointed by
384 P. */
386 static int
387 target_char_cast (tree cst, char *p)
389 unsigned HOST_WIDE_INT val, hostval;
391 if (!host_integerp (cst, 1)
392 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
393 return 1;
395 val = tree_low_cst (cst, 1);
396 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
397 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
399 hostval = val;
400 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
401 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
403 if (val != hostval)
404 return 1;
406 *p = hostval;
407 return 0;
410 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
411 times to get the address of either a higher stack frame, or a return
412 address located within it (depending on FNDECL_CODE). */
415 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
416 rtx tem)
418 int i;
420 /* Some machines need special handling before we can access
421 arbitrary frames. For example, on the sparc, we must first flush
422 all register windows to the stack. */
423 #ifdef SETUP_FRAME_ADDRESSES
424 if (count > 0)
425 SETUP_FRAME_ADDRESSES ();
426 #endif
428 /* On the sparc, the return address is not in the frame, it is in a
429 register. There is no way to access it off of the current frame
430 pointer, but it can be accessed off the previous frame pointer by
431 reading the value from the register window save area. */
432 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
433 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
434 count--;
435 #endif
437 /* Scan back COUNT frames to the specified frame. */
438 for (i = 0; i < count; i++)
440 /* Assume the dynamic chain pointer is in the word that the
441 frame address points to, unless otherwise specified. */
442 #ifdef DYNAMIC_CHAIN_ADDRESS
443 tem = DYNAMIC_CHAIN_ADDRESS (tem);
444 #endif
445 tem = memory_address (Pmode, tem);
446 tem = gen_rtx_MEM (Pmode, tem);
447 set_mem_alias_set (tem, get_frame_alias_set ());
448 tem = copy_to_reg (tem);
451 /* For __builtin_frame_address, return what we've got. */
452 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
453 return tem;
455 /* For __builtin_return_address, Get the return address from that
456 frame. */
457 #ifdef RETURN_ADDR_RTX
458 tem = RETURN_ADDR_RTX (count, tem);
459 #else
460 tem = memory_address (Pmode,
461 plus_constant (tem, GET_MODE_SIZE (Pmode)));
462 tem = gen_rtx_MEM (Pmode, tem);
463 set_mem_alias_set (tem, get_frame_alias_set ());
464 #endif
465 return tem;
468 /* Alias set used for setjmp buffer. */
469 static HOST_WIDE_INT setjmp_alias_set = -1;
471 /* Construct the leading half of a __builtin_setjmp call. Control will
472 return to RECEIVER_LABEL. This is used directly by sjlj exception
473 handling code. */
475 void
476 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
478 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
479 rtx stack_save;
480 rtx mem;
482 if (setjmp_alias_set == -1)
483 setjmp_alias_set = new_alias_set ();
485 buf_addr = convert_memory_address (Pmode, buf_addr);
487 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
489 emit_queue ();
491 /* We store the frame pointer and the address of receiver_label in
492 the buffer and use the rest of it for the stack save area, which
493 is machine-dependent. */
495 mem = gen_rtx_MEM (Pmode, buf_addr);
496 set_mem_alias_set (mem, setjmp_alias_set);
497 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
499 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
500 set_mem_alias_set (mem, setjmp_alias_set);
502 emit_move_insn (validize_mem (mem),
503 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
505 stack_save = gen_rtx_MEM (sa_mode,
506 plus_constant (buf_addr,
507 2 * GET_MODE_SIZE (Pmode)));
508 set_mem_alias_set (stack_save, setjmp_alias_set);
509 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
511 /* If there is further processing to do, do it. */
512 #ifdef HAVE_builtin_setjmp_setup
513 if (HAVE_builtin_setjmp_setup)
514 emit_insn (gen_builtin_setjmp_setup (buf_addr));
515 #endif
517 /* Tell optimize_save_area_alloca that extra work is going to
518 need to go on during alloca. */
519 current_function_calls_setjmp = 1;
521 /* Set this so all the registers get saved in our frame; we need to be
522 able to copy the saved values for any registers from frames we unwind. */
523 current_function_has_nonlocal_label = 1;
526 /* Construct the trailing part of a __builtin_setjmp call.
527 This is used directly by sjlj exception handling code. */
529 void
530 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
532 /* Clobber the FP when we get here, so we have to make sure it's
533 marked as used by this function. */
534 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
536 /* Mark the static chain as clobbered here so life information
537 doesn't get messed up for it. */
538 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
540 /* Now put in the code to restore the frame pointer, and argument
541 pointer, if needed. The code below is from expand_end_bindings
542 in stmt.c; see detailed documentation there. */
543 #ifdef HAVE_nonlocal_goto
544 if (! HAVE_nonlocal_goto)
545 #endif
546 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
548 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
549 if (fixed_regs[ARG_POINTER_REGNUM])
551 #ifdef ELIMINABLE_REGS
552 size_t i;
553 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
555 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
556 if (elim_regs[i].from == ARG_POINTER_REGNUM
557 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
558 break;
560 if (i == ARRAY_SIZE (elim_regs))
561 #endif
563 /* Now restore our arg pointer from the address at which it
564 was saved in our stack frame. */
565 emit_move_insn (virtual_incoming_args_rtx,
566 copy_to_reg (get_arg_pointer_save_area (cfun)));
569 #endif
571 #ifdef HAVE_builtin_setjmp_receiver
572 if (HAVE_builtin_setjmp_receiver)
573 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
574 else
575 #endif
576 #ifdef HAVE_nonlocal_goto_receiver
577 if (HAVE_nonlocal_goto_receiver)
578 emit_insn (gen_nonlocal_goto_receiver ());
579 else
580 #endif
581 { /* Nothing */ }
583 /* @@@ This is a kludge. Not all machine descriptions define a blockage
584 insn, but we must not allow the code we just generated to be reordered
585 by scheduling. Specifically, the update of the frame pointer must
586 happen immediately, not later. So emit an ASM_INPUT to act as blockage
587 insn. */
588 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
591 /* __builtin_setjmp is passed a pointer to an array of five words (not
592 all will be used on all machines). It operates similarly to the C
593 library function of the same name, but is more efficient. Much of
594 the code below (and for longjmp) is copied from the handling of
595 non-local gotos.
597 NOTE: This is intended for use by GNAT and the exception handling
598 scheme in the compiler and will only work in the method used by
599 them. */
601 static rtx
602 expand_builtin_setjmp (tree arglist, rtx target)
604 rtx buf_addr, next_lab, cont_lab;
606 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
607 return NULL_RTX;
609 if (target == 0 || GET_CODE (target) != REG
610 || REGNO (target) < FIRST_PSEUDO_REGISTER)
611 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
613 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
615 next_lab = gen_label_rtx ();
616 cont_lab = gen_label_rtx ();
618 expand_builtin_setjmp_setup (buf_addr, next_lab);
620 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
621 ensure that pending stack adjustments are flushed. */
622 emit_move_insn (target, const0_rtx);
623 emit_jump (cont_lab);
625 emit_label (next_lab);
627 expand_builtin_setjmp_receiver (next_lab);
629 /* Set TARGET to one. */
630 emit_move_insn (target, const1_rtx);
631 emit_label (cont_lab);
633 /* Tell flow about the strange goings on. Putting `next_lab' on
634 `nonlocal_goto_handler_labels' to indicates that function
635 calls may traverse the arc back to this label. */
637 current_function_has_nonlocal_label = 1;
638 nonlocal_goto_handler_labels
639 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
641 return target;
644 /* __builtin_longjmp is passed a pointer to an array of five words (not
645 all will be used on all machines). It operates similarly to the C
646 library function of the same name, but is more efficient. Much of
647 the code below is copied from the handling of non-local gotos.
649 NOTE: This is intended for use by GNAT and the exception handling
650 scheme in the compiler and will only work in the method used by
651 them. */
653 void
654 expand_builtin_longjmp (rtx buf_addr, rtx value)
656 rtx fp, lab, stack, insn, last;
657 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
659 if (setjmp_alias_set == -1)
660 setjmp_alias_set = new_alias_set ();
662 buf_addr = convert_memory_address (Pmode, buf_addr);
664 buf_addr = force_reg (Pmode, buf_addr);
666 /* We used to store value in static_chain_rtx, but that fails if pointers
667 are smaller than integers. We instead require that the user must pass
668 a second argument of 1, because that is what builtin_setjmp will
669 return. This also makes EH slightly more efficient, since we are no
670 longer copying around a value that we don't care about. */
671 if (value != const1_rtx)
672 abort ();
674 current_function_calls_longjmp = 1;
676 last = get_last_insn ();
677 #ifdef HAVE_builtin_longjmp
678 if (HAVE_builtin_longjmp)
679 emit_insn (gen_builtin_longjmp (buf_addr));
680 else
681 #endif
683 fp = gen_rtx_MEM (Pmode, buf_addr);
684 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
685 GET_MODE_SIZE (Pmode)));
687 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
688 2 * GET_MODE_SIZE (Pmode)));
689 set_mem_alias_set (fp, setjmp_alias_set);
690 set_mem_alias_set (lab, setjmp_alias_set);
691 set_mem_alias_set (stack, setjmp_alias_set);
693 /* Pick up FP, label, and SP from the block and jump. This code is
694 from expand_goto in stmt.c; see there for detailed comments. */
695 #if HAVE_nonlocal_goto
696 if (HAVE_nonlocal_goto)
697 /* We have to pass a value to the nonlocal_goto pattern that will
698 get copied into the static_chain pointer, but it does not matter
699 what that value is, because builtin_setjmp does not use it. */
700 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
701 else
702 #endif
704 lab = copy_to_reg (lab);
706 emit_insn (gen_rtx_CLOBBER (VOIDmode,
707 gen_rtx_MEM (BLKmode,
708 gen_rtx_SCRATCH (VOIDmode))));
709 emit_insn (gen_rtx_CLOBBER (VOIDmode,
710 gen_rtx_MEM (BLKmode,
711 hard_frame_pointer_rtx)));
713 emit_move_insn (hard_frame_pointer_rtx, fp);
714 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
716 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
717 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
718 emit_indirect_jump (lab);
722 /* Search backwards and mark the jump insn as a non-local goto.
723 Note that this precludes the use of __builtin_longjmp to a
724 __builtin_setjmp target in the same function. However, we've
725 already cautioned the user that these functions are for
726 internal exception handling use only. */
727 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
729 if (insn == last)
730 abort ();
731 if (GET_CODE (insn) == JUMP_INSN)
733 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
734 REG_NOTES (insn));
735 break;
737 else if (GET_CODE (insn) == CALL_INSN)
738 break;
742 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
743 (not all will be used on all machines) that was passed to __builtin_setjmp.
744 It updates the stack pointer in that block to correspond to the current
745 stack pointer. */
747 static void
748 expand_builtin_update_setjmp_buf (rtx buf_addr)
750 enum machine_mode sa_mode = Pmode;
751 rtx stack_save;
754 #ifdef HAVE_save_stack_nonlocal
755 if (HAVE_save_stack_nonlocal)
756 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
757 #endif
758 #ifdef STACK_SAVEAREA_MODE
759 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
760 #endif
762 stack_save
763 = gen_rtx_MEM (sa_mode,
764 memory_address
765 (sa_mode,
766 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
768 #ifdef HAVE_setjmp
769 if (HAVE_setjmp)
770 emit_insn (gen_setjmp ());
771 #endif
773 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
776 /* Expand a call to __builtin_prefetch. For a target that does not support
777 data prefetch, evaluate the memory address argument in case it has side
778 effects. */
780 static void
781 expand_builtin_prefetch (tree arglist)
783 tree arg0, arg1, arg2;
784 rtx op0, op1, op2;
786 if (!validate_arglist (arglist, POINTER_TYPE, 0))
787 return;
789 arg0 = TREE_VALUE (arglist);
790 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
791 zero (read) and argument 2 (locality) defaults to 3 (high degree of
792 locality). */
793 if (TREE_CHAIN (arglist))
795 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
796 if (TREE_CHAIN (TREE_CHAIN (arglist)))
797 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
798 else
799 arg2 = build_int_2 (3, 0);
801 else
803 arg1 = integer_zero_node;
804 arg2 = build_int_2 (3, 0);
807 /* Argument 0 is an address. */
808 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
810 /* Argument 1 (read/write flag) must be a compile-time constant int. */
811 if (TREE_CODE (arg1) != INTEGER_CST)
813 error ("second arg to `__builtin_prefetch' must be a constant");
814 arg1 = integer_zero_node;
816 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
817 /* Argument 1 must be either zero or one. */
818 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
820 warning ("invalid second arg to __builtin_prefetch; using zero");
821 op1 = const0_rtx;
824 /* Argument 2 (locality) must be a compile-time constant int. */
825 if (TREE_CODE (arg2) != INTEGER_CST)
827 error ("third arg to `__builtin_prefetch' must be a constant");
828 arg2 = integer_zero_node;
830 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
831 /* Argument 2 must be 0, 1, 2, or 3. */
832 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
834 warning ("invalid third arg to __builtin_prefetch; using zero");
835 op2 = const0_rtx;
838 #ifdef HAVE_prefetch
839 if (HAVE_prefetch)
841 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
842 (op0,
843 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
844 || (GET_MODE (op0) != Pmode))
846 op0 = convert_memory_address (Pmode, op0);
847 op0 = force_reg (Pmode, op0);
849 emit_insn (gen_prefetch (op0, op1, op2));
851 else
852 #endif
853 op0 = protect_from_queue (op0, 0);
854 /* Don't do anything with direct references to volatile memory, but
855 generate code to handle other side effects. */
856 if (GET_CODE (op0) != MEM && side_effects_p (op0))
857 emit_insn (op0);
860 /* Get a MEM rtx for expression EXP which is the address of an operand
861 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
863 static rtx
864 get_memory_rtx (tree exp)
866 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
867 rtx mem;
869 addr = convert_memory_address (Pmode, addr);
871 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
873 /* Get an expression we can use to find the attributes to assign to MEM.
874 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
875 we can. First remove any nops. */
876 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
877 || TREE_CODE (exp) == NON_LVALUE_EXPR)
878 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
879 exp = TREE_OPERAND (exp, 0);
881 if (TREE_CODE (exp) == ADDR_EXPR)
883 exp = TREE_OPERAND (exp, 0);
884 set_mem_attributes (mem, exp, 0);
886 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
888 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
889 /* memcpy, memset and other builtin stringops can alias with anything. */
890 set_mem_alias_set (mem, 0);
893 return mem;
896 /* Built-in functions to perform an untyped call and return. */
898 /* For each register that may be used for calling a function, this
899 gives a mode used to copy the register's value. VOIDmode indicates
900 the register is not used for calling a function. If the machine
901 has register windows, this gives only the outbound registers.
902 INCOMING_REGNO gives the corresponding inbound register. */
903 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
905 /* For each register that may be used for returning values, this gives
906 a mode used to copy the register's value. VOIDmode indicates the
907 register is not used for returning values. If the machine has
908 register windows, this gives only the outbound registers.
909 INCOMING_REGNO gives the corresponding inbound register. */
910 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
912 /* For each register that may be used for calling a function, this
913 gives the offset of that register into the block returned by
914 __builtin_apply_args. 0 indicates that the register is not
915 used for calling a function. */
916 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
918 /* Return the size required for the block returned by __builtin_apply_args,
919 and initialize apply_args_mode. */
921 static int
922 apply_args_size (void)
924 static int size = -1;
925 int align;
926 unsigned int regno;
927 enum machine_mode mode;
929 /* The values computed by this function never change. */
930 if (size < 0)
932 /* The first value is the incoming arg-pointer. */
933 size = GET_MODE_SIZE (Pmode);
935 /* The second value is the structure value address unless this is
936 passed as an "invisible" first argument. */
937 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
938 size += GET_MODE_SIZE (Pmode);
940 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
941 if (FUNCTION_ARG_REGNO_P (regno))
943 mode = reg_raw_mode[regno];
945 if (mode == VOIDmode)
946 abort ();
948 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
949 if (size % align != 0)
950 size = CEIL (size, align) * align;
951 apply_args_reg_offset[regno] = size;
952 size += GET_MODE_SIZE (mode);
953 apply_args_mode[regno] = mode;
955 else
957 apply_args_mode[regno] = VOIDmode;
958 apply_args_reg_offset[regno] = 0;
961 return size;
964 /* Return the size required for the block returned by __builtin_apply,
965 and initialize apply_result_mode. */
967 static int
968 apply_result_size (void)
970 static int size = -1;
971 int align, regno;
972 enum machine_mode mode;
974 /* The values computed by this function never change. */
975 if (size < 0)
977 size = 0;
979 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
980 if (FUNCTION_VALUE_REGNO_P (regno))
982 mode = reg_raw_mode[regno];
984 if (mode == VOIDmode)
985 abort ();
987 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
988 if (size % align != 0)
989 size = CEIL (size, align) * align;
990 size += GET_MODE_SIZE (mode);
991 apply_result_mode[regno] = mode;
993 else
994 apply_result_mode[regno] = VOIDmode;
996 /* Allow targets that use untyped_call and untyped_return to override
997 the size so that machine-specific information can be stored here. */
998 #ifdef APPLY_RESULT_SIZE
999 size = APPLY_RESULT_SIZE;
1000 #endif
1002 return size;
1005 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1006 /* Create a vector describing the result block RESULT. If SAVEP is true,
1007 the result block is used to save the values; otherwise it is used to
1008 restore the values. */
1010 static rtx
1011 result_vector (int savep, rtx result)
1013 int regno, size, align, nelts;
1014 enum machine_mode mode;
1015 rtx reg, mem;
1016 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1018 size = nelts = 0;
1019 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1020 if ((mode = apply_result_mode[regno]) != VOIDmode)
1022 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1023 if (size % align != 0)
1024 size = CEIL (size, align) * align;
1025 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1026 mem = adjust_address (result, mode, size);
1027 savevec[nelts++] = (savep
1028 ? gen_rtx_SET (VOIDmode, mem, reg)
1029 : gen_rtx_SET (VOIDmode, reg, mem));
1030 size += GET_MODE_SIZE (mode);
1032 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1034 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1036 /* Save the state required to perform an untyped call with the same
1037 arguments as were passed to the current function. */
1039 static rtx
1040 expand_builtin_apply_args_1 (void)
1042 rtx registers, tem;
1043 int size, align, regno;
1044 enum machine_mode mode;
1045 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1047 /* Create a block where the arg-pointer, structure value address,
1048 and argument registers can be saved. */
1049 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1051 /* Walk past the arg-pointer and structure value address. */
1052 size = GET_MODE_SIZE (Pmode);
1053 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1054 size += GET_MODE_SIZE (Pmode);
1056 /* Save each register used in calling a function to the block. */
1057 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1058 if ((mode = apply_args_mode[regno]) != VOIDmode)
1060 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1061 if (size % align != 0)
1062 size = CEIL (size, align) * align;
1064 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1066 emit_move_insn (adjust_address (registers, mode, size), tem);
1067 size += GET_MODE_SIZE (mode);
1070 /* Save the arg pointer to the block. */
1071 tem = copy_to_reg (virtual_incoming_args_rtx);
1072 #ifdef STACK_GROWS_DOWNWARD
1073 /* We need the pointer as the caller actually passed them to us, not
1074 as we might have pretended they were passed. Make sure it's a valid
1075 operand, as emit_move_insn isn't expected to handle a PLUS. */
1077 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1078 NULL_RTX);
1079 #endif
1080 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1082 size = GET_MODE_SIZE (Pmode);
1084 /* Save the structure value address unless this is passed as an
1085 "invisible" first argument. */
1086 if (struct_incoming_value)
1088 emit_move_insn (adjust_address (registers, Pmode, size),
1089 copy_to_reg (struct_incoming_value));
1090 size += GET_MODE_SIZE (Pmode);
1093 /* Return the address of the block. */
1094 return copy_addr_to_reg (XEXP (registers, 0));
1097 /* __builtin_apply_args returns block of memory allocated on
1098 the stack into which is stored the arg pointer, structure
1099 value address, static chain, and all the registers that might
1100 possibly be used in performing a function call. The code is
1101 moved to the start of the function so the incoming values are
1102 saved. */
1104 static rtx
1105 expand_builtin_apply_args (void)
1107 /* Don't do __builtin_apply_args more than once in a function.
1108 Save the result of the first call and reuse it. */
1109 if (apply_args_value != 0)
1110 return apply_args_value;
1112 /* When this function is called, it means that registers must be
1113 saved on entry to this function. So we migrate the
1114 call to the first insn of this function. */
1115 rtx temp;
1116 rtx seq;
1118 start_sequence ();
1119 temp = expand_builtin_apply_args_1 ();
1120 seq = get_insns ();
1121 end_sequence ();
1123 apply_args_value = temp;
1125 /* Put the insns after the NOTE that starts the function.
1126 If this is inside a start_sequence, make the outer-level insn
1127 chain current, so the code is placed at the start of the
1128 function. */
1129 push_topmost_sequence ();
1130 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1131 pop_topmost_sequence ();
1132 return temp;
1136 /* Perform an untyped call and save the state required to perform an
1137 untyped return of whatever value was returned by the given function. */
1139 static rtx
1140 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1142 int size, align, regno;
1143 enum machine_mode mode;
1144 rtx incoming_args, result, reg, dest, src, call_insn;
1145 rtx old_stack_level = 0;
1146 rtx call_fusage = 0;
1147 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1149 arguments = convert_memory_address (Pmode, arguments);
1151 /* Create a block where the return registers can be saved. */
1152 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1154 /* Fetch the arg pointer from the ARGUMENTS block. */
1155 incoming_args = gen_reg_rtx (Pmode);
1156 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1157 #ifndef STACK_GROWS_DOWNWARD
1158 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1159 incoming_args, 0, OPTAB_LIB_WIDEN);
1160 #endif
1162 /* Perform postincrements before actually calling the function. */
1163 emit_queue ();
1165 /* Push a new argument block and copy the arguments. Do not allow
1166 the (potential) memcpy call below to interfere with our stack
1167 manipulations. */
1168 do_pending_stack_adjust ();
1169 NO_DEFER_POP;
1171 /* Save the stack with nonlocal if available. */
1172 #ifdef HAVE_save_stack_nonlocal
1173 if (HAVE_save_stack_nonlocal)
1174 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1175 else
1176 #endif
1177 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1179 /* Allocate a block of memory onto the stack and copy the memory
1180 arguments to the outgoing arguments address. */
1181 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1182 dest = virtual_outgoing_args_rtx;
1183 #ifndef STACK_GROWS_DOWNWARD
1184 if (GET_CODE (argsize) == CONST_INT)
1185 dest = plus_constant (dest, -INTVAL (argsize));
1186 else
1187 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1188 #endif
1189 dest = gen_rtx_MEM (BLKmode, dest);
1190 set_mem_align (dest, PARM_BOUNDARY);
1191 src = gen_rtx_MEM (BLKmode, incoming_args);
1192 set_mem_align (src, PARM_BOUNDARY);
1193 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1195 /* Refer to the argument block. */
1196 apply_args_size ();
1197 arguments = gen_rtx_MEM (BLKmode, arguments);
1198 set_mem_align (arguments, PARM_BOUNDARY);
1200 /* Walk past the arg-pointer and structure value address. */
1201 size = GET_MODE_SIZE (Pmode);
1202 if (struct_value)
1203 size += GET_MODE_SIZE (Pmode);
1205 /* Restore each of the registers previously saved. Make USE insns
1206 for each of these registers for use in making the call. */
1207 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1208 if ((mode = apply_args_mode[regno]) != VOIDmode)
1210 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1211 if (size % align != 0)
1212 size = CEIL (size, align) * align;
1213 reg = gen_rtx_REG (mode, regno);
1214 emit_move_insn (reg, adjust_address (arguments, mode, size));
1215 use_reg (&call_fusage, reg);
1216 size += GET_MODE_SIZE (mode);
1219 /* Restore the structure value address unless this is passed as an
1220 "invisible" first argument. */
1221 size = GET_MODE_SIZE (Pmode);
1222 if (struct_value)
1224 rtx value = gen_reg_rtx (Pmode);
1225 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1226 emit_move_insn (struct_value, value);
1227 if (GET_CODE (struct_value) == REG)
1228 use_reg (&call_fusage, struct_value);
1229 size += GET_MODE_SIZE (Pmode);
1232 /* All arguments and registers used for the call are set up by now! */
1233 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1235 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1236 and we don't want to load it into a register as an optimization,
1237 because prepare_call_address already did it if it should be done. */
1238 if (GET_CODE (function) != SYMBOL_REF)
1239 function = memory_address (FUNCTION_MODE, function);
1241 /* Generate the actual call instruction and save the return value. */
1242 #ifdef HAVE_untyped_call
1243 if (HAVE_untyped_call)
1244 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1245 result, result_vector (1, result)));
1246 else
1247 #endif
1248 #ifdef HAVE_call_value
1249 if (HAVE_call_value)
1251 rtx valreg = 0;
1253 /* Locate the unique return register. It is not possible to
1254 express a call that sets more than one return register using
1255 call_value; use untyped_call for that. In fact, untyped_call
1256 only needs to save the return registers in the given block. */
1257 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1258 if ((mode = apply_result_mode[regno]) != VOIDmode)
1260 if (valreg)
1261 abort (); /* HAVE_untyped_call required. */
1262 valreg = gen_rtx_REG (mode, regno);
1265 emit_call_insn (GEN_CALL_VALUE (valreg,
1266 gen_rtx_MEM (FUNCTION_MODE, function),
1267 const0_rtx, NULL_RTX, const0_rtx));
1269 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1271 else
1272 #endif
1273 abort ();
1275 /* Find the CALL insn we just emitted, and attach the register usage
1276 information. */
1277 call_insn = last_call_insn ();
1278 add_function_usage_to (call_insn, call_fusage);
1280 /* Restore the stack. */
1281 #ifdef HAVE_save_stack_nonlocal
1282 if (HAVE_save_stack_nonlocal)
1283 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1284 else
1285 #endif
1286 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1288 OK_DEFER_POP;
1290 /* Return the address of the result block. */
1291 result = copy_addr_to_reg (XEXP (result, 0));
1292 return convert_memory_address (ptr_mode, result);
1295 /* Perform an untyped return. */
1297 static void
1298 expand_builtin_return (rtx result)
1300 int size, align, regno;
1301 enum machine_mode mode;
1302 rtx reg;
1303 rtx call_fusage = 0;
1305 result = convert_memory_address (Pmode, result);
1307 apply_result_size ();
1308 result = gen_rtx_MEM (BLKmode, result);
1310 #ifdef HAVE_untyped_return
1311 if (HAVE_untyped_return)
1313 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1314 emit_barrier ();
1315 return;
1317 #endif
1319 /* Restore the return value and note that each value is used. */
1320 size = 0;
1321 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1322 if ((mode = apply_result_mode[regno]) != VOIDmode)
1324 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1325 if (size % align != 0)
1326 size = CEIL (size, align) * align;
1327 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1328 emit_move_insn (reg, adjust_address (result, mode, size));
1330 push_to_sequence (call_fusage);
1331 emit_insn (gen_rtx_USE (VOIDmode, reg));
1332 call_fusage = get_insns ();
1333 end_sequence ();
1334 size += GET_MODE_SIZE (mode);
1337 /* Put the USE insns before the return. */
1338 emit_insn (call_fusage);
1340 /* Return whatever values was restored by jumping directly to the end
1341 of the function. */
1342 expand_naked_return ();
1345 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1347 static enum type_class
1348 type_to_class (tree type)
1350 switch (TREE_CODE (type))
1352 case VOID_TYPE: return void_type_class;
1353 case INTEGER_TYPE: return integer_type_class;
1354 case CHAR_TYPE: return char_type_class;
1355 case ENUMERAL_TYPE: return enumeral_type_class;
1356 case BOOLEAN_TYPE: return boolean_type_class;
1357 case POINTER_TYPE: return pointer_type_class;
1358 case REFERENCE_TYPE: return reference_type_class;
1359 case OFFSET_TYPE: return offset_type_class;
1360 case REAL_TYPE: return real_type_class;
1361 case COMPLEX_TYPE: return complex_type_class;
1362 case FUNCTION_TYPE: return function_type_class;
1363 case METHOD_TYPE: return method_type_class;
1364 case RECORD_TYPE: return record_type_class;
1365 case UNION_TYPE:
1366 case QUAL_UNION_TYPE: return union_type_class;
1367 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1368 ? string_type_class : array_type_class);
1369 case SET_TYPE: return set_type_class;
1370 case FILE_TYPE: return file_type_class;
1371 case LANG_TYPE: return lang_type_class;
1372 default: return no_type_class;
1376 /* Expand a call to __builtin_classify_type with arguments found in
1377 ARGLIST. */
1379 static rtx
1380 expand_builtin_classify_type (tree arglist)
1382 if (arglist != 0)
1383 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1384 return GEN_INT (no_type_class);
1387 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1389 static rtx
1390 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1392 rtx tmp;
1394 if (arglist == 0)
1395 return const0_rtx;
1396 arglist = TREE_VALUE (arglist);
1398 /* We have taken care of the easy cases during constant folding. This
1399 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1400 get a chance to see if it can deduce whether ARGLIST is constant.
1401 If CSE isn't going to run, of course, don't bother waiting. */
1403 if (cse_not_expected)
1404 return const0_rtx;
1406 current_function_calls_constant_p = 1;
1408 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1409 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1410 return tmp;
1413 /* This helper macro, meant to be used in mathfn_built_in below,
1414 determines which among a set of three builtin math functions is
1415 appropriate for a given type mode. The `F' and `L' cases are
1416 automatically generated from the `double' case. */
1417 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1418 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1419 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1420 fcodel = BUILT_IN_MATHFN##L ; break;
1422 /* Return mathematic function equivalent to FN but operating directly
1423 on TYPE, if available. If we can't do the conversion, return zero. */
1424 tree
1425 mathfn_built_in (tree type, enum built_in_function fn)
1427 enum built_in_function fcode, fcodef, fcodel;
1429 switch (fn)
1431 CASE_MATHFN (BUILT_IN_ACOS)
1432 CASE_MATHFN (BUILT_IN_ACOSH)
1433 CASE_MATHFN (BUILT_IN_ASIN)
1434 CASE_MATHFN (BUILT_IN_ASINH)
1435 CASE_MATHFN (BUILT_IN_ATAN)
1436 CASE_MATHFN (BUILT_IN_ATAN2)
1437 CASE_MATHFN (BUILT_IN_ATANH)
1438 CASE_MATHFN (BUILT_IN_CBRT)
1439 CASE_MATHFN (BUILT_IN_CEIL)
1440 CASE_MATHFN (BUILT_IN_COPYSIGN)
1441 CASE_MATHFN (BUILT_IN_COS)
1442 CASE_MATHFN (BUILT_IN_COSH)
1443 CASE_MATHFN (BUILT_IN_DREM)
1444 CASE_MATHFN (BUILT_IN_ERF)
1445 CASE_MATHFN (BUILT_IN_ERFC)
1446 CASE_MATHFN (BUILT_IN_EXP)
1447 CASE_MATHFN (BUILT_IN_EXP10)
1448 CASE_MATHFN (BUILT_IN_EXP2)
1449 CASE_MATHFN (BUILT_IN_EXPM1)
1450 CASE_MATHFN (BUILT_IN_FABS)
1451 CASE_MATHFN (BUILT_IN_FDIM)
1452 CASE_MATHFN (BUILT_IN_FLOOR)
1453 CASE_MATHFN (BUILT_IN_FMA)
1454 CASE_MATHFN (BUILT_IN_FMAX)
1455 CASE_MATHFN (BUILT_IN_FMIN)
1456 CASE_MATHFN (BUILT_IN_FMOD)
1457 CASE_MATHFN (BUILT_IN_FREXP)
1458 CASE_MATHFN (BUILT_IN_GAMMA)
1459 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1460 CASE_MATHFN (BUILT_IN_HYPOT)
1461 CASE_MATHFN (BUILT_IN_ILOGB)
1462 CASE_MATHFN (BUILT_IN_INF)
1463 CASE_MATHFN (BUILT_IN_J0)
1464 CASE_MATHFN (BUILT_IN_J1)
1465 CASE_MATHFN (BUILT_IN_JN)
1466 CASE_MATHFN (BUILT_IN_LDEXP)
1467 CASE_MATHFN (BUILT_IN_LGAMMA)
1468 CASE_MATHFN (BUILT_IN_LLRINT)
1469 CASE_MATHFN (BUILT_IN_LLROUND)
1470 CASE_MATHFN (BUILT_IN_LOG)
1471 CASE_MATHFN (BUILT_IN_LOG10)
1472 CASE_MATHFN (BUILT_IN_LOG1P)
1473 CASE_MATHFN (BUILT_IN_LOG2)
1474 CASE_MATHFN (BUILT_IN_LOGB)
1475 CASE_MATHFN (BUILT_IN_LRINT)
1476 CASE_MATHFN (BUILT_IN_LROUND)
1477 CASE_MATHFN (BUILT_IN_MODF)
1478 CASE_MATHFN (BUILT_IN_NAN)
1479 CASE_MATHFN (BUILT_IN_NANS)
1480 CASE_MATHFN (BUILT_IN_NEARBYINT)
1481 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1482 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1483 CASE_MATHFN (BUILT_IN_POW)
1484 CASE_MATHFN (BUILT_IN_POW10)
1485 CASE_MATHFN (BUILT_IN_REMAINDER)
1486 CASE_MATHFN (BUILT_IN_REMQUO)
1487 CASE_MATHFN (BUILT_IN_RINT)
1488 CASE_MATHFN (BUILT_IN_ROUND)
1489 CASE_MATHFN (BUILT_IN_SCALB)
1490 CASE_MATHFN (BUILT_IN_SCALBLN)
1491 CASE_MATHFN (BUILT_IN_SCALBN)
1492 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1493 CASE_MATHFN (BUILT_IN_SIN)
1494 CASE_MATHFN (BUILT_IN_SINCOS)
1495 CASE_MATHFN (BUILT_IN_SINH)
1496 CASE_MATHFN (BUILT_IN_SQRT)
1497 CASE_MATHFN (BUILT_IN_TAN)
1498 CASE_MATHFN (BUILT_IN_TANH)
1499 CASE_MATHFN (BUILT_IN_TGAMMA)
1500 CASE_MATHFN (BUILT_IN_TRUNC)
1501 CASE_MATHFN (BUILT_IN_Y0)
1502 CASE_MATHFN (BUILT_IN_Y1)
1503 CASE_MATHFN (BUILT_IN_YN)
1505 default:
1506 return 0;
1509 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1510 return implicit_built_in_decls[fcode];
1511 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1512 return implicit_built_in_decls[fcodef];
1513 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1514 return implicit_built_in_decls[fcodel];
1515 else
1516 return 0;
1519 /* If errno must be maintained, expand the RTL to check if the result,
1520 TARGET, of a built-in function call, EXP, is NaN, and if so set
1521 errno to EDOM. */
1523 static void
1524 expand_errno_check (tree exp, rtx target)
1526 rtx lab = gen_label_rtx ();
1528 /* Test the result; if it is NaN, set errno=EDOM because
1529 the argument was not in the domain. */
1530 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1531 0, lab);
1533 #ifdef TARGET_EDOM
1534 /* If this built-in doesn't throw an exception, set errno directly. */
1535 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1537 #ifdef GEN_ERRNO_RTX
1538 rtx errno_rtx = GEN_ERRNO_RTX;
1539 #else
1540 rtx errno_rtx
1541 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1542 #endif
1543 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1544 emit_label (lab);
1545 return;
1547 #endif
1549 /* We can't set errno=EDOM directly; let the library call do it.
1550 Pop the arguments right away in case the call gets deleted. */
1551 NO_DEFER_POP;
1552 expand_call (exp, target, 0);
1553 OK_DEFER_POP;
1554 emit_label (lab);
1558 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1559 Return 0 if a normal call should be emitted rather than expanding the
1560 function in-line. EXP is the expression that is a call to the builtin
1561 function; if convenient, the result should be placed in TARGET.
1562 SUBTARGET may be used as the target for computing one of EXP's operands. */
1564 static rtx
1565 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1567 optab builtin_optab;
1568 rtx op0, insns, before_call;
1569 tree fndecl = get_callee_fndecl (exp);
1570 tree arglist = TREE_OPERAND (exp, 1);
1571 enum machine_mode mode;
1572 bool errno_set = false;
1573 tree arg, narg;
1575 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1576 return 0;
1578 arg = TREE_VALUE (arglist);
1580 switch (DECL_FUNCTION_CODE (fndecl))
1582 case BUILT_IN_SQRT:
1583 case BUILT_IN_SQRTF:
1584 case BUILT_IN_SQRTL:
1585 errno_set = ! tree_expr_nonnegative_p (arg);
1586 builtin_optab = sqrt_optab;
1587 break;
1588 case BUILT_IN_EXP:
1589 case BUILT_IN_EXPF:
1590 case BUILT_IN_EXPL:
1591 errno_set = true; builtin_optab = exp_optab; break;
1592 case BUILT_IN_EXP10:
1593 case BUILT_IN_EXP10F:
1594 case BUILT_IN_EXP10L:
1595 case BUILT_IN_POW10:
1596 case BUILT_IN_POW10F:
1597 case BUILT_IN_POW10L:
1598 errno_set = true; builtin_optab = exp10_optab; break;
1599 case BUILT_IN_EXP2:
1600 case BUILT_IN_EXP2F:
1601 case BUILT_IN_EXP2L:
1602 errno_set = true; builtin_optab = exp2_optab; break;
1603 case BUILT_IN_EXPM1:
1604 case BUILT_IN_EXPM1F:
1605 case BUILT_IN_EXPM1L:
1606 errno_set = true; builtin_optab = expm1_optab; break;
1607 case BUILT_IN_LOGB:
1608 case BUILT_IN_LOGBF:
1609 case BUILT_IN_LOGBL:
1610 errno_set = true; builtin_optab = logb_optab; break;
1611 case BUILT_IN_ILOGB:
1612 case BUILT_IN_ILOGBF:
1613 case BUILT_IN_ILOGBL:
1614 errno_set = true; builtin_optab = ilogb_optab; break;
1615 case BUILT_IN_LOG:
1616 case BUILT_IN_LOGF:
1617 case BUILT_IN_LOGL:
1618 errno_set = true; builtin_optab = log_optab; break;
1619 case BUILT_IN_LOG10:
1620 case BUILT_IN_LOG10F:
1621 case BUILT_IN_LOG10L:
1622 errno_set = true; builtin_optab = log10_optab; break;
1623 case BUILT_IN_LOG2:
1624 case BUILT_IN_LOG2F:
1625 case BUILT_IN_LOG2L:
1626 errno_set = true; builtin_optab = log2_optab; break;
1627 case BUILT_IN_ASIN:
1628 case BUILT_IN_ASINF:
1629 case BUILT_IN_ASINL:
1630 builtin_optab = asin_optab; break;
1631 case BUILT_IN_ACOS:
1632 case BUILT_IN_ACOSF:
1633 case BUILT_IN_ACOSL:
1634 builtin_optab = acos_optab; break;
1635 case BUILT_IN_TAN:
1636 case BUILT_IN_TANF:
1637 case BUILT_IN_TANL:
1638 builtin_optab = tan_optab; break;
1639 case BUILT_IN_ATAN:
1640 case BUILT_IN_ATANF:
1641 case BUILT_IN_ATANL:
1642 builtin_optab = atan_optab; break;
1643 case BUILT_IN_FLOOR:
1644 case BUILT_IN_FLOORF:
1645 case BUILT_IN_FLOORL:
1646 builtin_optab = floor_optab; break;
1647 case BUILT_IN_CEIL:
1648 case BUILT_IN_CEILF:
1649 case BUILT_IN_CEILL:
1650 builtin_optab = ceil_optab; break;
1651 case BUILT_IN_TRUNC:
1652 case BUILT_IN_TRUNCF:
1653 case BUILT_IN_TRUNCL:
1654 builtin_optab = btrunc_optab; break;
1655 case BUILT_IN_ROUND:
1656 case BUILT_IN_ROUNDF:
1657 case BUILT_IN_ROUNDL:
1658 builtin_optab = round_optab; break;
1659 case BUILT_IN_NEARBYINT:
1660 case BUILT_IN_NEARBYINTF:
1661 case BUILT_IN_NEARBYINTL:
1662 builtin_optab = nearbyint_optab; break;
1663 default:
1664 abort ();
1667 /* Make a suitable register to place result in. */
1668 mode = TYPE_MODE (TREE_TYPE (exp));
1670 if (! flag_errno_math || ! HONOR_NANS (mode))
1671 errno_set = false;
1673 /* Before working hard, check whether the instruction is available. */
1674 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1676 target = gen_reg_rtx (mode);
1678 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1679 need to expand the argument again. This way, we will not perform
1680 side-effects more the once. */
1681 narg = save_expr (arg);
1682 if (narg != arg)
1684 arglist = build_tree_list (NULL_TREE, arg);
1685 exp = build_function_call_expr (fndecl, arglist);
1688 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1690 emit_queue ();
1691 start_sequence ();
1693 /* Compute into TARGET.
1694 Set TARGET to wherever the result comes back. */
1695 target = expand_unop (mode, builtin_optab, op0, target, 0);
1697 if (target != 0)
1699 if (errno_set)
1700 expand_errno_check (exp, target);
1702 /* Output the entire sequence. */
1703 insns = get_insns ();
1704 end_sequence ();
1705 emit_insn (insns);
1706 return target;
1709 /* If we were unable to expand via the builtin, stop the sequence
1710 (without outputting the insns) and call to the library function
1711 with the stabilized argument list. */
1712 end_sequence ();
1715 before_call = get_last_insn ();
1717 target = expand_call (exp, target, target == const0_rtx);
1719 /* If this is a sqrt operation and we don't care about errno, try to
1720 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1721 This allows the semantics of the libcall to be visible to the RTL
1722 optimizers. */
1723 if (builtin_optab == sqrt_optab && !errno_set)
1725 /* Search backwards through the insns emitted by expand_call looking
1726 for the instruction with the REG_RETVAL note. */
1727 rtx last = get_last_insn ();
1728 while (last != before_call)
1730 if (find_reg_note (last, REG_RETVAL, NULL))
1732 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1733 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1734 two elements, i.e. symbol_ref(sqrt) and the operand. */
1735 if (note
1736 && GET_CODE (note) == EXPR_LIST
1737 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1738 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1739 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1741 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1742 /* Check operand is a register with expected mode. */
1743 if (operand
1744 && GET_CODE (operand) == REG
1745 && GET_MODE (operand) == mode)
1747 /* Replace the REG_EQUAL note with a SQRT rtx. */
1748 rtx equiv = gen_rtx_SQRT (mode, operand);
1749 set_unique_reg_note (last, REG_EQUAL, equiv);
1752 break;
1754 last = PREV_INSN (last);
1758 return target;
1761 /* Expand a call to the builtin binary math functions (pow and atan2).
1762 Return 0 if a normal call should be emitted rather than expanding the
1763 function in-line. EXP is the expression that is a call to the builtin
1764 function; if convenient, the result should be placed in TARGET.
1765 SUBTARGET may be used as the target for computing one of EXP's
1766 operands. */
1768 static rtx
1769 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1771 optab builtin_optab;
1772 rtx op0, op1, insns;
1773 tree fndecl = get_callee_fndecl (exp);
1774 tree arglist = TREE_OPERAND (exp, 1);
1775 tree arg0, arg1, temp, narg;
1776 enum machine_mode mode;
1777 bool errno_set = true;
1778 bool stable = true;
1780 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1781 return 0;
1783 arg0 = TREE_VALUE (arglist);
1784 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1786 switch (DECL_FUNCTION_CODE (fndecl))
1788 case BUILT_IN_POW:
1789 case BUILT_IN_POWF:
1790 case BUILT_IN_POWL:
1791 builtin_optab = pow_optab; break;
1792 case BUILT_IN_ATAN2:
1793 case BUILT_IN_ATAN2F:
1794 case BUILT_IN_ATAN2L:
1795 builtin_optab = atan2_optab; break;
1796 case BUILT_IN_FMOD:
1797 case BUILT_IN_FMODF:
1798 case BUILT_IN_FMODL:
1799 builtin_optab = fmod_optab; break;
1800 case BUILT_IN_DREM:
1801 case BUILT_IN_DREMF:
1802 case BUILT_IN_DREML:
1803 builtin_optab = drem_optab; break;
1804 default:
1805 abort ();
1808 /* Make a suitable register to place result in. */
1809 mode = TYPE_MODE (TREE_TYPE (exp));
1811 /* Before working hard, check whether the instruction is available. */
1812 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1813 return 0;
1815 target = gen_reg_rtx (mode);
1817 if (! flag_errno_math || ! HONOR_NANS (mode))
1818 errno_set = false;
1820 /* Alway stabilize the argument list. */
1821 narg = save_expr (arg1);
1822 if (narg != arg1)
1824 temp = build_tree_list (NULL_TREE, narg);
1825 stable = false;
1827 else
1828 temp = TREE_CHAIN (arglist);
1830 narg = save_expr (arg0);
1831 if (narg != arg0)
1833 arglist = tree_cons (NULL_TREE, narg, temp);
1834 stable = false;
1836 else if (! stable)
1837 arglist = tree_cons (NULL_TREE, arg0, temp);
1839 if (! stable)
1840 exp = build_function_call_expr (fndecl, arglist);
1842 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1843 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1845 emit_queue ();
1846 start_sequence ();
1848 /* Compute into TARGET.
1849 Set TARGET to wherever the result comes back. */
1850 target = expand_binop (mode, builtin_optab, op0, op1,
1851 target, 0, OPTAB_DIRECT);
1853 /* If we were unable to expand via the builtin, stop the sequence
1854 (without outputting the insns) and call to the library function
1855 with the stabilized argument list. */
1856 if (target == 0)
1858 end_sequence ();
1859 return expand_call (exp, target, target == const0_rtx);
1862 if (errno_set)
1863 expand_errno_check (exp, target);
1865 /* Output the entire sequence. */
1866 insns = get_insns ();
1867 end_sequence ();
1868 emit_insn (insns);
1870 return target;
1873 /* Expand a call to the builtin sin and cos math functions.
1874 Return 0 if a normal call should be emitted rather than expanding the
1875 function in-line. EXP is the expression that is a call to the builtin
1876 function; if convenient, the result should be placed in TARGET.
1877 SUBTARGET may be used as the target for computing one of EXP's
1878 operands. */
1880 static rtx
1881 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1883 optab builtin_optab;
1884 rtx op0, insns, before_call;
1885 tree fndecl = get_callee_fndecl (exp);
1886 tree arglist = TREE_OPERAND (exp, 1);
1887 enum machine_mode mode;
1888 bool errno_set = false;
1889 tree arg, narg;
1891 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1892 return 0;
1894 arg = TREE_VALUE (arglist);
1896 switch (DECL_FUNCTION_CODE (fndecl))
1898 case BUILT_IN_SIN:
1899 case BUILT_IN_SINF:
1900 case BUILT_IN_SINL:
1901 case BUILT_IN_COS:
1902 case BUILT_IN_COSF:
1903 case BUILT_IN_COSL:
1904 builtin_optab = sincos_optab; break;
1905 default:
1906 abort ();
1909 /* Make a suitable register to place result in. */
1910 mode = TYPE_MODE (TREE_TYPE (exp));
1912 if (! flag_errno_math || ! HONOR_NANS (mode))
1913 errno_set = false;
1915 /* Check if sincos insn is available, otherwise fallback
1916 to sin or cos insn. */
1917 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
1918 switch (DECL_FUNCTION_CODE (fndecl))
1920 case BUILT_IN_SIN:
1921 case BUILT_IN_SINF:
1922 case BUILT_IN_SINL:
1923 builtin_optab = sin_optab; break;
1924 case BUILT_IN_COS:
1925 case BUILT_IN_COSF:
1926 case BUILT_IN_COSL:
1927 builtin_optab = cos_optab; break;
1928 default:
1929 abort();
1933 /* Before working hard, check whether the instruction is available. */
1934 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1936 target = gen_reg_rtx (mode);
1938 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1939 need to expand the argument again. This way, we will not perform
1940 side-effects more the once. */
1941 narg = save_expr (arg);
1942 if (narg != arg)
1944 arglist = build_tree_list (NULL_TREE, arg);
1945 exp = build_function_call_expr (fndecl, arglist);
1948 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1950 emit_queue ();
1951 start_sequence ();
1953 /* Compute into TARGET.
1954 Set TARGET to wherever the result comes back. */
1955 if (builtin_optab == sincos_optab)
1957 switch (DECL_FUNCTION_CODE (fndecl))
1959 case BUILT_IN_SIN:
1960 case BUILT_IN_SINF:
1961 case BUILT_IN_SINL:
1962 if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
1963 abort();
1964 break;
1965 case BUILT_IN_COS:
1966 case BUILT_IN_COSF:
1967 case BUILT_IN_COSL:
1968 if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
1969 abort();
1970 break;
1971 default:
1972 abort();
1975 else
1977 target = expand_unop (mode, builtin_optab, op0, target, 0);
1980 if (target != 0)
1982 if (errno_set)
1983 expand_errno_check (exp, target);
1985 /* Output the entire sequence. */
1986 insns = get_insns ();
1987 end_sequence ();
1988 emit_insn (insns);
1989 return target;
1992 /* If we were unable to expand via the builtin, stop the sequence
1993 (without outputting the insns) and call to the library function
1994 with the stabilized argument list. */
1995 end_sequence ();
1998 before_call = get_last_insn ();
2000 target = expand_call (exp, target, target == const0_rtx);
2002 return target;
2005 /* To evaluate powi(x,n), the floating point value x raised to the
2006 constant integer exponent n, we use a hybrid algorithm that
2007 combines the "window method" with look-up tables. For an
2008 introduction to exponentiation algorithms and "addition chains",
2009 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2010 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2011 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2012 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2014 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2015 multiplications to inline before calling the system library's pow
2016 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2017 so this default never requires calling pow, powf or powl. */
2019 #ifndef POWI_MAX_MULTS
2020 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2021 #endif
2023 /* The size of the "optimal power tree" lookup table. All
2024 exponents less than this value are simply looked up in the
2025 powi_table below. This threshold is also used to size the
2026 cache of pseudo registers that hold intermediate results. */
2027 #define POWI_TABLE_SIZE 256
2029 /* The size, in bits of the window, used in the "window method"
2030 exponentiation algorithm. This is equivalent to a radix of
2031 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2032 #define POWI_WINDOW_SIZE 3
2034 /* The following table is an efficient representation of an
2035 "optimal power tree". For each value, i, the corresponding
2036 value, j, in the table states than an optimal evaluation
2037 sequence for calculating pow(x,i) can be found by evaluating
2038 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2039 100 integers is given in Knuth's "Seminumerical algorithms". */
2041 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2043 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2044 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2045 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2046 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2047 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2048 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2049 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2050 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2051 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2052 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2053 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2054 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2055 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2056 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2057 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2058 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2059 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2060 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2061 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2062 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2063 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2064 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2065 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2066 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2067 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2068 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2069 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2070 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2071 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2072 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2073 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2074 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2078 /* Return the number of multiplications required to calculate
2079 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2080 subroutine of powi_cost. CACHE is an array indicating
2081 which exponents have already been calculated. */
2083 static int
2084 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2086 /* If we've already calculated this exponent, then this evaluation
2087 doesn't require any additional multiplications. */
2088 if (cache[n])
2089 return 0;
2091 cache[n] = true;
2092 return powi_lookup_cost (n - powi_table[n], cache)
2093 + powi_lookup_cost (powi_table[n], cache) + 1;
2096 /* Return the number of multiplications required to calculate
2097 powi(x,n) for an arbitrary x, given the exponent N. This
2098 function needs to be kept in sync with expand_powi below. */
2100 static int
2101 powi_cost (HOST_WIDE_INT n)
2103 bool cache[POWI_TABLE_SIZE];
2104 unsigned HOST_WIDE_INT digit;
2105 unsigned HOST_WIDE_INT val;
2106 int result;
2108 if (n == 0)
2109 return 0;
2111 /* Ignore the reciprocal when calculating the cost. */
2112 val = (n < 0) ? -n : n;
2114 /* Initialize the exponent cache. */
2115 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2116 cache[1] = true;
2118 result = 0;
2120 while (val >= POWI_TABLE_SIZE)
2122 if (val & 1)
2124 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2125 result += powi_lookup_cost (digit, cache)
2126 + POWI_WINDOW_SIZE + 1;
2127 val >>= POWI_WINDOW_SIZE;
2129 else
2131 val >>= 1;
2132 result++;
2136 return result + powi_lookup_cost (val, cache);
2139 /* Recursive subroutine of expand_powi. This function takes the array,
2140 CACHE, of already calculated exponents and an exponent N and returns
2141 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2143 static rtx
2144 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2146 unsigned HOST_WIDE_INT digit;
2147 rtx target, result;
2148 rtx op0, op1;
2150 if (n < POWI_TABLE_SIZE)
2152 if (cache[n])
2153 return cache[n];
2155 target = gen_reg_rtx (mode);
2156 cache[n] = target;
2158 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2159 op1 = expand_powi_1 (mode, powi_table[n], cache);
2161 else if (n & 1)
2163 target = gen_reg_rtx (mode);
2164 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2165 op0 = expand_powi_1 (mode, n - digit, cache);
2166 op1 = expand_powi_1 (mode, digit, cache);
2168 else
2170 target = gen_reg_rtx (mode);
2171 op0 = expand_powi_1 (mode, n >> 1, cache);
2172 op1 = op0;
2175 result = expand_mult (mode, op0, op1, target, 0);
2176 if (result != target)
2177 emit_move_insn (target, result);
2178 return target;
2181 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2182 floating point operand in mode MODE, and N is the exponent. This
2183 function needs to be kept in sync with powi_cost above. */
2185 static rtx
2186 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2188 unsigned HOST_WIDE_INT val;
2189 rtx cache[POWI_TABLE_SIZE];
2190 rtx result;
2192 if (n == 0)
2193 return CONST1_RTX (mode);
2195 val = (n < 0) ? -n : n;
2197 memset (cache, 0, sizeof (cache));
2198 cache[1] = x;
2200 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2202 /* If the original exponent was negative, reciprocate the result. */
2203 if (n < 0)
2204 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2205 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2207 return result;
2210 /* Expand a call to the pow built-in mathematical function. Return 0 if
2211 a normal call should be emitted rather than expanding the function
2212 in-line. EXP is the expression that is a call to the builtin
2213 function; if convenient, the result should be placed in TARGET. */
2215 static rtx
2216 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2218 tree arglist = TREE_OPERAND (exp, 1);
2219 tree arg0, arg1;
2221 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2222 return 0;
2224 arg0 = TREE_VALUE (arglist);
2225 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2227 if (TREE_CODE (arg1) == REAL_CST
2228 && ! TREE_CONSTANT_OVERFLOW (arg1))
2230 REAL_VALUE_TYPE cint;
2231 REAL_VALUE_TYPE c;
2232 HOST_WIDE_INT n;
2234 c = TREE_REAL_CST (arg1);
2235 n = real_to_integer (&c);
2236 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2237 if (real_identical (&c, &cint))
2239 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2240 Otherwise, check the number of multiplications required.
2241 Note that pow never sets errno for an integer exponent. */
2242 if ((n >= -1 && n <= 2)
2243 || (flag_unsafe_math_optimizations
2244 && ! optimize_size
2245 && powi_cost (n) <= POWI_MAX_MULTS))
2247 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2248 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2249 op = force_reg (mode, op);
2250 return expand_powi (op, mode, n);
2255 if (! flag_unsafe_math_optimizations)
2256 return NULL_RTX;
2257 return expand_builtin_mathfn_2 (exp, target, subtarget);
2260 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2261 if we failed the caller should emit a normal call, otherwise
2262 try to get the result in TARGET, if convenient. */
2264 static rtx
2265 expand_builtin_strlen (tree arglist, rtx target,
2266 enum machine_mode target_mode)
2268 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2269 return 0;
2270 else
2272 rtx pat;
2273 tree len, src = TREE_VALUE (arglist);
2274 rtx result, src_reg, char_rtx, before_strlen;
2275 enum machine_mode insn_mode = target_mode, char_mode;
2276 enum insn_code icode = CODE_FOR_nothing;
2277 int align;
2279 /* If the length can be computed at compile-time, return it. */
2280 len = c_strlen (src, 0);
2281 if (len)
2282 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2284 /* If the length can be computed at compile-time and is constant
2285 integer, but there are side-effects in src, evaluate
2286 src for side-effects, then return len.
2287 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2288 can be optimized into: i++; x = 3; */
2289 len = c_strlen (src, 1);
2290 if (len && TREE_CODE (len) == INTEGER_CST)
2292 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2293 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2296 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2298 /* If SRC is not a pointer type, don't do this operation inline. */
2299 if (align == 0)
2300 return 0;
2302 /* Bail out if we can't compute strlen in the right mode. */
2303 while (insn_mode != VOIDmode)
2305 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2306 if (icode != CODE_FOR_nothing)
2307 break;
2309 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2311 if (insn_mode == VOIDmode)
2312 return 0;
2314 /* Make a place to write the result of the instruction. */
2315 result = target;
2316 if (! (result != 0
2317 && GET_CODE (result) == REG
2318 && GET_MODE (result) == insn_mode
2319 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2320 result = gen_reg_rtx (insn_mode);
2322 /* Make a place to hold the source address. We will not expand
2323 the actual source until we are sure that the expansion will
2324 not fail -- there are trees that cannot be expanded twice. */
2325 src_reg = gen_reg_rtx (Pmode);
2327 /* Mark the beginning of the strlen sequence so we can emit the
2328 source operand later. */
2329 before_strlen = get_last_insn ();
2331 char_rtx = const0_rtx;
2332 char_mode = insn_data[(int) icode].operand[2].mode;
2333 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2334 char_mode))
2335 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2337 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2338 char_rtx, GEN_INT (align));
2339 if (! pat)
2340 return 0;
2341 emit_insn (pat);
2343 /* Now that we are assured of success, expand the source. */
2344 start_sequence ();
2345 pat = memory_address (BLKmode,
2346 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2347 if (pat != src_reg)
2348 emit_move_insn (src_reg, pat);
2349 pat = get_insns ();
2350 end_sequence ();
2352 if (before_strlen)
2353 emit_insn_after (pat, before_strlen);
2354 else
2355 emit_insn_before (pat, get_insns ());
2357 /* Return the value in the proper mode for this function. */
2358 if (GET_MODE (result) == target_mode)
2359 target = result;
2360 else if (target != 0)
2361 convert_move (target, result, 0);
2362 else
2363 target = convert_to_mode (target_mode, result, 0);
2365 return target;
2369 /* Expand a call to the strstr builtin. Return 0 if we failed the
2370 caller should emit a normal call, otherwise try to get the result
2371 in TARGET, if convenient (and in mode MODE if that's convenient). */
2373 static rtx
2374 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2376 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2377 return 0;
2378 else
2380 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2381 tree fn;
2382 const char *p1, *p2;
2384 p2 = c_getstr (s2);
2385 if (p2 == NULL)
2386 return 0;
2388 p1 = c_getstr (s1);
2389 if (p1 != NULL)
2391 const char *r = strstr (p1, p2);
2393 if (r == NULL)
2394 return const0_rtx;
2396 /* Return an offset into the constant string argument. */
2397 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2398 fold_convert (TREE_TYPE (s1),
2399 ssize_int (r - p1)))),
2400 target, mode, EXPAND_NORMAL);
2403 if (p2[0] == '\0')
2404 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2406 if (p2[1] != '\0')
2407 return 0;
2409 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2410 if (!fn)
2411 return 0;
2413 /* New argument list transforming strstr(s1, s2) to
2414 strchr(s1, s2[0]). */
2415 arglist =
2416 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2417 arglist = tree_cons (NULL_TREE, s1, arglist);
2418 return expand_expr (build_function_call_expr (fn, arglist),
2419 target, mode, EXPAND_NORMAL);
2423 /* Expand a call to the strchr builtin. Return 0 if we failed the
2424 caller should emit a normal call, otherwise try to get the result
2425 in TARGET, if convenient (and in mode MODE if that's convenient). */
2427 static rtx
2428 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2430 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2431 return 0;
2432 else
2434 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2435 const char *p1;
2437 if (TREE_CODE (s2) != INTEGER_CST)
2438 return 0;
2440 p1 = c_getstr (s1);
2441 if (p1 != NULL)
2443 char c;
2444 const char *r;
2446 if (target_char_cast (s2, &c))
2447 return 0;
2449 r = strchr (p1, c);
2451 if (r == NULL)
2452 return const0_rtx;
2454 /* Return an offset into the constant string argument. */
2455 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2456 fold_convert (TREE_TYPE (s1),
2457 ssize_int (r - p1)))),
2458 target, mode, EXPAND_NORMAL);
2461 /* FIXME: Should use here strchrM optab so that ports can optimize
2462 this. */
2463 return 0;
2467 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2468 caller should emit a normal call, otherwise try to get the result
2469 in TARGET, if convenient (and in mode MODE if that's convenient). */
2471 static rtx
2472 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2474 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2475 return 0;
2476 else
2478 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2479 tree fn;
2480 const char *p1;
2482 if (TREE_CODE (s2) != INTEGER_CST)
2483 return 0;
2485 p1 = c_getstr (s1);
2486 if (p1 != NULL)
2488 char c;
2489 const char *r;
2491 if (target_char_cast (s2, &c))
2492 return 0;
2494 r = strrchr (p1, c);
2496 if (r == NULL)
2497 return const0_rtx;
2499 /* Return an offset into the constant string argument. */
2500 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2501 fold_convert (TREE_TYPE (s1),
2502 ssize_int (r - p1)))),
2503 target, mode, EXPAND_NORMAL);
2506 if (! integer_zerop (s2))
2507 return 0;
2509 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2510 if (!fn)
2511 return 0;
2513 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2514 return expand_expr (build_function_call_expr (fn, arglist),
2515 target, mode, EXPAND_NORMAL);
2519 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2520 caller should emit a normal call, otherwise try to get the result
2521 in TARGET, if convenient (and in mode MODE if that's convenient). */
2523 static rtx
2524 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2526 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2527 return 0;
2528 else
2530 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2531 tree fn;
2532 const char *p1, *p2;
2534 p2 = c_getstr (s2);
2535 if (p2 == NULL)
2536 return 0;
2538 p1 = c_getstr (s1);
2539 if (p1 != NULL)
2541 const char *r = strpbrk (p1, p2);
2543 if (r == NULL)
2544 return const0_rtx;
2546 /* Return an offset into the constant string argument. */
2547 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2548 fold_convert (TREE_TYPE (s1),
2549 ssize_int (r - p1)))),
2550 target, mode, EXPAND_NORMAL);
2553 if (p2[0] == '\0')
2555 /* strpbrk(x, "") == NULL.
2556 Evaluate and ignore the arguments in case they had
2557 side-effects. */
2558 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2559 return const0_rtx;
2562 if (p2[1] != '\0')
2563 return 0; /* Really call strpbrk. */
2565 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2566 if (!fn)
2567 return 0;
2569 /* New argument list transforming strpbrk(s1, s2) to
2570 strchr(s1, s2[0]). */
2571 arglist =
2572 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2573 arglist = tree_cons (NULL_TREE, s1, arglist);
2574 return expand_expr (build_function_call_expr (fn, arglist),
2575 target, mode, EXPAND_NORMAL);
2579 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2580 bytes from constant string DATA + OFFSET and return it as target
2581 constant. */
2583 static rtx
2584 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2585 enum machine_mode mode)
2587 const char *str = (const char *) data;
2589 if (offset < 0
2590 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2591 > strlen (str) + 1))
2592 abort (); /* Attempt to read past the end of constant string. */
2594 return c_readstr (str + offset, mode);
2597 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2598 Return 0 if we failed, the caller should emit a normal call,
2599 otherwise try to get the result in TARGET, if convenient (and in
2600 mode MODE if that's convenient). */
2601 static rtx
2602 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2604 if (!validate_arglist (arglist,
2605 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2606 return 0;
2607 else
2609 tree dest = TREE_VALUE (arglist);
2610 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2611 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2612 const char *src_str;
2613 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2614 unsigned int dest_align
2615 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2616 rtx dest_mem, src_mem, dest_addr, len_rtx;
2618 /* If DEST is not a pointer type, call the normal function. */
2619 if (dest_align == 0)
2620 return 0;
2622 /* If the LEN parameter is zero, return DEST. */
2623 if (integer_zerop (len))
2625 /* Evaluate and ignore SRC in case it has side-effects. */
2626 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2627 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2630 /* If SRC and DEST are the same (and not volatile), return DEST. */
2631 if (operand_equal_p (src, dest, 0))
2633 /* Evaluate and ignore LEN in case it has side-effects. */
2634 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2635 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2638 /* If either SRC is not a pointer type, don't do this
2639 operation in-line. */
2640 if (src_align == 0)
2641 return 0;
2643 dest_mem = get_memory_rtx (dest);
2644 set_mem_align (dest_mem, dest_align);
2645 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2646 src_str = c_getstr (src);
2648 /* If SRC is a string constant and block move would be done
2649 by pieces, we can avoid loading the string from memory
2650 and only stored the computed constants. */
2651 if (src_str
2652 && GET_CODE (len_rtx) == CONST_INT
2653 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2654 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2655 (void *) src_str, dest_align))
2657 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2658 builtin_memcpy_read_str,
2659 (void *) src_str, dest_align, 0);
2660 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2661 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2662 return dest_mem;
2665 src_mem = get_memory_rtx (src);
2666 set_mem_align (src_mem, src_align);
2668 /* Copy word part most expediently. */
2669 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2670 BLOCK_OP_NORMAL);
2672 if (dest_addr == 0)
2674 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2675 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2677 return dest_addr;
2681 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2682 Return 0 if we failed the caller should emit a normal call,
2683 otherwise try to get the result in TARGET, if convenient (and in
2684 mode MODE if that's convenient). If ENDP is 0 return the
2685 destination pointer, if ENDP is 1 return the end pointer ala
2686 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2687 stpcpy. */
2689 static rtx
2690 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2691 int endp)
2693 if (!validate_arglist (arglist,
2694 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2695 return 0;
2696 /* If return value is ignored, transform mempcpy into memcpy. */
2697 else if (target == const0_rtx)
2699 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2701 if (!fn)
2702 return 0;
2704 return expand_expr (build_function_call_expr (fn, arglist),
2705 target, mode, EXPAND_NORMAL);
2707 else
2709 tree dest = TREE_VALUE (arglist);
2710 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2711 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2712 const char *src_str;
2713 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2714 unsigned int dest_align
2715 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2716 rtx dest_mem, src_mem, len_rtx;
2718 /* If DEST is not a pointer type, call the normal function. */
2719 if (dest_align == 0)
2720 return 0;
2722 /* If SRC and DEST are the same (and not volatile), do nothing. */
2723 if (operand_equal_p (src, dest, 0))
2725 tree expr;
2727 if (endp == 0)
2729 /* Evaluate and ignore LEN in case it has side-effects. */
2730 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2731 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2734 if (endp == 2)
2735 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2736 integer_one_node));
2737 len = fold_convert (TREE_TYPE (dest), len);
2738 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2739 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2742 /* If LEN is not constant, call the normal function. */
2743 if (! host_integerp (len, 1))
2744 return 0;
2746 /* If the LEN parameter is zero, return DEST. */
2747 if (tree_low_cst (len, 1) == 0)
2749 /* Evaluate and ignore SRC in case it has side-effects. */
2750 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2751 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2754 /* If either SRC is not a pointer type, don't do this
2755 operation in-line. */
2756 if (src_align == 0)
2757 return 0;
2759 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2760 src_str = c_getstr (src);
2762 /* If SRC is a string constant and block move would be done
2763 by pieces, we can avoid loading the string from memory
2764 and only stored the computed constants. */
2765 if (src_str
2766 && GET_CODE (len_rtx) == CONST_INT
2767 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2768 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2769 (void *) src_str, dest_align))
2771 dest_mem = get_memory_rtx (dest);
2772 set_mem_align (dest_mem, dest_align);
2773 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2774 builtin_memcpy_read_str,
2775 (void *) src_str, dest_align, endp);
2776 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2777 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2778 return dest_mem;
2781 if (GET_CODE (len_rtx) == CONST_INT
2782 && can_move_by_pieces (INTVAL (len_rtx),
2783 MIN (dest_align, src_align)))
2785 dest_mem = get_memory_rtx (dest);
2786 set_mem_align (dest_mem, dest_align);
2787 src_mem = get_memory_rtx (src);
2788 set_mem_align (src_mem, src_align);
2789 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2790 MIN (dest_align, src_align), endp);
2791 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2792 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2793 return dest_mem;
2796 return 0;
2800 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2801 if we failed the caller should emit a normal call. */
2803 static rtx
2804 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2806 if (!validate_arglist (arglist,
2807 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2808 return 0;
2809 else
2811 tree dest = TREE_VALUE (arglist);
2812 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2813 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2815 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2816 unsigned int dest_align
2817 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2819 /* If DEST is not a pointer type, call the normal function. */
2820 if (dest_align == 0)
2821 return 0;
2823 /* If the LEN parameter is zero, return DEST. */
2824 if (integer_zerop (len))
2826 /* Evaluate and ignore SRC in case it has side-effects. */
2827 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2828 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2831 /* If SRC and DEST are the same (and not volatile), return DEST. */
2832 if (operand_equal_p (src, dest, 0))
2834 /* Evaluate and ignore LEN in case it has side-effects. */
2835 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2836 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2839 /* If either SRC is not a pointer type, don't do this
2840 operation in-line. */
2841 if (src_align == 0)
2842 return 0;
2844 /* If src is categorized for a readonly section we can use
2845 normal memcpy. */
2846 if (readonly_data_expr (src))
2848 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2849 if (!fn)
2850 return 0;
2851 return expand_expr (build_function_call_expr (fn, arglist),
2852 target, mode, EXPAND_NORMAL);
2855 /* Otherwise, call the normal function. */
2856 return 0;
2860 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2861 if we failed the caller should emit a normal call. */
2863 static rtx
2864 expand_builtin_bcopy (tree arglist)
2866 tree src, dest, size, newarglist;
2868 if (!validate_arglist (arglist,
2869 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2870 return NULL_RTX;
2872 src = TREE_VALUE (arglist);
2873 dest = TREE_VALUE (TREE_CHAIN (arglist));
2874 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2876 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2877 memmove(ptr y, ptr x, size_t z). This is done this way
2878 so that if it isn't expanded inline, we fallback to
2879 calling bcopy instead of memmove. */
2881 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2882 newarglist = tree_cons (NULL_TREE, src, newarglist);
2883 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2885 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2888 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2889 if we failed the caller should emit a normal call, otherwise try to get
2890 the result in TARGET, if convenient (and in mode MODE if that's
2891 convenient). */
2893 static rtx
2894 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2896 tree fn, len, src, dst;
2898 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2899 return 0;
2901 src = TREE_VALUE (TREE_CHAIN (arglist));
2902 dst = TREE_VALUE (arglist);
2904 /* If SRC and DST are equal (and not volatile), return DST. */
2905 if (operand_equal_p (src, dst, 0))
2906 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2908 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2909 if (!fn)
2910 return 0;
2912 len = c_strlen (src, 1);
2913 if (len == 0 || TREE_SIDE_EFFECTS (len))
2914 return 0;
2916 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2917 arglist = build_tree_list (NULL_TREE, len);
2918 arglist = tree_cons (NULL_TREE, src, arglist);
2919 arglist = tree_cons (NULL_TREE, dst, arglist);
2920 return expand_expr (build_function_call_expr (fn, arglist),
2921 target, mode, EXPAND_NORMAL);
2924 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2925 Return 0 if we failed the caller should emit a normal call,
2926 otherwise try to get the result in TARGET, if convenient (and in
2927 mode MODE if that's convenient). */
2929 static rtx
2930 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2932 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2933 return 0;
2934 else
2936 tree dst, src, len;
2938 /* If return value is ignored, transform stpcpy into strcpy. */
2939 if (target == const0_rtx)
2941 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2942 if (!fn)
2943 return 0;
2945 return expand_expr (build_function_call_expr (fn, arglist),
2946 target, mode, EXPAND_NORMAL);
2949 /* Ensure we get an actual string whose length can be evaluated at
2950 compile-time, not an expression containing a string. This is
2951 because the latter will potentially produce pessimized code
2952 when used to produce the return value. */
2953 src = TREE_VALUE (TREE_CHAIN (arglist));
2954 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2955 return 0;
2957 dst = TREE_VALUE (arglist);
2958 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2959 arglist = build_tree_list (NULL_TREE, len);
2960 arglist = tree_cons (NULL_TREE, src, arglist);
2961 arglist = tree_cons (NULL_TREE, dst, arglist);
2962 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2966 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2967 bytes from constant string DATA + OFFSET and return it as target
2968 constant. */
2970 static rtx
2971 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2972 enum machine_mode mode)
2974 const char *str = (const char *) data;
2976 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2977 return const0_rtx;
2979 return c_readstr (str + offset, mode);
2982 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2983 if we failed the caller should emit a normal call. */
2985 static rtx
2986 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2988 if (!validate_arglist (arglist,
2989 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2990 return 0;
2991 else
2993 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2994 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2995 tree fn;
2997 /* We must be passed a constant len parameter. */
2998 if (TREE_CODE (len) != INTEGER_CST)
2999 return 0;
3001 /* If the len parameter is zero, return the dst parameter. */
3002 if (integer_zerop (len))
3004 /* Evaluate and ignore the src argument in case it has
3005 side-effects. */
3006 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3007 VOIDmode, EXPAND_NORMAL);
3008 /* Return the dst parameter. */
3009 return expand_expr (TREE_VALUE (arglist), target, mode,
3010 EXPAND_NORMAL);
3013 /* Now, we must be passed a constant src ptr parameter. */
3014 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3015 return 0;
3017 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3019 /* We're required to pad with trailing zeros if the requested
3020 len is greater than strlen(s2)+1. In that case try to
3021 use store_by_pieces, if it fails, punt. */
3022 if (tree_int_cst_lt (slen, len))
3024 tree dest = TREE_VALUE (arglist);
3025 unsigned int dest_align
3026 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3027 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3028 rtx dest_mem;
3030 if (!p || dest_align == 0 || !host_integerp (len, 1)
3031 || !can_store_by_pieces (tree_low_cst (len, 1),
3032 builtin_strncpy_read_str,
3033 (void *) p, dest_align))
3034 return 0;
3036 dest_mem = get_memory_rtx (dest);
3037 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3038 builtin_strncpy_read_str,
3039 (void *) p, dest_align, 0);
3040 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3041 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3042 return dest_mem;
3045 /* OK transform into builtin memcpy. */
3046 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3047 if (!fn)
3048 return 0;
3049 return expand_expr (build_function_call_expr (fn, arglist),
3050 target, mode, EXPAND_NORMAL);
3054 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3055 bytes from constant string DATA + OFFSET and return it as target
3056 constant. */
3058 static rtx
3059 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3060 enum machine_mode mode)
3062 const char *c = (const char *) data;
3063 char *p = alloca (GET_MODE_SIZE (mode));
3065 memset (p, *c, GET_MODE_SIZE (mode));
3067 return c_readstr (p, mode);
3070 /* Callback routine for store_by_pieces. Return the RTL of a register
3071 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3072 char value given in the RTL register data. For example, if mode is
3073 4 bytes wide, return the RTL for 0x01010101*data. */
3075 static rtx
3076 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3077 enum machine_mode mode)
3079 rtx target, coeff;
3080 size_t size;
3081 char *p;
3083 size = GET_MODE_SIZE (mode);
3084 if (size == 1)
3085 return (rtx) data;
3087 p = alloca (size);
3088 memset (p, 1, size);
3089 coeff = c_readstr (p, mode);
3091 target = convert_to_mode (mode, (rtx) data, 1);
3092 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3093 return force_reg (mode, target);
3096 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3097 if we failed the caller should emit a normal call, otherwise try to get
3098 the result in TARGET, if convenient (and in mode MODE if that's
3099 convenient). */
3101 static rtx
3102 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3104 if (!validate_arglist (arglist,
3105 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3106 return 0;
3107 else
3109 tree dest = TREE_VALUE (arglist);
3110 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3111 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3112 char c;
3114 unsigned int dest_align
3115 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3116 rtx dest_mem, dest_addr, len_rtx;
3118 /* If DEST is not a pointer type, don't do this
3119 operation in-line. */
3120 if (dest_align == 0)
3121 return 0;
3123 /* If the LEN parameter is zero, return DEST. */
3124 if (integer_zerop (len))
3126 /* Evaluate and ignore VAL in case it has side-effects. */
3127 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3128 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3131 if (TREE_CODE (val) != INTEGER_CST)
3133 rtx val_rtx;
3135 if (!host_integerp (len, 1))
3136 return 0;
3138 if (optimize_size && tree_low_cst (len, 1) > 1)
3139 return 0;
3141 /* Assume that we can memset by pieces if we can store the
3142 * the coefficients by pieces (in the required modes).
3143 * We can't pass builtin_memset_gen_str as that emits RTL. */
3144 c = 1;
3145 if (!can_store_by_pieces (tree_low_cst (len, 1),
3146 builtin_memset_read_str,
3147 &c, dest_align))
3148 return 0;
3150 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3151 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3152 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3153 val_rtx);
3154 dest_mem = get_memory_rtx (dest);
3155 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3156 builtin_memset_gen_str,
3157 val_rtx, dest_align, 0);
3158 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3159 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3160 return dest_mem;
3163 if (target_char_cast (val, &c))
3164 return 0;
3166 if (c)
3168 if (!host_integerp (len, 1))
3169 return 0;
3170 if (!can_store_by_pieces (tree_low_cst (len, 1),
3171 builtin_memset_read_str, &c,
3172 dest_align))
3173 return 0;
3175 dest_mem = get_memory_rtx (dest);
3176 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3177 builtin_memset_read_str,
3178 &c, dest_align, 0);
3179 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3180 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3181 return dest_mem;
3184 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3186 dest_mem = get_memory_rtx (dest);
3187 set_mem_align (dest_mem, dest_align);
3188 dest_addr = clear_storage (dest_mem, len_rtx);
3190 if (dest_addr == 0)
3192 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3193 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3196 return dest_addr;
3200 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3201 if we failed the caller should emit a normal call. */
3203 static rtx
3204 expand_builtin_bzero (tree arglist)
3206 tree dest, size, newarglist;
3208 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3209 return NULL_RTX;
3211 dest = TREE_VALUE (arglist);
3212 size = TREE_VALUE (TREE_CHAIN (arglist));
3214 /* New argument list transforming bzero(ptr x, int y) to
3215 memset(ptr x, int 0, size_t y). This is done this way
3216 so that if it isn't expanded inline, we fallback to
3217 calling bzero instead of memset. */
3219 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3220 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3221 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3223 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3226 /* Expand expression EXP, which is a call to the memcmp built-in function.
3227 ARGLIST is the argument list for this call. Return 0 if we failed and the
3228 caller should emit a normal call, otherwise try to get the result in
3229 TARGET, if convenient (and in mode MODE, if that's convenient). */
3231 static rtx
3232 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3233 enum machine_mode mode)
3235 tree arg1, arg2, len;
3236 const char *p1, *p2;
3238 if (!validate_arglist (arglist,
3239 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3240 return 0;
3242 arg1 = TREE_VALUE (arglist);
3243 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3244 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3246 /* If the len parameter is zero, return zero. */
3247 if (integer_zerop (len))
3249 /* Evaluate and ignore arg1 and arg2 in case they have
3250 side-effects. */
3251 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3252 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3253 return const0_rtx;
3256 /* If both arguments are equal (and not volatile), return zero. */
3257 if (operand_equal_p (arg1, arg2, 0))
3259 /* Evaluate and ignore len in case it has side-effects. */
3260 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3261 return const0_rtx;
3264 p1 = c_getstr (arg1);
3265 p2 = c_getstr (arg2);
3267 /* If all arguments are constant, and the value of len is not greater
3268 than the lengths of arg1 and arg2, evaluate at compile-time. */
3269 if (host_integerp (len, 1) && p1 && p2
3270 && compare_tree_int (len, strlen (p1) + 1) <= 0
3271 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3273 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3275 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3278 /* If len parameter is one, return an expression corresponding to
3279 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3280 if (integer_onep (len))
3282 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3283 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3284 tree ind1 =
3285 fold (build1 (CONVERT_EXPR, integer_type_node,
3286 build1 (INDIRECT_REF, cst_uchar_node,
3287 fold_convert (cst_uchar_ptr_node, arg1))));
3288 tree ind2 =
3289 fold (build1 (CONVERT_EXPR, integer_type_node,
3290 build1 (INDIRECT_REF, cst_uchar_node,
3291 fold_convert (cst_uchar_ptr_node, arg2))));
3292 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3293 return expand_expr (result, target, mode, EXPAND_NORMAL);
3296 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3298 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3299 rtx result;
3300 rtx insn;
3302 int arg1_align
3303 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3304 int arg2_align
3305 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3306 enum machine_mode insn_mode;
3308 #ifdef HAVE_cmpmemsi
3309 if (HAVE_cmpmemsi)
3310 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3311 else
3312 #endif
3313 #ifdef HAVE_cmpstrsi
3314 if (HAVE_cmpstrsi)
3315 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3316 else
3317 #endif
3318 return 0;
3320 /* If we don't have POINTER_TYPE, call the function. */
3321 if (arg1_align == 0 || arg2_align == 0)
3322 return 0;
3324 /* Make a place to write the result of the instruction. */
3325 result = target;
3326 if (! (result != 0
3327 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3328 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3329 result = gen_reg_rtx (insn_mode);
3331 arg1_rtx = get_memory_rtx (arg1);
3332 arg2_rtx = get_memory_rtx (arg2);
3333 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3334 #ifdef HAVE_cmpmemsi
3335 if (HAVE_cmpmemsi)
3336 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3337 GEN_INT (MIN (arg1_align, arg2_align)));
3338 else
3339 #endif
3340 #ifdef HAVE_cmpstrsi
3341 if (HAVE_cmpstrsi)
3342 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3343 GEN_INT (MIN (arg1_align, arg2_align)));
3344 else
3345 #endif
3346 abort ();
3348 if (insn)
3349 emit_insn (insn);
3350 else
3351 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3352 TYPE_MODE (integer_type_node), 3,
3353 XEXP (arg1_rtx, 0), Pmode,
3354 XEXP (arg2_rtx, 0), Pmode,
3355 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3356 TYPE_UNSIGNED (sizetype)),
3357 TYPE_MODE (sizetype));
3359 /* Return the value in the proper mode for this function. */
3360 mode = TYPE_MODE (TREE_TYPE (exp));
3361 if (GET_MODE (result) == mode)
3362 return result;
3363 else if (target != 0)
3365 convert_move (target, result, 0);
3366 return target;
3368 else
3369 return convert_to_mode (mode, result, 0);
3371 #endif
3373 return 0;
3376 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3377 if we failed the caller should emit a normal call, otherwise try to get
3378 the result in TARGET, if convenient. */
3380 static rtx
3381 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3383 tree arglist = TREE_OPERAND (exp, 1);
3384 tree arg1, arg2;
3385 const char *p1, *p2;
3387 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3388 return 0;
3390 arg1 = TREE_VALUE (arglist);
3391 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3393 /* If both arguments are equal (and not volatile), return zero. */
3394 if (operand_equal_p (arg1, arg2, 0))
3395 return const0_rtx;
3397 p1 = c_getstr (arg1);
3398 p2 = c_getstr (arg2);
3400 if (p1 && p2)
3402 const int i = strcmp (p1, p2);
3403 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3406 /* If either arg is "", return an expression corresponding to
3407 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3408 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3410 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3411 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3412 tree ind1 =
3413 fold (build1 (CONVERT_EXPR, integer_type_node,
3414 build1 (INDIRECT_REF, cst_uchar_node,
3415 fold_convert (cst_uchar_ptr_node, arg1))));
3416 tree ind2 =
3417 fold (build1 (CONVERT_EXPR, integer_type_node,
3418 build1 (INDIRECT_REF, cst_uchar_node,
3419 fold_convert (cst_uchar_ptr_node, arg2))));
3420 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3421 return expand_expr (result, target, mode, EXPAND_NORMAL);
3424 #ifdef HAVE_cmpstrsi
3425 if (HAVE_cmpstrsi)
3427 tree len, len1, len2;
3428 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3429 rtx result, insn;
3430 tree fndecl;
3432 int arg1_align
3433 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3434 int arg2_align
3435 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3436 enum machine_mode insn_mode
3437 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3439 len1 = c_strlen (arg1, 1);
3440 len2 = c_strlen (arg2, 1);
3442 if (len1)
3443 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3444 if (len2)
3445 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3447 /* If we don't have a constant length for the first, use the length
3448 of the second, if we know it. We don't require a constant for
3449 this case; some cost analysis could be done if both are available
3450 but neither is constant. For now, assume they're equally cheap,
3451 unless one has side effects. If both strings have constant lengths,
3452 use the smaller. */
3454 if (!len1)
3455 len = len2;
3456 else if (!len2)
3457 len = len1;
3458 else if (TREE_SIDE_EFFECTS (len1))
3459 len = len2;
3460 else if (TREE_SIDE_EFFECTS (len2))
3461 len = len1;
3462 else if (TREE_CODE (len1) != INTEGER_CST)
3463 len = len2;
3464 else if (TREE_CODE (len2) != INTEGER_CST)
3465 len = len1;
3466 else if (tree_int_cst_lt (len1, len2))
3467 len = len1;
3468 else
3469 len = len2;
3471 /* If both arguments have side effects, we cannot optimize. */
3472 if (!len || TREE_SIDE_EFFECTS (len))
3473 return 0;
3475 /* If we don't have POINTER_TYPE, call the function. */
3476 if (arg1_align == 0 || arg2_align == 0)
3477 return 0;
3479 /* Make a place to write the result of the instruction. */
3480 result = target;
3481 if (! (result != 0
3482 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3483 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3484 result = gen_reg_rtx (insn_mode);
3486 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3487 arg1 = save_expr (arg1);
3488 arg2 = save_expr (arg2);
3490 arg1_rtx = get_memory_rtx (arg1);
3491 arg2_rtx = get_memory_rtx (arg2);
3492 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3493 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3494 GEN_INT (MIN (arg1_align, arg2_align)));
3495 if (insn)
3497 emit_insn (insn);
3499 /* Return the value in the proper mode for this function. */
3500 mode = TYPE_MODE (TREE_TYPE (exp));
3501 if (GET_MODE (result) == mode)
3502 return result;
3503 if (target == 0)
3504 return convert_to_mode (mode, result, 0);
3505 convert_move (target, result, 0);
3506 return target;
3509 /* Expand the library call ourselves using a stabilized argument
3510 list to avoid re-evaluating the function's arguments twice. */
3511 arglist = build_tree_list (NULL_TREE, arg2);
3512 arglist = tree_cons (NULL_TREE, arg1, arglist);
3513 fndecl = get_callee_fndecl (exp);
3514 exp = build_function_call_expr (fndecl, arglist);
3515 return expand_call (exp, target, target == const0_rtx);
3517 #endif
3518 return 0;
3521 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3522 if we failed the caller should emit a normal call, otherwise try to get
3523 the result in TARGET, if convenient. */
3525 static rtx
3526 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3528 tree arglist = TREE_OPERAND (exp, 1);
3529 tree arg1, arg2, arg3;
3530 const char *p1, *p2;
3532 if (!validate_arglist (arglist,
3533 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3534 return 0;
3536 arg1 = TREE_VALUE (arglist);
3537 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3538 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3540 /* If the len parameter is zero, return zero. */
3541 if (integer_zerop (arg3))
3543 /* Evaluate and ignore arg1 and arg2 in case they have
3544 side-effects. */
3545 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3546 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3547 return const0_rtx;
3550 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3551 if (operand_equal_p (arg1, arg2, 0))
3553 /* Evaluate and ignore arg3 in case it has side-effects. */
3554 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3555 return const0_rtx;
3558 p1 = c_getstr (arg1);
3559 p2 = c_getstr (arg2);
3561 /* If all arguments are constant, evaluate at compile-time. */
3562 if (host_integerp (arg3, 1) && p1 && p2)
3564 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3565 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3568 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3569 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3570 if (host_integerp (arg3, 1)
3571 && (tree_low_cst (arg3, 1) == 1
3572 || (tree_low_cst (arg3, 1) > 1
3573 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3575 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3576 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3577 tree ind1 =
3578 fold (build1 (CONVERT_EXPR, integer_type_node,
3579 build1 (INDIRECT_REF, cst_uchar_node,
3580 fold_convert (cst_uchar_ptr_node, arg1))));
3581 tree ind2 =
3582 fold (build1 (CONVERT_EXPR, integer_type_node,
3583 build1 (INDIRECT_REF, cst_uchar_node,
3584 fold_convert (cst_uchar_ptr_node, arg2))));
3585 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3586 return expand_expr (result, target, mode, EXPAND_NORMAL);
3589 /* If c_strlen can determine an expression for one of the string
3590 lengths, and it doesn't have side effects, then emit cmpstrsi
3591 using length MIN(strlen(string)+1, arg3). */
3592 #ifdef HAVE_cmpstrsi
3593 if (HAVE_cmpstrsi)
3595 tree len, len1, len2;
3596 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3597 rtx result, insn;
3598 tree fndecl;
3600 int arg1_align
3601 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3602 int arg2_align
3603 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3604 enum machine_mode insn_mode
3605 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3607 len1 = c_strlen (arg1, 1);
3608 len2 = c_strlen (arg2, 1);
3610 if (len1)
3611 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3612 if (len2)
3613 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3615 /* If we don't have a constant length for the first, use the length
3616 of the second, if we know it. We don't require a constant for
3617 this case; some cost analysis could be done if both are available
3618 but neither is constant. For now, assume they're equally cheap,
3619 unless one has side effects. If both strings have constant lengths,
3620 use the smaller. */
3622 if (!len1)
3623 len = len2;
3624 else if (!len2)
3625 len = len1;
3626 else if (TREE_SIDE_EFFECTS (len1))
3627 len = len2;
3628 else if (TREE_SIDE_EFFECTS (len2))
3629 len = len1;
3630 else if (TREE_CODE (len1) != INTEGER_CST)
3631 len = len2;
3632 else if (TREE_CODE (len2) != INTEGER_CST)
3633 len = len1;
3634 else if (tree_int_cst_lt (len1, len2))
3635 len = len1;
3636 else
3637 len = len2;
3639 /* If both arguments have side effects, we cannot optimize. */
3640 if (!len || TREE_SIDE_EFFECTS (len))
3641 return 0;
3643 /* The actual new length parameter is MIN(len,arg3). */
3644 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3646 /* If we don't have POINTER_TYPE, call the function. */
3647 if (arg1_align == 0 || arg2_align == 0)
3648 return 0;
3650 /* Make a place to write the result of the instruction. */
3651 result = target;
3652 if (! (result != 0
3653 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3654 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3655 result = gen_reg_rtx (insn_mode);
3657 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3658 arg1 = save_expr (arg1);
3659 arg2 = save_expr (arg2);
3660 len = save_expr (len);
3662 arg1_rtx = get_memory_rtx (arg1);
3663 arg2_rtx = get_memory_rtx (arg2);
3664 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3665 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3666 GEN_INT (MIN (arg1_align, arg2_align)));
3667 if (insn)
3669 emit_insn (insn);
3671 /* Return the value in the proper mode for this function. */
3672 mode = TYPE_MODE (TREE_TYPE (exp));
3673 if (GET_MODE (result) == mode)
3674 return result;
3675 if (target == 0)
3676 return convert_to_mode (mode, result, 0);
3677 convert_move (target, result, 0);
3678 return target;
3681 /* Expand the library call ourselves using a stabilized argument
3682 list to avoid re-evaluating the function's arguments twice. */
3683 arglist = build_tree_list (NULL_TREE, len);
3684 arglist = tree_cons (NULL_TREE, arg2, arglist);
3685 arglist = tree_cons (NULL_TREE, arg1, arglist);
3686 fndecl = get_callee_fndecl (exp);
3687 exp = build_function_call_expr (fndecl, arglist);
3688 return expand_call (exp, target, target == const0_rtx);
3690 #endif
3691 return 0;
3694 /* Expand expression EXP, which is a call to the strcat builtin.
3695 Return 0 if we failed the caller should emit a normal call,
3696 otherwise try to get the result in TARGET, if convenient. */
3698 static rtx
3699 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3701 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3702 return 0;
3703 else
3705 tree dst = TREE_VALUE (arglist),
3706 src = TREE_VALUE (TREE_CHAIN (arglist));
3707 const char *p = c_getstr (src);
3709 if (p)
3711 /* If the string length is zero, return the dst parameter. */
3712 if (*p == '\0')
3713 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3714 else if (!optimize_size)
3716 /* Otherwise if !optimize_size, see if we can store by
3717 pieces into (dst + strlen(dst)). */
3718 tree newdst, arglist,
3719 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3721 /* This is the length argument. */
3722 arglist = build_tree_list (NULL_TREE,
3723 fold (size_binop (PLUS_EXPR,
3724 c_strlen (src, 0),
3725 ssize_int (1))));
3726 /* Prepend src argument. */
3727 arglist = tree_cons (NULL_TREE, src, arglist);
3729 /* We're going to use dst more than once. */
3730 dst = save_expr (dst);
3732 /* Create strlen (dst). */
3733 newdst =
3734 fold (build_function_call_expr (strlen_fn,
3735 build_tree_list (NULL_TREE,
3736 dst)));
3737 /* Create (dst + strlen (dst)). */
3738 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3740 /* Prepend the new dst argument. */
3741 arglist = tree_cons (NULL_TREE, newdst, arglist);
3743 /* We don't want to get turned into a memcpy if the
3744 target is const0_rtx, i.e. when the return value
3745 isn't used. That would produce pessimized code so
3746 pass in a target of zero, it should never actually be
3747 used. If this was successful return the original
3748 dst, not the result of mempcpy. */
3749 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3750 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3751 else
3752 return 0;
3756 return 0;
3760 /* Expand expression EXP, which is a call to the strncat builtin.
3761 Return 0 if we failed the caller should emit a normal call,
3762 otherwise try to get the result in TARGET, if convenient. */
3764 static rtx
3765 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3767 if (!validate_arglist (arglist,
3768 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3769 return 0;
3770 else
3772 tree dst = TREE_VALUE (arglist),
3773 src = TREE_VALUE (TREE_CHAIN (arglist)),
3774 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3775 const char *p = c_getstr (src);
3777 /* If the requested length is zero, or the src parameter string
3778 length is zero, return the dst parameter. */
3779 if (integer_zerop (len) || (p && *p == '\0'))
3781 /* Evaluate and ignore the src and len parameters in case
3782 they have side-effects. */
3783 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3784 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3785 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3788 /* If the requested len is greater than or equal to the string
3789 length, call strcat. */
3790 if (TREE_CODE (len) == INTEGER_CST && p
3791 && compare_tree_int (len, strlen (p)) >= 0)
3793 tree newarglist
3794 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3795 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3797 /* If the replacement _DECL isn't initialized, don't do the
3798 transformation. */
3799 if (!fn)
3800 return 0;
3802 return expand_expr (build_function_call_expr (fn, newarglist),
3803 target, mode, EXPAND_NORMAL);
3805 return 0;
3809 /* Expand expression EXP, which is a call to the strspn builtin.
3810 Return 0 if we failed the caller should emit a normal call,
3811 otherwise try to get the result in TARGET, if convenient. */
3813 static rtx
3814 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3816 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3817 return 0;
3818 else
3820 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3821 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3823 /* If both arguments are constants, evaluate at compile-time. */
3824 if (p1 && p2)
3826 const size_t r = strspn (p1, p2);
3827 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3830 /* If either argument is "", return 0. */
3831 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3833 /* Evaluate and ignore both arguments in case either one has
3834 side-effects. */
3835 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3836 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3837 return const0_rtx;
3839 return 0;
3843 /* Expand expression EXP, which is a call to the strcspn builtin.
3844 Return 0 if we failed the caller should emit a normal call,
3845 otherwise try to get the result in TARGET, if convenient. */
3847 static rtx
3848 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3850 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3851 return 0;
3852 else
3854 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3855 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3857 /* If both arguments are constants, evaluate at compile-time. */
3858 if (p1 && p2)
3860 const size_t r = strcspn (p1, p2);
3861 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3864 /* If the first argument is "", return 0. */
3865 if (p1 && *p1 == '\0')
3867 /* Evaluate and ignore argument s2 in case it has
3868 side-effects. */
3869 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3870 return const0_rtx;
3873 /* If the second argument is "", return __builtin_strlen(s1). */
3874 if (p2 && *p2 == '\0')
3876 tree newarglist = build_tree_list (NULL_TREE, s1),
3877 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3879 /* If the replacement _DECL isn't initialized, don't do the
3880 transformation. */
3881 if (!fn)
3882 return 0;
3884 return expand_expr (build_function_call_expr (fn, newarglist),
3885 target, mode, EXPAND_NORMAL);
3887 return 0;
3891 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3892 if that's convenient. */
3895 expand_builtin_saveregs (void)
3897 rtx val, seq;
3899 /* Don't do __builtin_saveregs more than once in a function.
3900 Save the result of the first call and reuse it. */
3901 if (saveregs_value != 0)
3902 return saveregs_value;
3904 /* When this function is called, it means that registers must be
3905 saved on entry to this function. So we migrate the call to the
3906 first insn of this function. */
3908 start_sequence ();
3910 /* Do whatever the machine needs done in this case. */
3911 val = targetm.calls.expand_builtin_saveregs ();
3913 seq = get_insns ();
3914 end_sequence ();
3916 saveregs_value = val;
3918 /* Put the insns after the NOTE that starts the function. If this
3919 is inside a start_sequence, make the outer-level insn chain current, so
3920 the code is placed at the start of the function. */
3921 push_topmost_sequence ();
3922 emit_insn_after (seq, get_insns ());
3923 pop_topmost_sequence ();
3925 return val;
3928 /* __builtin_args_info (N) returns word N of the arg space info
3929 for the current function. The number and meanings of words
3930 is controlled by the definition of CUMULATIVE_ARGS. */
3932 static rtx
3933 expand_builtin_args_info (tree arglist)
3935 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3936 int *word_ptr = (int *) &current_function_args_info;
3938 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3939 abort ();
3941 if (arglist != 0)
3943 if (!host_integerp (TREE_VALUE (arglist), 0))
3944 error ("argument of `__builtin_args_info' must be constant");
3945 else
3947 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3949 if (wordnum < 0 || wordnum >= nwords)
3950 error ("argument of `__builtin_args_info' out of range");
3951 else
3952 return GEN_INT (word_ptr[wordnum]);
3955 else
3956 error ("missing argument in `__builtin_args_info'");
3958 return const0_rtx;
3961 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3963 static rtx
3964 expand_builtin_next_arg (tree arglist)
3966 tree fntype = TREE_TYPE (current_function_decl);
3968 if (TYPE_ARG_TYPES (fntype) == 0
3969 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3970 == void_type_node))
3972 error ("`va_start' used in function with fixed args");
3973 return const0_rtx;
3976 if (arglist)
3978 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3979 tree arg = TREE_VALUE (arglist);
3981 /* Strip off all nops for the sake of the comparison. This
3982 is not quite the same as STRIP_NOPS. It does more.
3983 We must also strip off INDIRECT_EXPR for C++ reference
3984 parameters. */
3985 while (TREE_CODE (arg) == NOP_EXPR
3986 || TREE_CODE (arg) == CONVERT_EXPR
3987 || TREE_CODE (arg) == NON_LVALUE_EXPR
3988 || TREE_CODE (arg) == INDIRECT_REF)
3989 arg = TREE_OPERAND (arg, 0);
3990 if (arg != last_parm)
3991 warning ("second parameter of `va_start' not last named argument");
3993 else
3994 /* Evidently an out of date version of <stdarg.h>; can't validate
3995 va_start's second argument, but can still work as intended. */
3996 warning ("`__builtin_next_arg' called without an argument");
3998 return expand_binop (Pmode, add_optab,
3999 current_function_internal_arg_pointer,
4000 current_function_arg_offset_rtx,
4001 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4004 /* Make it easier for the backends by protecting the valist argument
4005 from multiple evaluations. */
4007 static tree
4008 stabilize_va_list (tree valist, int needs_lvalue)
4010 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4012 if (TREE_SIDE_EFFECTS (valist))
4013 valist = save_expr (valist);
4015 /* For this case, the backends will be expecting a pointer to
4016 TREE_TYPE (va_list_type_node), but it's possible we've
4017 actually been given an array (an actual va_list_type_node).
4018 So fix it. */
4019 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4021 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4022 tree p2 = build_pointer_type (va_list_type_node);
4024 valist = build1 (ADDR_EXPR, p2, valist);
4025 valist = fold_convert (p1, valist);
4028 else
4030 tree pt;
4032 if (! needs_lvalue)
4034 if (! TREE_SIDE_EFFECTS (valist))
4035 return valist;
4037 pt = build_pointer_type (va_list_type_node);
4038 valist = fold (build1 (ADDR_EXPR, pt, valist));
4039 TREE_SIDE_EFFECTS (valist) = 1;
4042 if (TREE_SIDE_EFFECTS (valist))
4043 valist = save_expr (valist);
4044 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
4045 valist));
4048 return valist;
4051 /* The "standard" definition of va_list is void*. */
4053 tree
4054 std_build_builtin_va_list (void)
4056 return ptr_type_node;
4059 /* The "standard" implementation of va_start: just assign `nextarg' to
4060 the variable. */
4062 void
4063 std_expand_builtin_va_start (tree valist, rtx nextarg)
4065 tree t;
4067 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4068 make_tree (ptr_type_node, nextarg));
4069 TREE_SIDE_EFFECTS (t) = 1;
4071 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4074 /* Expand ARGLIST, from a call to __builtin_va_start. */
4076 static rtx
4077 expand_builtin_va_start (tree arglist)
4079 rtx nextarg;
4080 tree chain, valist;
4082 chain = TREE_CHAIN (arglist);
4084 if (TREE_CHAIN (chain))
4085 error ("too many arguments to function `va_start'");
4087 nextarg = expand_builtin_next_arg (chain);
4088 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4090 #ifdef EXPAND_BUILTIN_VA_START
4091 EXPAND_BUILTIN_VA_START (valist, nextarg);
4092 #else
4093 std_expand_builtin_va_start (valist, nextarg);
4094 #endif
4096 return const0_rtx;
4099 /* The "standard" implementation of va_arg: read the value from the
4100 current (padded) address and increment by the (padded) size. */
4103 std_expand_builtin_va_arg (tree valist, tree type)
4105 tree addr_tree, t, type_size = NULL;
4106 tree align, alignm1;
4107 tree rounded_size;
4108 rtx addr;
4109 HOST_WIDE_INT boundary;
4111 /* Compute the rounded size of the type. */
4112 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4113 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4114 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4116 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4117 requires greater alignment, we must perform dynamic alignment. */
4119 if (boundary > PARM_BOUNDARY)
4121 if (!PAD_VARARGS_DOWN)
4123 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4124 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4125 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4126 TREE_SIDE_EFFECTS (t) = 1;
4127 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4129 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4130 build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4131 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4132 TREE_SIDE_EFFECTS (t) = 1;
4133 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4135 if (type == error_mark_node
4136 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4137 || TREE_OVERFLOW (type_size))
4138 rounded_size = size_zero_node;
4139 else
4140 rounded_size = fold (build (MULT_EXPR, sizetype,
4141 fold (build (TRUNC_DIV_EXPR, sizetype,
4142 fold (build (PLUS_EXPR, sizetype,
4143 type_size, alignm1)),
4144 align)),
4145 align));
4147 /* Get AP. */
4148 addr_tree = valist;
4149 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4151 /* Small args are padded downward. */
4152 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4153 fold (build (COND_EXPR, sizetype,
4154 fold (build (GT_EXPR, sizetype,
4155 rounded_size,
4156 align)),
4157 size_zero_node,
4158 fold (build (MINUS_EXPR, sizetype,
4159 rounded_size,
4160 type_size))))));
4163 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4164 addr = copy_to_reg (addr);
4166 /* Compute new value for AP. */
4167 if (! integer_zerop (rounded_size))
4169 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4170 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4171 rounded_size));
4172 TREE_SIDE_EFFECTS (t) = 1;
4173 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4176 return addr;
4179 /* Expand __builtin_va_arg, which is not really a builtin function, but
4180 a very special sort of operator. */
4183 expand_builtin_va_arg (tree valist, tree type)
4185 rtx addr, result;
4186 tree promoted_type, want_va_type, have_va_type;
4188 /* Verify that valist is of the proper type. */
4190 want_va_type = va_list_type_node;
4191 have_va_type = TREE_TYPE (valist);
4192 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4194 /* If va_list is an array type, the argument may have decayed
4195 to a pointer type, e.g. by being passed to another function.
4196 In that case, unwrap both types so that we can compare the
4197 underlying records. */
4198 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4199 || TREE_CODE (have_va_type) == POINTER_TYPE)
4201 want_va_type = TREE_TYPE (want_va_type);
4202 have_va_type = TREE_TYPE (have_va_type);
4205 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4207 error ("first argument to `va_arg' not of type `va_list'");
4208 addr = const0_rtx;
4211 /* Generate a diagnostic for requesting data of a type that cannot
4212 be passed through `...' due to type promotion at the call site. */
4213 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4214 != type)
4216 const char *name = "<anonymous type>", *pname = 0;
4217 static bool gave_help;
4219 if (TYPE_NAME (type))
4221 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4222 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4223 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4224 && DECL_NAME (TYPE_NAME (type)))
4225 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4227 if (TYPE_NAME (promoted_type))
4229 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4230 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4231 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4232 && DECL_NAME (TYPE_NAME (promoted_type)))
4233 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4236 /* Unfortunately, this is merely undefined, rather than a constraint
4237 violation, so we cannot make this an error. If this call is never
4238 executed, the program is still strictly conforming. */
4239 warning ("`%s' is promoted to `%s' when passed through `...'",
4240 name, pname);
4241 if (! gave_help)
4243 gave_help = true;
4244 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4245 pname, name);
4248 /* We can, however, treat "undefined" any way we please.
4249 Call abort to encourage the user to fix the program. */
4250 inform ("if this code is reached, the program will abort");
4251 expand_builtin_trap ();
4253 /* This is dead code, but go ahead and finish so that the
4254 mode of the result comes out right. */
4255 addr = const0_rtx;
4257 else
4259 /* Make it easier for the backends by protecting the valist argument
4260 from multiple evaluations. */
4261 valist = stabilize_va_list (valist, 0);
4263 #ifdef EXPAND_BUILTIN_VA_ARG
4264 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4265 #else
4266 addr = std_expand_builtin_va_arg (valist, type);
4267 #endif
4270 addr = convert_memory_address (Pmode, addr);
4272 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4273 set_mem_alias_set (result, get_varargs_alias_set ());
4275 return result;
4278 /* Expand ARGLIST, from a call to __builtin_va_end. */
4280 static rtx
4281 expand_builtin_va_end (tree arglist)
4283 tree valist = TREE_VALUE (arglist);
4285 /* Evaluate for side effects, if needed. I hate macros that don't
4286 do that. */
4287 if (TREE_SIDE_EFFECTS (valist))
4288 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4290 return const0_rtx;
4293 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4294 builtin rather than just as an assignment in stdarg.h because of the
4295 nastiness of array-type va_list types. */
4297 static rtx
4298 expand_builtin_va_copy (tree arglist)
4300 tree dst, src, t;
4302 dst = TREE_VALUE (arglist);
4303 src = TREE_VALUE (TREE_CHAIN (arglist));
4305 dst = stabilize_va_list (dst, 1);
4306 src = stabilize_va_list (src, 0);
4308 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4310 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4311 TREE_SIDE_EFFECTS (t) = 1;
4312 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4314 else
4316 rtx dstb, srcb, size;
4318 /* Evaluate to pointers. */
4319 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4320 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4321 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4322 VOIDmode, EXPAND_NORMAL);
4324 dstb = convert_memory_address (Pmode, dstb);
4325 srcb = convert_memory_address (Pmode, srcb);
4327 /* "Dereference" to BLKmode memories. */
4328 dstb = gen_rtx_MEM (BLKmode, dstb);
4329 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4330 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4331 srcb = gen_rtx_MEM (BLKmode, srcb);
4332 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4333 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4335 /* Copy. */
4336 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4339 return const0_rtx;
4342 /* Expand a call to one of the builtin functions __builtin_frame_address or
4343 __builtin_return_address. */
4345 static rtx
4346 expand_builtin_frame_address (tree fndecl, tree arglist)
4348 /* The argument must be a nonnegative integer constant.
4349 It counts the number of frames to scan up the stack.
4350 The value is the return address saved in that frame. */
4351 if (arglist == 0)
4352 /* Warning about missing arg was already issued. */
4353 return const0_rtx;
4354 else if (! host_integerp (TREE_VALUE (arglist), 1))
4356 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4357 error ("invalid arg to `__builtin_frame_address'");
4358 else
4359 error ("invalid arg to `__builtin_return_address'");
4360 return const0_rtx;
4362 else
4364 rtx tem
4365 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4366 tree_low_cst (TREE_VALUE (arglist), 1),
4367 hard_frame_pointer_rtx);
4369 /* Some ports cannot access arbitrary stack frames. */
4370 if (tem == NULL)
4372 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4373 warning ("unsupported arg to `__builtin_frame_address'");
4374 else
4375 warning ("unsupported arg to `__builtin_return_address'");
4376 return const0_rtx;
4379 /* For __builtin_frame_address, return what we've got. */
4380 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4381 return tem;
4383 if (GET_CODE (tem) != REG
4384 && ! CONSTANT_P (tem))
4385 tem = copy_to_mode_reg (Pmode, tem);
4386 return tem;
4390 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4391 we failed and the caller should emit a normal call, otherwise try to get
4392 the result in TARGET, if convenient. */
4394 static rtx
4395 expand_builtin_alloca (tree arglist, rtx target)
4397 rtx op0;
4398 rtx result;
4400 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4401 return 0;
4403 /* Compute the argument. */
4404 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4406 /* Allocate the desired space. */
4407 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4408 result = convert_memory_address (ptr_mode, result);
4410 return result;
4413 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4414 Return 0 if a normal call should be emitted rather than expanding the
4415 function in-line. If convenient, the result should be placed in TARGET.
4416 SUBTARGET may be used as the target for computing one of EXP's operands. */
4418 static rtx
4419 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4420 rtx subtarget, optab op_optab)
4422 rtx op0;
4423 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4424 return 0;
4426 /* Compute the argument. */
4427 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4428 /* Compute op, into TARGET if possible.
4429 Set TARGET to wherever the result comes back. */
4430 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4431 op_optab, op0, target, 1);
4432 if (target == 0)
4433 abort ();
4435 return convert_to_mode (target_mode, target, 0);
4438 /* If the string passed to fputs is a constant and is one character
4439 long, we attempt to transform this call into __builtin_fputc(). */
4441 static rtx
4442 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4444 tree len, fn;
4445 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4446 : implicit_built_in_decls[BUILT_IN_FPUTC];
4447 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4448 : implicit_built_in_decls[BUILT_IN_FWRITE];
4450 /* If the return value is used, or the replacement _DECL isn't
4451 initialized, don't do the transformation. */
4452 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4453 return 0;
4455 /* Verify the arguments in the original call. */
4456 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4457 return 0;
4459 /* Get the length of the string passed to fputs. If the length
4460 can't be determined, punt. */
4461 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4462 || TREE_CODE (len) != INTEGER_CST)
4463 return 0;
4465 switch (compare_tree_int (len, 1))
4467 case -1: /* length is 0, delete the call entirely . */
4469 /* Evaluate and ignore the argument in case it has
4470 side-effects. */
4471 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4472 VOIDmode, EXPAND_NORMAL);
4473 return const0_rtx;
4475 case 0: /* length is 1, call fputc. */
4477 const char *p = c_getstr (TREE_VALUE (arglist));
4479 if (p != NULL)
4481 /* New argument list transforming fputs(string, stream) to
4482 fputc(string[0], stream). */
4483 arglist =
4484 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4485 arglist =
4486 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4487 fn = fn_fputc;
4488 break;
4491 /* Fall through. */
4492 case 1: /* length is greater than 1, call fwrite. */
4494 tree string_arg;
4496 /* If optimizing for size keep fputs. */
4497 if (optimize_size)
4498 return 0;
4499 string_arg = TREE_VALUE (arglist);
4500 /* New argument list transforming fputs(string, stream) to
4501 fwrite(string, 1, len, stream). */
4502 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4503 arglist = tree_cons (NULL_TREE, len, arglist);
4504 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4505 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4506 fn = fn_fwrite;
4507 break;
4509 default:
4510 abort ();
4513 return expand_expr (build_function_call_expr (fn, arglist),
4514 const0_rtx, VOIDmode, EXPAND_NORMAL);
4517 /* Expand a call to __builtin_expect. We return our argument and emit a
4518 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4519 a non-jump context. */
4521 static rtx
4522 expand_builtin_expect (tree arglist, rtx target)
4524 tree exp, c;
4525 rtx note, rtx_c;
4527 if (arglist == NULL_TREE
4528 || TREE_CHAIN (arglist) == NULL_TREE)
4529 return const0_rtx;
4530 exp = TREE_VALUE (arglist);
4531 c = TREE_VALUE (TREE_CHAIN (arglist));
4533 if (TREE_CODE (c) != INTEGER_CST)
4535 error ("second arg to `__builtin_expect' must be a constant");
4536 c = integer_zero_node;
4539 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4541 /* Don't bother with expected value notes for integral constants. */
4542 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4544 /* We do need to force this into a register so that we can be
4545 moderately sure to be able to correctly interpret the branch
4546 condition later. */
4547 target = force_reg (GET_MODE (target), target);
4549 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4551 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4552 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4555 return target;
4558 /* Like expand_builtin_expect, except do this in a jump context. This is
4559 called from do_jump if the conditional is a __builtin_expect. Return either
4560 a list of insns to emit the jump or NULL if we cannot optimize
4561 __builtin_expect. We need to optimize this at jump time so that machines
4562 like the PowerPC don't turn the test into a SCC operation, and then jump
4563 based on the test being 0/1. */
4566 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4568 tree arglist = TREE_OPERAND (exp, 1);
4569 tree arg0 = TREE_VALUE (arglist);
4570 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4571 rtx ret = NULL_RTX;
4573 /* Only handle __builtin_expect (test, 0) and
4574 __builtin_expect (test, 1). */
4575 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4576 && (integer_zerop (arg1) || integer_onep (arg1)))
4578 rtx insn, drop_through_label, temp;
4580 /* Expand the jump insns. */
4581 start_sequence ();
4582 do_jump (arg0, if_false_label, if_true_label);
4583 ret = get_insns ();
4585 drop_through_label = get_last_insn ();
4586 if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4587 drop_through_label = prev_nonnote_insn (drop_through_label);
4588 if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4589 drop_through_label = NULL_RTX;
4590 end_sequence ();
4592 if (! if_true_label)
4593 if_true_label = drop_through_label;
4594 if (! if_false_label)
4595 if_false_label = drop_through_label;
4597 /* Go through and add the expect's to each of the conditional jumps. */
4598 insn = ret;
4599 while (insn != NULL_RTX)
4601 rtx next = NEXT_INSN (insn);
4603 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4605 rtx ifelse = SET_SRC (pc_set (insn));
4606 rtx then_dest = XEXP (ifelse, 1);
4607 rtx else_dest = XEXP (ifelse, 2);
4608 int taken = -1;
4610 /* First check if we recognize any of the labels. */
4611 if (GET_CODE (then_dest) == LABEL_REF
4612 && XEXP (then_dest, 0) == if_true_label)
4613 taken = 1;
4614 else if (GET_CODE (then_dest) == LABEL_REF
4615 && XEXP (then_dest, 0) == if_false_label)
4616 taken = 0;
4617 else if (GET_CODE (else_dest) == LABEL_REF
4618 && XEXP (else_dest, 0) == if_false_label)
4619 taken = 1;
4620 else if (GET_CODE (else_dest) == LABEL_REF
4621 && XEXP (else_dest, 0) == if_true_label)
4622 taken = 0;
4623 /* Otherwise check where we drop through. */
4624 else if (else_dest == pc_rtx)
4626 if (next && GET_CODE (next) == NOTE)
4627 next = next_nonnote_insn (next);
4629 if (next && GET_CODE (next) == JUMP_INSN
4630 && any_uncondjump_p (next))
4631 temp = XEXP (SET_SRC (pc_set (next)), 0);
4632 else
4633 temp = next;
4635 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4636 else that can't possibly match either target label. */
4637 if (temp == if_false_label)
4638 taken = 1;
4639 else if (temp == if_true_label)
4640 taken = 0;
4642 else if (then_dest == pc_rtx)
4644 if (next && GET_CODE (next) == NOTE)
4645 next = next_nonnote_insn (next);
4647 if (next && GET_CODE (next) == JUMP_INSN
4648 && any_uncondjump_p (next))
4649 temp = XEXP (SET_SRC (pc_set (next)), 0);
4650 else
4651 temp = next;
4653 if (temp == if_false_label)
4654 taken = 0;
4655 else if (temp == if_true_label)
4656 taken = 1;
4659 if (taken != -1)
4661 /* If the test is expected to fail, reverse the
4662 probabilities. */
4663 if (integer_zerop (arg1))
4664 taken = 1 - taken;
4665 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4669 insn = next;
4673 return ret;
4676 void
4677 expand_builtin_trap (void)
4679 #ifdef HAVE_trap
4680 if (HAVE_trap)
4681 emit_insn (gen_trap ());
4682 else
4683 #endif
4684 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4685 emit_barrier ();
4688 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4689 Return 0 if a normal call should be emitted rather than expanding
4690 the function inline. If convenient, the result should be placed
4691 in TARGET. SUBTARGET may be used as the target for computing
4692 the operand. */
4694 static rtx
4695 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4697 enum machine_mode mode;
4698 tree arg;
4699 rtx op0;
4701 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4702 return 0;
4704 arg = TREE_VALUE (arglist);
4705 mode = TYPE_MODE (TREE_TYPE (arg));
4706 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4707 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4710 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4711 Return 0 if a normal call should be emitted rather than expanding
4712 the function inline. If convenient, the result should be placed
4713 in target. */
4715 static rtx
4716 expand_builtin_cabs (tree arglist, rtx target)
4718 enum machine_mode mode;
4719 tree arg;
4720 rtx op0;
4722 if (arglist == 0 || TREE_CHAIN (arglist))
4723 return 0;
4724 arg = TREE_VALUE (arglist);
4725 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4726 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4727 return 0;
4729 mode = TYPE_MODE (TREE_TYPE (arg));
4730 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4731 return expand_complex_abs (mode, op0, target, 0);
4734 /* Create a new constant string literal and return a char* pointer to it.
4735 The STRING_CST value is the LEN characters at STR. */
4736 static tree
4737 build_string_literal (int len, const char *str)
4739 tree t, elem, index, type;
4741 t = build_string (len, str);
4742 elem = build_type_variant (char_type_node, 1, 0);
4743 index = build_index_type (build_int_2 (len - 1, 0));
4744 type = build_array_type (elem, index);
4745 TREE_TYPE (t) = type;
4746 TREE_CONSTANT (t) = 1;
4747 TREE_READONLY (t) = 1;
4748 TREE_STATIC (t) = 1;
4750 type = build_pointer_type (type);
4751 t = build1 (ADDR_EXPR, type, t);
4753 type = build_pointer_type (elem);
4754 t = build1 (NOP_EXPR, type, t);
4755 return t;
4758 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4759 Return 0 if a normal call should be emitted rather than transforming
4760 the function inline. If convenient, the result should be placed in
4761 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4762 call. */
4763 static rtx
4764 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4765 bool unlocked)
4767 tree fn_putchar = unlocked
4768 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4769 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4770 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4771 : implicit_built_in_decls[BUILT_IN_PUTS];
4772 const char *fmt_str;
4773 tree fn, fmt, arg;
4775 /* If the return value is used, don't do the transformation. */
4776 if (target != const0_rtx)
4777 return 0;
4779 /* Verify the required arguments in the original call. */
4780 if (! arglist)
4781 return 0;
4782 fmt = TREE_VALUE (arglist);
4783 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4784 return 0;
4785 arglist = TREE_CHAIN (arglist);
4787 /* Check whether the format is a literal string constant. */
4788 fmt_str = c_getstr (fmt);
4789 if (fmt_str == NULL)
4790 return 0;
4792 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4793 if (strcmp (fmt_str, "%s\n") == 0)
4795 if (! arglist
4796 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4797 || TREE_CHAIN (arglist))
4798 return 0;
4799 fn = fn_puts;
4801 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4802 else if (strcmp (fmt_str, "%c") == 0)
4804 if (! arglist
4805 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4806 || TREE_CHAIN (arglist))
4807 return 0;
4808 fn = fn_putchar;
4810 else
4812 /* We can't handle anything else with % args or %% ... yet. */
4813 if (strchr (fmt_str, '%'))
4814 return 0;
4816 if (arglist)
4817 return 0;
4819 /* If the format specifier was "", printf does nothing. */
4820 if (fmt_str[0] == '\0')
4821 return const0_rtx;
4822 /* If the format specifier has length of 1, call putchar. */
4823 if (fmt_str[1] == '\0')
4825 /* Given printf("c"), (where c is any one character,)
4826 convert "c"[0] to an int and pass that to the replacement
4827 function. */
4828 arg = build_int_2 (fmt_str[0], 0);
4829 arglist = build_tree_list (NULL_TREE, arg);
4830 fn = fn_putchar;
4832 else
4834 /* If the format specifier was "string\n", call puts("string"). */
4835 size_t len = strlen (fmt_str);
4836 if (fmt_str[len - 1] == '\n')
4838 /* Create a NUL-terminated string that's one char shorter
4839 than the original, stripping off the trailing '\n'. */
4840 char *newstr = alloca (len);
4841 memcpy (newstr, fmt_str, len - 1);
4842 newstr[len - 1] = 0;
4844 arg = build_string_literal (len, newstr);
4845 arglist = build_tree_list (NULL_TREE, arg);
4846 fn = fn_puts;
4848 else
4849 /* We'd like to arrange to call fputs(string,stdout) here,
4850 but we need stdout and don't have a way to get it yet. */
4851 return 0;
4855 if (!fn)
4856 return 0;
4857 return expand_expr (build_function_call_expr (fn, arglist),
4858 target, mode, EXPAND_NORMAL);
4861 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4862 Return 0 if a normal call should be emitted rather than transforming
4863 the function inline. If convenient, the result should be placed in
4864 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4865 call. */
4866 static rtx
4867 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4868 bool unlocked)
4870 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4871 : implicit_built_in_decls[BUILT_IN_FPUTC];
4872 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4873 : implicit_built_in_decls[BUILT_IN_FPUTS];
4874 const char *fmt_str;
4875 tree fn, fmt, fp, arg;
4877 /* If the return value is used, don't do the transformation. */
4878 if (target != const0_rtx)
4879 return 0;
4881 /* Verify the required arguments in the original call. */
4882 if (! arglist)
4883 return 0;
4884 fp = TREE_VALUE (arglist);
4885 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4886 return 0;
4887 arglist = TREE_CHAIN (arglist);
4888 if (! arglist)
4889 return 0;
4890 fmt = TREE_VALUE (arglist);
4891 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4892 return 0;
4893 arglist = TREE_CHAIN (arglist);
4895 /* Check whether the format is a literal string constant. */
4896 fmt_str = c_getstr (fmt);
4897 if (fmt_str == NULL)
4898 return 0;
4900 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4901 if (strcmp (fmt_str, "%s") == 0)
4903 if (! arglist
4904 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4905 || TREE_CHAIN (arglist))
4906 return 0;
4907 arg = TREE_VALUE (arglist);
4908 arglist = build_tree_list (NULL_TREE, fp);
4909 arglist = tree_cons (NULL_TREE, arg, arglist);
4910 fn = fn_fputs;
4912 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4913 else if (strcmp (fmt_str, "%c") == 0)
4915 if (! arglist
4916 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4917 || TREE_CHAIN (arglist))
4918 return 0;
4919 arg = TREE_VALUE (arglist);
4920 arglist = build_tree_list (NULL_TREE, fp);
4921 arglist = tree_cons (NULL_TREE, arg, arglist);
4922 fn = fn_fputc;
4924 else
4926 /* We can't handle anything else with % args or %% ... yet. */
4927 if (strchr (fmt_str, '%'))
4928 return 0;
4930 if (arglist)
4931 return 0;
4933 /* If the format specifier was "", fprintf does nothing. */
4934 if (fmt_str[0] == '\0')
4936 /* Evaluate and ignore FILE* argument for side-effects. */
4937 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4938 return const0_rtx;
4941 /* When "string" doesn't contain %, replace all cases of
4942 fprintf(stream,string) with fputs(string,stream). The fputs
4943 builtin will take care of special cases like length == 1. */
4944 arglist = build_tree_list (NULL_TREE, fp);
4945 arglist = tree_cons (NULL_TREE, fmt, arglist);
4946 fn = fn_fputs;
4949 if (!fn)
4950 return 0;
4951 return expand_expr (build_function_call_expr (fn, arglist),
4952 target, mode, EXPAND_NORMAL);
4955 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4956 a normal call should be emitted rather than expanding the function
4957 inline. If convenient, the result should be placed in TARGET with
4958 mode MODE. */
4960 static rtx
4961 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4963 tree orig_arglist, dest, fmt;
4964 const char *fmt_str;
4966 orig_arglist = arglist;
4968 /* Verify the required arguments in the original call. */
4969 if (! arglist)
4970 return 0;
4971 dest = TREE_VALUE (arglist);
4972 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4973 return 0;
4974 arglist = TREE_CHAIN (arglist);
4975 if (! arglist)
4976 return 0;
4977 fmt = TREE_VALUE (arglist);
4978 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4979 return 0;
4980 arglist = TREE_CHAIN (arglist);
4982 /* Check whether the format is a literal string constant. */
4983 fmt_str = c_getstr (fmt);
4984 if (fmt_str == NULL)
4985 return 0;
4987 /* If the format doesn't contain % args or %%, use strcpy. */
4988 if (strchr (fmt_str, '%') == 0)
4990 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4991 tree exp;
4993 if (arglist || ! fn)
4994 return 0;
4995 expand_expr (build_function_call_expr (fn, orig_arglist),
4996 const0_rtx, VOIDmode, EXPAND_NORMAL);
4997 if (target == const0_rtx)
4998 return const0_rtx;
4999 exp = build_int_2 (strlen (fmt_str), 0);
5000 exp = fold_convert (integer_type_node, exp);
5001 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5003 /* If the format is "%s", use strcpy if the result isn't used. */
5004 else if (strcmp (fmt_str, "%s") == 0)
5006 tree fn, arg, len;
5007 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5009 if (! fn)
5010 return 0;
5012 if (! arglist || TREE_CHAIN (arglist))
5013 return 0;
5014 arg = TREE_VALUE (arglist);
5015 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5016 return 0;
5018 if (target != const0_rtx)
5020 len = c_strlen (arg, 1);
5021 if (! len || TREE_CODE (len) != INTEGER_CST)
5022 return 0;
5024 else
5025 len = NULL_TREE;
5027 arglist = build_tree_list (NULL_TREE, arg);
5028 arglist = tree_cons (NULL_TREE, dest, arglist);
5029 expand_expr (build_function_call_expr (fn, arglist),
5030 const0_rtx, VOIDmode, EXPAND_NORMAL);
5032 if (target == const0_rtx)
5033 return const0_rtx;
5034 return expand_expr (len, target, mode, EXPAND_NORMAL);
5037 return 0;
5040 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5041 Return NULL_RTX if a normal call should be emitted rather than expanding
5042 the function in-line. EXP is the expression that is a call to the builtin
5043 function; if convenient, the result should be placed in TARGET. */
5045 static rtx
5046 expand_builtin_signbit (tree exp, rtx target)
5048 const struct real_format *fmt;
5049 enum machine_mode fmode, imode, rmode;
5050 HOST_WIDE_INT hi, lo;
5051 tree arg, arglist;
5052 int bitpos;
5053 rtx temp;
5055 arglist = TREE_OPERAND (exp, 1);
5056 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5057 return 0;
5059 arg = TREE_VALUE (arglist);
5060 fmode = TYPE_MODE (TREE_TYPE (arg));
5061 rmode = TYPE_MODE (TREE_TYPE (exp));
5062 fmt = REAL_MODE_FORMAT (fmode);
5064 /* For floating point formats without a sign bit, implement signbit
5065 as "ARG < 0.0". */
5066 if (fmt->signbit < 0)
5068 /* But we can't do this if the format supports signed zero. */
5069 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5070 return 0;
5072 arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
5073 build_real (TREE_TYPE (arg), dconst0)));
5074 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5077 imode = int_mode_for_mode (fmode);
5078 if (imode == BLKmode)
5079 return 0;
5081 bitpos = fmt->signbit;
5082 /* Handle targets with different FP word orders. */
5083 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5085 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5086 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5087 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5090 /* If the sign bit is not in the lowpart and the floating point format
5091 is wider than an integer, check that is twice the size of an integer
5092 so that we can use gen_highpart below. */
5093 if (bitpos >= GET_MODE_BITSIZE (rmode)
5094 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5095 return 0;
5097 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5098 temp = gen_lowpart (imode, temp);
5100 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5102 if (BYTES_BIG_ENDIAN)
5103 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5104 temp = copy_to_mode_reg (imode, temp);
5105 temp = extract_bit_field (temp, 1, bitpos, 1,
5106 NULL_RTX, rmode, rmode,
5107 GET_MODE_SIZE (imode));
5109 else
5111 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5112 temp = gen_lowpart (rmode, temp);
5113 if (bitpos < HOST_BITS_PER_WIDE_INT)
5115 hi = 0;
5116 lo = (HOST_WIDE_INT) 1 << bitpos;
5118 else
5120 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5121 lo = 0;
5124 temp = force_reg (rmode, temp);
5125 temp = expand_binop (rmode, and_optab, temp,
5126 immed_double_const (lo, hi, rmode),
5127 target, 1, OPTAB_LIB_WIDEN);
5129 return temp;
5132 /* Expand fork or exec calls. TARGET is the desired target of the
5133 call. ARGLIST is the list of arguments of the call. FN is the
5134 identificator of the actual function. IGNORE is nonzero if the
5135 value is to be ignored. */
5137 static rtx
5138 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5140 tree id, decl;
5141 tree call;
5143 /* If we are not profiling, just call the function. */
5144 if (!profile_arc_flag)
5145 return NULL_RTX;
5147 /* Otherwise call the wrapper. This should be equivalent for the rest of
5148 compiler, so the code does not diverge, and the wrapper may run the
5149 code necessary for keeping the profiling sane. */
5151 switch (DECL_FUNCTION_CODE (fn))
5153 case BUILT_IN_FORK:
5154 id = get_identifier ("__gcov_fork");
5155 break;
5157 case BUILT_IN_EXECL:
5158 id = get_identifier ("__gcov_execl");
5159 break;
5161 case BUILT_IN_EXECV:
5162 id = get_identifier ("__gcov_execv");
5163 break;
5165 case BUILT_IN_EXECLP:
5166 id = get_identifier ("__gcov_execlp");
5167 break;
5169 case BUILT_IN_EXECLE:
5170 id = get_identifier ("__gcov_execle");
5171 break;
5173 case BUILT_IN_EXECVP:
5174 id = get_identifier ("__gcov_execvp");
5175 break;
5177 case BUILT_IN_EXECVE:
5178 id = get_identifier ("__gcov_execve");
5179 break;
5181 default:
5182 abort ();
5185 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5186 DECL_EXTERNAL (decl) = 1;
5187 TREE_PUBLIC (decl) = 1;
5188 DECL_ARTIFICIAL (decl) = 1;
5189 TREE_NOTHROW (decl) = 1;
5190 call = build_function_call_expr (decl, arglist);
5192 return expand_call (call, target, ignore);
5195 /* Expand an expression EXP that calls a built-in function,
5196 with result going to TARGET if that's convenient
5197 (and in mode MODE if that's convenient).
5198 SUBTARGET may be used as the target for computing one of EXP's operands.
5199 IGNORE is nonzero if the value is to be ignored. */
5202 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5203 int ignore)
5205 tree fndecl = get_callee_fndecl (exp);
5206 tree arglist = TREE_OPERAND (exp, 1);
5207 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5208 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5210 /* Perform postincrements before expanding builtin functions. */
5211 emit_queue ();
5213 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5214 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5216 /* When not optimizing, generate calls to library functions for a certain
5217 set of builtins. */
5218 if (!optimize
5219 && !CALLED_AS_BUILT_IN (fndecl)
5220 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5221 && fcode != BUILT_IN_ALLOCA)
5222 return expand_call (exp, target, ignore);
5224 /* The built-in function expanders test for target == const0_rtx
5225 to determine whether the function's result will be ignored. */
5226 if (ignore)
5227 target = const0_rtx;
5229 /* If the result of a pure or const built-in function is ignored, and
5230 none of its arguments are volatile, we can avoid expanding the
5231 built-in call and just evaluate the arguments for side-effects. */
5232 if (target == const0_rtx
5233 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5235 bool volatilep = false;
5236 tree arg;
5238 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5239 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5241 volatilep = true;
5242 break;
5245 if (! volatilep)
5247 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5248 expand_expr (TREE_VALUE (arg), const0_rtx,
5249 VOIDmode, EXPAND_NORMAL);
5250 return const0_rtx;
5254 switch (fcode)
5256 case BUILT_IN_ABS:
5257 case BUILT_IN_LABS:
5258 case BUILT_IN_LLABS:
5259 case BUILT_IN_IMAXABS:
5260 /* build_function_call changes these into ABS_EXPR. */
5261 abort ();
5263 case BUILT_IN_FABS:
5264 case BUILT_IN_FABSF:
5265 case BUILT_IN_FABSL:
5266 target = expand_builtin_fabs (arglist, target, subtarget);
5267 if (target)
5268 return target;
5269 break;
5271 case BUILT_IN_CABS:
5272 case BUILT_IN_CABSF:
5273 case BUILT_IN_CABSL:
5274 if (flag_unsafe_math_optimizations)
5276 target = expand_builtin_cabs (arglist, target);
5277 if (target)
5278 return target;
5280 break;
5282 case BUILT_IN_CONJ:
5283 case BUILT_IN_CONJF:
5284 case BUILT_IN_CONJL:
5285 case BUILT_IN_CREAL:
5286 case BUILT_IN_CREALF:
5287 case BUILT_IN_CREALL:
5288 case BUILT_IN_CIMAG:
5289 case BUILT_IN_CIMAGF:
5290 case BUILT_IN_CIMAGL:
5291 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5292 and IMAGPART_EXPR. */
5293 abort ();
5295 case BUILT_IN_EXP:
5296 case BUILT_IN_EXPF:
5297 case BUILT_IN_EXPL:
5298 case BUILT_IN_EXP10:
5299 case BUILT_IN_EXP10F:
5300 case BUILT_IN_EXP10L:
5301 case BUILT_IN_POW10:
5302 case BUILT_IN_POW10F:
5303 case BUILT_IN_POW10L:
5304 case BUILT_IN_EXP2:
5305 case BUILT_IN_EXP2F:
5306 case BUILT_IN_EXP2L:
5307 case BUILT_IN_EXPM1:
5308 case BUILT_IN_EXPM1F:
5309 case BUILT_IN_EXPM1L:
5310 case BUILT_IN_LOGB:
5311 case BUILT_IN_LOGBF:
5312 case BUILT_IN_LOGBL:
5313 case BUILT_IN_ILOGB:
5314 case BUILT_IN_ILOGBF:
5315 case BUILT_IN_ILOGBL:
5316 case BUILT_IN_LOG:
5317 case BUILT_IN_LOGF:
5318 case BUILT_IN_LOGL:
5319 case BUILT_IN_LOG10:
5320 case BUILT_IN_LOG10F:
5321 case BUILT_IN_LOG10L:
5322 case BUILT_IN_LOG2:
5323 case BUILT_IN_LOG2F:
5324 case BUILT_IN_LOG2L:
5325 case BUILT_IN_TAN:
5326 case BUILT_IN_TANF:
5327 case BUILT_IN_TANL:
5328 case BUILT_IN_ASIN:
5329 case BUILT_IN_ASINF:
5330 case BUILT_IN_ASINL:
5331 case BUILT_IN_ACOS:
5332 case BUILT_IN_ACOSF:
5333 case BUILT_IN_ACOSL:
5334 case BUILT_IN_ATAN:
5335 case BUILT_IN_ATANF:
5336 case BUILT_IN_ATANL:
5337 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5338 because of possible accuracy problems. */
5339 if (! flag_unsafe_math_optimizations)
5340 break;
5341 case BUILT_IN_SQRT:
5342 case BUILT_IN_SQRTF:
5343 case BUILT_IN_SQRTL:
5344 case BUILT_IN_FLOOR:
5345 case BUILT_IN_FLOORF:
5346 case BUILT_IN_FLOORL:
5347 case BUILT_IN_CEIL:
5348 case BUILT_IN_CEILF:
5349 case BUILT_IN_CEILL:
5350 case BUILT_IN_TRUNC:
5351 case BUILT_IN_TRUNCF:
5352 case BUILT_IN_TRUNCL:
5353 case BUILT_IN_ROUND:
5354 case BUILT_IN_ROUNDF:
5355 case BUILT_IN_ROUNDL:
5356 case BUILT_IN_NEARBYINT:
5357 case BUILT_IN_NEARBYINTF:
5358 case BUILT_IN_NEARBYINTL:
5359 target = expand_builtin_mathfn (exp, target, subtarget);
5360 if (target)
5361 return target;
5362 break;
5364 case BUILT_IN_POW:
5365 case BUILT_IN_POWF:
5366 case BUILT_IN_POWL:
5367 target = expand_builtin_pow (exp, target, subtarget);
5368 if (target)
5369 return target;
5370 break;
5372 case BUILT_IN_ATAN2:
5373 case BUILT_IN_ATAN2F:
5374 case BUILT_IN_ATAN2L:
5375 case BUILT_IN_FMOD:
5376 case BUILT_IN_FMODF:
5377 case BUILT_IN_FMODL:
5378 case BUILT_IN_DREM:
5379 case BUILT_IN_DREMF:
5380 case BUILT_IN_DREML:
5381 if (! flag_unsafe_math_optimizations)
5382 break;
5383 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5384 if (target)
5385 return target;
5386 break;
5388 case BUILT_IN_SIN:
5389 case BUILT_IN_SINF:
5390 case BUILT_IN_SINL:
5391 case BUILT_IN_COS:
5392 case BUILT_IN_COSF:
5393 case BUILT_IN_COSL:
5394 if (! flag_unsafe_math_optimizations)
5395 break;
5396 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5397 if (target)
5398 return target;
5399 break;
5401 case BUILT_IN_APPLY_ARGS:
5402 return expand_builtin_apply_args ();
5404 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5405 FUNCTION with a copy of the parameters described by
5406 ARGUMENTS, and ARGSIZE. It returns a block of memory
5407 allocated on the stack into which is stored all the registers
5408 that might possibly be used for returning the result of a
5409 function. ARGUMENTS is the value returned by
5410 __builtin_apply_args. ARGSIZE is the number of bytes of
5411 arguments that must be copied. ??? How should this value be
5412 computed? We'll also need a safe worst case value for varargs
5413 functions. */
5414 case BUILT_IN_APPLY:
5415 if (!validate_arglist (arglist, POINTER_TYPE,
5416 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5417 && !validate_arglist (arglist, REFERENCE_TYPE,
5418 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5419 return const0_rtx;
5420 else
5422 int i;
5423 tree t;
5424 rtx ops[3];
5426 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5427 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5429 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5432 /* __builtin_return (RESULT) causes the function to return the
5433 value described by RESULT. RESULT is address of the block of
5434 memory returned by __builtin_apply. */
5435 case BUILT_IN_RETURN:
5436 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5437 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5438 NULL_RTX, VOIDmode, 0));
5439 return const0_rtx;
5441 case BUILT_IN_SAVEREGS:
5442 return expand_builtin_saveregs ();
5444 case BUILT_IN_ARGS_INFO:
5445 return expand_builtin_args_info (arglist);
5447 /* Return the address of the first anonymous stack arg. */
5448 case BUILT_IN_NEXT_ARG:
5449 return expand_builtin_next_arg (arglist);
5451 case BUILT_IN_CLASSIFY_TYPE:
5452 return expand_builtin_classify_type (arglist);
5454 case BUILT_IN_CONSTANT_P:
5455 return expand_builtin_constant_p (arglist, target_mode);
5457 case BUILT_IN_FRAME_ADDRESS:
5458 case BUILT_IN_RETURN_ADDRESS:
5459 return expand_builtin_frame_address (fndecl, arglist);
5461 /* Returns the address of the area where the structure is returned.
5462 0 otherwise. */
5463 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5464 if (arglist != 0
5465 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5466 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5467 return const0_rtx;
5468 else
5469 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5471 case BUILT_IN_ALLOCA:
5472 target = expand_builtin_alloca (arglist, target);
5473 if (target)
5474 return target;
5475 break;
5477 case BUILT_IN_FFS:
5478 case BUILT_IN_FFSL:
5479 case BUILT_IN_FFSLL:
5480 target = expand_builtin_unop (target_mode, arglist, target,
5481 subtarget, ffs_optab);
5482 if (target)
5483 return target;
5484 break;
5486 case BUILT_IN_CLZ:
5487 case BUILT_IN_CLZL:
5488 case BUILT_IN_CLZLL:
5489 target = expand_builtin_unop (target_mode, arglist, target,
5490 subtarget, clz_optab);
5491 if (target)
5492 return target;
5493 break;
5495 case BUILT_IN_CTZ:
5496 case BUILT_IN_CTZL:
5497 case BUILT_IN_CTZLL:
5498 target = expand_builtin_unop (target_mode, arglist, target,
5499 subtarget, ctz_optab);
5500 if (target)
5501 return target;
5502 break;
5504 case BUILT_IN_POPCOUNT:
5505 case BUILT_IN_POPCOUNTL:
5506 case BUILT_IN_POPCOUNTLL:
5507 target = expand_builtin_unop (target_mode, arglist, target,
5508 subtarget, popcount_optab);
5509 if (target)
5510 return target;
5511 break;
5513 case BUILT_IN_PARITY:
5514 case BUILT_IN_PARITYL:
5515 case BUILT_IN_PARITYLL:
5516 target = expand_builtin_unop (target_mode, arglist, target,
5517 subtarget, parity_optab);
5518 if (target)
5519 return target;
5520 break;
5522 case BUILT_IN_STRLEN:
5523 target = expand_builtin_strlen (arglist, target, target_mode);
5524 if (target)
5525 return target;
5526 break;
5528 case BUILT_IN_STRCPY:
5529 target = expand_builtin_strcpy (arglist, target, mode);
5530 if (target)
5531 return target;
5532 break;
5534 case BUILT_IN_STRNCPY:
5535 target = expand_builtin_strncpy (arglist, target, mode);
5536 if (target)
5537 return target;
5538 break;
5540 case BUILT_IN_STPCPY:
5541 target = expand_builtin_stpcpy (arglist, target, mode);
5542 if (target)
5543 return target;
5544 break;
5546 case BUILT_IN_STRCAT:
5547 target = expand_builtin_strcat (arglist, target, mode);
5548 if (target)
5549 return target;
5550 break;
5552 case BUILT_IN_STRNCAT:
5553 target = expand_builtin_strncat (arglist, target, mode);
5554 if (target)
5555 return target;
5556 break;
5558 case BUILT_IN_STRSPN:
5559 target = expand_builtin_strspn (arglist, target, mode);
5560 if (target)
5561 return target;
5562 break;
5564 case BUILT_IN_STRCSPN:
5565 target = expand_builtin_strcspn (arglist, target, mode);
5566 if (target)
5567 return target;
5568 break;
5570 case BUILT_IN_STRSTR:
5571 target = expand_builtin_strstr (arglist, target, mode);
5572 if (target)
5573 return target;
5574 break;
5576 case BUILT_IN_STRPBRK:
5577 target = expand_builtin_strpbrk (arglist, target, mode);
5578 if (target)
5579 return target;
5580 break;
5582 case BUILT_IN_INDEX:
5583 case BUILT_IN_STRCHR:
5584 target = expand_builtin_strchr (arglist, target, mode);
5585 if (target)
5586 return target;
5587 break;
5589 case BUILT_IN_RINDEX:
5590 case BUILT_IN_STRRCHR:
5591 target = expand_builtin_strrchr (arglist, target, mode);
5592 if (target)
5593 return target;
5594 break;
5596 case BUILT_IN_MEMCPY:
5597 target = expand_builtin_memcpy (arglist, target, mode);
5598 if (target)
5599 return target;
5600 break;
5602 case BUILT_IN_MEMPCPY:
5603 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5604 if (target)
5605 return target;
5606 break;
5608 case BUILT_IN_MEMMOVE:
5609 target = expand_builtin_memmove (arglist, target, mode);
5610 if (target)
5611 return target;
5612 break;
5614 case BUILT_IN_BCOPY:
5615 target = expand_builtin_bcopy (arglist);
5616 if (target)
5617 return target;
5618 break;
5620 case BUILT_IN_MEMSET:
5621 target = expand_builtin_memset (arglist, target, mode);
5622 if (target)
5623 return target;
5624 break;
5626 case BUILT_IN_BZERO:
5627 target = expand_builtin_bzero (arglist);
5628 if (target)
5629 return target;
5630 break;
5632 case BUILT_IN_STRCMP:
5633 target = expand_builtin_strcmp (exp, target, mode);
5634 if (target)
5635 return target;
5636 break;
5638 case BUILT_IN_STRNCMP:
5639 target = expand_builtin_strncmp (exp, target, mode);
5640 if (target)
5641 return target;
5642 break;
5644 case BUILT_IN_BCMP:
5645 case BUILT_IN_MEMCMP:
5646 target = expand_builtin_memcmp (exp, arglist, target, mode);
5647 if (target)
5648 return target;
5649 break;
5651 case BUILT_IN_SETJMP:
5652 target = expand_builtin_setjmp (arglist, target);
5653 if (target)
5654 return target;
5655 break;
5657 /* __builtin_longjmp is passed a pointer to an array of five words.
5658 It's similar to the C library longjmp function but works with
5659 __builtin_setjmp above. */
5660 case BUILT_IN_LONGJMP:
5661 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5662 break;
5663 else
5665 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5666 VOIDmode, 0);
5667 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5668 NULL_RTX, VOIDmode, 0);
5670 if (value != const1_rtx)
5672 error ("__builtin_longjmp second argument must be 1");
5673 return const0_rtx;
5676 expand_builtin_longjmp (buf_addr, value);
5677 return const0_rtx;
5680 /* This updates the setjmp buffer that is its argument with the value
5681 of the current stack pointer. */
5682 case BUILT_IN_UPDATE_SETJMP_BUF:
5683 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5685 rtx buf_addr
5686 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5688 expand_builtin_update_setjmp_buf (buf_addr);
5689 return const0_rtx;
5691 break;
5693 case BUILT_IN_TRAP:
5694 expand_builtin_trap ();
5695 return const0_rtx;
5697 case BUILT_IN_PRINTF:
5698 target = expand_builtin_printf (arglist, target, mode, false);
5699 if (target)
5700 return target;
5701 break;
5703 case BUILT_IN_PRINTF_UNLOCKED:
5704 target = expand_builtin_printf (arglist, target, mode, true);
5705 if (target)
5706 return target;
5707 break;
5709 case BUILT_IN_FPUTS:
5710 target = expand_builtin_fputs (arglist, target, false);
5711 if (target)
5712 return target;
5713 break;
5715 case BUILT_IN_FPUTS_UNLOCKED:
5716 target = expand_builtin_fputs (arglist, target, true);
5717 if (target)
5718 return target;
5719 break;
5721 case BUILT_IN_FPRINTF:
5722 target = expand_builtin_fprintf (arglist, target, mode, false);
5723 if (target)
5724 return target;
5725 break;
5727 case BUILT_IN_FPRINTF_UNLOCKED:
5728 target = expand_builtin_fprintf (arglist, target, mode, true);
5729 if (target)
5730 return target;
5731 break;
5733 case BUILT_IN_SPRINTF:
5734 target = expand_builtin_sprintf (arglist, target, mode);
5735 if (target)
5736 return target;
5737 break;
5739 case BUILT_IN_SIGNBIT:
5740 case BUILT_IN_SIGNBITF:
5741 case BUILT_IN_SIGNBITL:
5742 target = expand_builtin_signbit (exp, target);
5743 if (target)
5744 return target;
5745 break;
5747 /* Various hooks for the DWARF 2 __throw routine. */
5748 case BUILT_IN_UNWIND_INIT:
5749 expand_builtin_unwind_init ();
5750 return const0_rtx;
5751 case BUILT_IN_DWARF_CFA:
5752 return virtual_cfa_rtx;
5753 #ifdef DWARF2_UNWIND_INFO
5754 case BUILT_IN_DWARF_SP_COLUMN:
5755 return expand_builtin_dwarf_sp_column ();
5756 case BUILT_IN_INIT_DWARF_REG_SIZES:
5757 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5758 return const0_rtx;
5759 #endif
5760 case BUILT_IN_FROB_RETURN_ADDR:
5761 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5762 case BUILT_IN_EXTRACT_RETURN_ADDR:
5763 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5764 case BUILT_IN_EH_RETURN:
5765 expand_builtin_eh_return (TREE_VALUE (arglist),
5766 TREE_VALUE (TREE_CHAIN (arglist)));
5767 return const0_rtx;
5768 #ifdef EH_RETURN_DATA_REGNO
5769 case BUILT_IN_EH_RETURN_DATA_REGNO:
5770 return expand_builtin_eh_return_data_regno (arglist);
5771 #endif
5772 case BUILT_IN_EXTEND_POINTER:
5773 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5775 case BUILT_IN_VA_START:
5776 case BUILT_IN_STDARG_START:
5777 return expand_builtin_va_start (arglist);
5778 case BUILT_IN_VA_END:
5779 return expand_builtin_va_end (arglist);
5780 case BUILT_IN_VA_COPY:
5781 return expand_builtin_va_copy (arglist);
5782 case BUILT_IN_EXPECT:
5783 return expand_builtin_expect (arglist, target);
5784 case BUILT_IN_PREFETCH:
5785 expand_builtin_prefetch (arglist);
5786 return const0_rtx;
5788 case BUILT_IN_FORK:
5789 case BUILT_IN_EXECL:
5790 case BUILT_IN_EXECV:
5791 case BUILT_IN_EXECLP:
5792 case BUILT_IN_EXECLE:
5793 case BUILT_IN_EXECVP:
5794 case BUILT_IN_EXECVE:
5795 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5796 if (target)
5797 return target;
5798 break;
5800 default: /* just do library call, if unknown builtin */
5801 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5802 error ("built-in function `%s' not currently supported",
5803 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5806 /* The switch statement above can drop through to cause the function
5807 to be called normally. */
5808 return expand_call (exp, target, ignore);
5811 /* Determine whether a tree node represents a call to a built-in
5812 function. If the tree T is a call to a built-in function with
5813 the right number of arguments of the appropriate types, return
5814 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5815 Otherwise the return value is END_BUILTINS. */
5817 enum built_in_function
5818 builtin_mathfn_code (tree t)
5820 tree fndecl, arglist, parmlist;
5821 tree argtype, parmtype;
5823 if (TREE_CODE (t) != CALL_EXPR
5824 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5825 return END_BUILTINS;
5827 fndecl = get_callee_fndecl (t);
5828 if (fndecl == NULL_TREE
5829 || TREE_CODE (fndecl) != FUNCTION_DECL
5830 || ! DECL_BUILT_IN (fndecl)
5831 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5832 return END_BUILTINS;
5834 arglist = TREE_OPERAND (t, 1);
5835 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5836 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5838 /* If a function doesn't take a variable number of arguments,
5839 the last element in the list will have type `void'. */
5840 parmtype = TREE_VALUE (parmlist);
5841 if (VOID_TYPE_P (parmtype))
5843 if (arglist)
5844 return END_BUILTINS;
5845 return DECL_FUNCTION_CODE (fndecl);
5848 if (! arglist)
5849 return END_BUILTINS;
5851 argtype = TREE_TYPE (TREE_VALUE (arglist));
5853 if (SCALAR_FLOAT_TYPE_P (parmtype))
5855 if (! SCALAR_FLOAT_TYPE_P (argtype))
5856 return END_BUILTINS;
5858 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5860 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5861 return END_BUILTINS;
5863 else if (POINTER_TYPE_P (parmtype))
5865 if (! POINTER_TYPE_P (argtype))
5866 return END_BUILTINS;
5868 else if (INTEGRAL_TYPE_P (parmtype))
5870 if (! INTEGRAL_TYPE_P (argtype))
5871 return END_BUILTINS;
5873 else
5874 return END_BUILTINS;
5876 arglist = TREE_CHAIN (arglist);
5879 /* Variable-length argument list. */
5880 return DECL_FUNCTION_CODE (fndecl);
5883 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5884 constant. ARGLIST is the argument list of the call. */
5886 static tree
5887 fold_builtin_constant_p (tree arglist)
5889 if (arglist == 0)
5890 return 0;
5892 arglist = TREE_VALUE (arglist);
5894 /* We return 1 for a numeric type that's known to be a constant
5895 value at compile-time or for an aggregate type that's a
5896 literal constant. */
5897 STRIP_NOPS (arglist);
5899 /* If we know this is a constant, emit the constant of one. */
5900 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5901 || (TREE_CODE (arglist) == CONSTRUCTOR
5902 && TREE_CONSTANT (arglist))
5903 || (TREE_CODE (arglist) == ADDR_EXPR
5904 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5905 return integer_one_node;
5907 /* If this expression has side effects, show we don't know it to be a
5908 constant. Likewise if it's a pointer or aggregate type since in
5909 those case we only want literals, since those are only optimized
5910 when generating RTL, not later.
5911 And finally, if we are compiling an initializer, not code, we
5912 need to return a definite result now; there's not going to be any
5913 more optimization done. */
5914 if (TREE_SIDE_EFFECTS (arglist)
5915 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5916 || POINTER_TYPE_P (TREE_TYPE (arglist))
5917 || cfun == 0)
5918 return integer_zero_node;
5920 return 0;
5923 /* Fold a call to __builtin_classify_type. */
5925 static tree
5926 fold_builtin_classify_type (tree arglist)
5928 if (arglist == 0)
5929 return build_int_2 (no_type_class, 0);
5931 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5934 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5936 static tree
5937 fold_builtin_inf (tree type, int warn)
5939 REAL_VALUE_TYPE real;
5941 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5942 warning ("target format does not support infinity");
5944 real_inf (&real);
5945 return build_real (type, real);
5948 /* Fold a call to __builtin_nan or __builtin_nans. */
5950 static tree
5951 fold_builtin_nan (tree arglist, tree type, int quiet)
5953 REAL_VALUE_TYPE real;
5954 const char *str;
5956 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5957 return 0;
5958 str = c_getstr (TREE_VALUE (arglist));
5959 if (!str)
5960 return 0;
5962 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5963 return 0;
5965 return build_real (type, real);
5968 /* Return true if the floating point expression T has an integer value.
5969 We also allow +Inf, -Inf and NaN to be considered integer values. */
5971 static bool
5972 integer_valued_real_p (tree t)
5974 switch (TREE_CODE (t))
5976 case FLOAT_EXPR:
5977 return true;
5979 case ABS_EXPR:
5980 case SAVE_EXPR:
5981 case NON_LVALUE_EXPR:
5982 return integer_valued_real_p (TREE_OPERAND (t, 0));
5984 case COMPOUND_EXPR:
5985 case MODIFY_EXPR:
5986 case BIND_EXPR:
5987 return integer_valued_real_p (TREE_OPERAND (t, 1));
5989 case PLUS_EXPR:
5990 case MINUS_EXPR:
5991 case MULT_EXPR:
5992 case MIN_EXPR:
5993 case MAX_EXPR:
5994 return integer_valued_real_p (TREE_OPERAND (t, 0))
5995 && integer_valued_real_p (TREE_OPERAND (t, 1));
5997 case COND_EXPR:
5998 return integer_valued_real_p (TREE_OPERAND (t, 1))
5999 && integer_valued_real_p (TREE_OPERAND (t, 2));
6001 case REAL_CST:
6002 if (! TREE_CONSTANT_OVERFLOW (t))
6004 REAL_VALUE_TYPE c, cint;
6006 c = TREE_REAL_CST (t);
6007 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6008 return real_identical (&c, &cint);
6011 case NOP_EXPR:
6013 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6014 if (TREE_CODE (type) == INTEGER_TYPE)
6015 return true;
6016 if (TREE_CODE (type) == REAL_TYPE)
6017 return integer_valued_real_p (TREE_OPERAND (t, 0));
6018 break;
6021 case CALL_EXPR:
6022 switch (builtin_mathfn_code (t))
6024 case BUILT_IN_CEIL:
6025 case BUILT_IN_CEILF:
6026 case BUILT_IN_CEILL:
6027 case BUILT_IN_FLOOR:
6028 case BUILT_IN_FLOORF:
6029 case BUILT_IN_FLOORL:
6030 case BUILT_IN_NEARBYINT:
6031 case BUILT_IN_NEARBYINTF:
6032 case BUILT_IN_NEARBYINTL:
6033 case BUILT_IN_RINT:
6034 case BUILT_IN_RINTF:
6035 case BUILT_IN_RINTL:
6036 case BUILT_IN_ROUND:
6037 case BUILT_IN_ROUNDF:
6038 case BUILT_IN_ROUNDL:
6039 case BUILT_IN_TRUNC:
6040 case BUILT_IN_TRUNCF:
6041 case BUILT_IN_TRUNCL:
6042 return true;
6044 default:
6045 break;
6047 break;
6049 default:
6050 break;
6052 return false;
6055 /* EXP is assumed to be builtin call where truncation can be propagated
6056 across (for instance floor((double)f) == (double)floorf (f).
6057 Do the transformation. */
6059 static tree
6060 fold_trunc_transparent_mathfn (tree exp)
6062 tree fndecl = get_callee_fndecl (exp);
6063 tree arglist = TREE_OPERAND (exp, 1);
6064 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6065 tree arg;
6067 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6068 return 0;
6070 arg = TREE_VALUE (arglist);
6071 /* Integer rounding functions are idempotent. */
6072 if (fcode == builtin_mathfn_code (arg))
6073 return arg;
6075 /* If argument is already integer valued, and we don't need to worry
6076 about setting errno, there's no need to perform rounding. */
6077 if (! flag_errno_math && integer_valued_real_p (arg))
6078 return arg;
6080 if (optimize)
6082 tree arg0 = strip_float_extensions (arg);
6083 tree ftype = TREE_TYPE (exp);
6084 tree newtype = TREE_TYPE (arg0);
6085 tree decl;
6087 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6088 && (decl = mathfn_built_in (newtype, fcode)))
6090 arglist =
6091 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6092 return fold_convert (ftype,
6093 build_function_call_expr (decl, arglist));
6096 return 0;
6099 /* EXP is assumed to be builtin call which can narrow the FP type of
6100 the argument, for instance lround((double)f) -> lroundf (f). */
6102 static tree
6103 fold_fixed_mathfn (tree exp)
6105 tree fndecl = get_callee_fndecl (exp);
6106 tree arglist = TREE_OPERAND (exp, 1);
6107 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6108 tree arg;
6110 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6111 return 0;
6113 arg = TREE_VALUE (arglist);
6115 /* If argument is already integer valued, and we don't need to worry
6116 about setting errno, there's no need to perform rounding. */
6117 if (! flag_errno_math && integer_valued_real_p (arg))
6118 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6120 if (optimize)
6122 tree ftype = TREE_TYPE (arg);
6123 tree arg0 = strip_float_extensions (arg);
6124 tree newtype = TREE_TYPE (arg0);
6125 tree decl;
6127 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6128 && (decl = mathfn_built_in (newtype, fcode)))
6130 arglist =
6131 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6132 return build_function_call_expr (decl, arglist);
6135 return 0;
6138 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6139 is the argument list and TYPE is the return type. Return
6140 NULL_TREE if no if no simplification can be made. */
6142 static tree
6143 fold_builtin_cabs (tree arglist, tree type)
6145 tree arg;
6147 if (!arglist || TREE_CHAIN (arglist))
6148 return NULL_TREE;
6150 arg = TREE_VALUE (arglist);
6151 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6152 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6153 return NULL_TREE;
6155 /* Evaluate cabs of a constant at compile-time. */
6156 if (flag_unsafe_math_optimizations
6157 && TREE_CODE (arg) == COMPLEX_CST
6158 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6159 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6160 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6161 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6163 REAL_VALUE_TYPE r, i;
6165 r = TREE_REAL_CST (TREE_REALPART (arg));
6166 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6168 real_arithmetic (&r, MULT_EXPR, &r, &r);
6169 real_arithmetic (&i, MULT_EXPR, &i, &i);
6170 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6171 if (real_sqrt (&r, TYPE_MODE (type), &r)
6172 || ! flag_trapping_math)
6173 return build_real (type, r);
6176 /* If either part is zero, cabs is fabs of the other. */
6177 if (TREE_CODE (arg) == COMPLEX_EXPR
6178 && real_zerop (TREE_OPERAND (arg, 0)))
6179 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6180 if (TREE_CODE (arg) == COMPLEX_EXPR
6181 && real_zerop (TREE_OPERAND (arg, 1)))
6182 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6184 if (flag_unsafe_math_optimizations)
6186 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6188 if (sqrtfn != NULL_TREE)
6190 tree rpart, ipart, result, arglist;
6192 arg = save_expr (arg);
6194 rpart = fold (build1 (REALPART_EXPR, type, arg));
6195 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6197 rpart = save_expr (rpart);
6198 ipart = save_expr (ipart);
6200 result = fold (build (PLUS_EXPR, type,
6201 fold (build (MULT_EXPR, type,
6202 rpart, rpart)),
6203 fold (build (MULT_EXPR, type,
6204 ipart, ipart))));
6206 arglist = build_tree_list (NULL_TREE, result);
6207 return build_function_call_expr (sqrtfn, arglist);
6211 return NULL_TREE;
6214 /* Fold function call to builtin trunc, truncf or truncl. Return
6215 NULL_TREE if no simplification can be made. */
6217 static tree
6218 fold_builtin_trunc (tree exp)
6220 tree arglist = TREE_OPERAND (exp, 1);
6221 tree arg;
6223 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6224 return 0;
6226 /* Optimize trunc of constant value. */
6227 arg = TREE_VALUE (arglist);
6228 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6230 REAL_VALUE_TYPE r, x;
6231 tree type = TREE_TYPE (exp);
6233 x = TREE_REAL_CST (arg);
6234 real_trunc (&r, TYPE_MODE (type), &x);
6235 return build_real (type, r);
6238 return fold_trunc_transparent_mathfn (exp);
6241 /* Fold function call to builtin floor, floorf or floorl. Return
6242 NULL_TREE if no simplification can be made. */
6244 static tree
6245 fold_builtin_floor (tree exp)
6247 tree arglist = TREE_OPERAND (exp, 1);
6248 tree arg;
6250 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6251 return 0;
6253 /* Optimize floor of constant value. */
6254 arg = TREE_VALUE (arglist);
6255 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6257 REAL_VALUE_TYPE x;
6259 x = TREE_REAL_CST (arg);
6260 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6262 tree type = TREE_TYPE (exp);
6263 REAL_VALUE_TYPE r;
6265 real_floor (&r, TYPE_MODE (type), &x);
6266 return build_real (type, r);
6270 return fold_trunc_transparent_mathfn (exp);
6273 /* Fold function call to builtin ceil, ceilf or ceill. Return
6274 NULL_TREE if no simplification can be made. */
6276 static tree
6277 fold_builtin_ceil (tree exp)
6279 tree arglist = TREE_OPERAND (exp, 1);
6280 tree arg;
6282 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6283 return 0;
6285 /* Optimize ceil of constant value. */
6286 arg = TREE_VALUE (arglist);
6287 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6289 REAL_VALUE_TYPE x;
6291 x = TREE_REAL_CST (arg);
6292 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6294 tree type = TREE_TYPE (exp);
6295 REAL_VALUE_TYPE r;
6297 real_ceil (&r, TYPE_MODE (type), &x);
6298 return build_real (type, r);
6302 return fold_trunc_transparent_mathfn (exp);
6305 /* Fold function call to builtin round, roundf or roundl. Return
6306 NULL_TREE if no simplification can be made. */
6308 static tree
6309 fold_builtin_round (tree exp)
6311 tree arglist = TREE_OPERAND (exp, 1);
6312 tree arg;
6314 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6315 return 0;
6317 /* Optimize round of constant value. */
6318 arg = TREE_VALUE (arglist);
6319 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6321 REAL_VALUE_TYPE x;
6323 x = TREE_REAL_CST (arg);
6324 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6326 tree type = TREE_TYPE (exp);
6327 REAL_VALUE_TYPE r;
6329 real_round (&r, TYPE_MODE (type), &x);
6330 return build_real (type, r);
6334 return fold_trunc_transparent_mathfn (exp);
6337 /* Fold function call to builtin lround, lroundf or lroundl (or the
6338 corresponding long long versions). Return NULL_TREE if no
6339 simplification can be made. */
6341 static tree
6342 fold_builtin_lround (tree exp)
6344 tree arglist = TREE_OPERAND (exp, 1);
6345 tree arg;
6347 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6348 return 0;
6350 /* Optimize lround of constant value. */
6351 arg = TREE_VALUE (arglist);
6352 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6354 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6356 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6358 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6359 HOST_WIDE_INT hi, lo;
6360 REAL_VALUE_TYPE r;
6362 real_round (&r, TYPE_MODE (ftype), &x);
6363 REAL_VALUE_TO_INT (&lo, &hi, r);
6364 result = build_int_2 (lo, hi);
6365 if (int_fits_type_p (result, itype))
6366 return fold_convert (itype, result);
6370 return fold_fixed_mathfn (exp);
6373 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6374 and their long and long long variants (i.e. ffsl and ffsll).
6375 Return NULL_TREE if no simplification can be made. */
6377 static tree
6378 fold_builtin_bitop (tree exp)
6380 tree fndecl = get_callee_fndecl (exp);
6381 tree arglist = TREE_OPERAND (exp, 1);
6382 tree arg;
6384 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6385 return NULL_TREE;
6387 /* Optimize for constant argument. */
6388 arg = TREE_VALUE (arglist);
6389 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6391 HOST_WIDE_INT hi, width, result;
6392 unsigned HOST_WIDE_INT lo;
6393 tree type, t;
6395 type = TREE_TYPE (arg);
6396 width = TYPE_PRECISION (type);
6397 lo = TREE_INT_CST_LOW (arg);
6399 /* Clear all the bits that are beyond the type's precision. */
6400 if (width > HOST_BITS_PER_WIDE_INT)
6402 hi = TREE_INT_CST_HIGH (arg);
6403 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6404 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6406 else
6408 hi = 0;
6409 if (width < HOST_BITS_PER_WIDE_INT)
6410 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6413 switch (DECL_FUNCTION_CODE (fndecl))
6415 case BUILT_IN_FFS:
6416 case BUILT_IN_FFSL:
6417 case BUILT_IN_FFSLL:
6418 if (lo != 0)
6419 result = exact_log2 (lo & -lo) + 1;
6420 else if (hi != 0)
6421 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6422 else
6423 result = 0;
6424 break;
6426 case BUILT_IN_CLZ:
6427 case BUILT_IN_CLZL:
6428 case BUILT_IN_CLZLL:
6429 if (hi != 0)
6430 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6431 else if (lo != 0)
6432 result = width - floor_log2 (lo) - 1;
6433 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6434 result = width;
6435 break;
6437 case BUILT_IN_CTZ:
6438 case BUILT_IN_CTZL:
6439 case BUILT_IN_CTZLL:
6440 if (lo != 0)
6441 result = exact_log2 (lo & -lo);
6442 else if (hi != 0)
6443 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6444 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6445 result = width;
6446 break;
6448 case BUILT_IN_POPCOUNT:
6449 case BUILT_IN_POPCOUNTL:
6450 case BUILT_IN_POPCOUNTLL:
6451 result = 0;
6452 while (lo)
6453 result++, lo &= lo - 1;
6454 while (hi)
6455 result++, hi &= hi - 1;
6456 break;
6458 case BUILT_IN_PARITY:
6459 case BUILT_IN_PARITYL:
6460 case BUILT_IN_PARITYLL:
6461 result = 0;
6462 while (lo)
6463 result++, lo &= lo - 1;
6464 while (hi)
6465 result++, hi &= hi - 1;
6466 result &= 1;
6467 break;
6469 default:
6470 abort();
6473 t = build_int_2 (result, 0);
6474 TREE_TYPE (t) = TREE_TYPE (exp);
6475 return t;
6478 return NULL_TREE;
6481 /* Return true if EXPR is the real constant contained in VALUE. */
6483 static bool
6484 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6486 STRIP_NOPS (expr);
6488 return ((TREE_CODE (expr) == REAL_CST
6489 && ! TREE_CONSTANT_OVERFLOW (expr)
6490 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6491 || (TREE_CODE (expr) == COMPLEX_CST
6492 && real_dconstp (TREE_REALPART (expr), value)
6493 && real_zerop (TREE_IMAGPART (expr))));
6496 /* A subroutine of fold_builtin to fold the various logarithmic
6497 functions. EXP is the CALL_EXPR of a call to a builtin logN
6498 function. VALUE is the base of the logN function. */
6500 static tree
6501 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6503 tree arglist = TREE_OPERAND (exp, 1);
6505 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6507 tree fndecl = get_callee_fndecl (exp);
6508 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6509 tree arg = TREE_VALUE (arglist);
6510 const enum built_in_function fcode = builtin_mathfn_code (arg);
6512 /* Optimize logN(1.0) = 0.0. */
6513 if (real_onep (arg))
6514 return build_real (type, dconst0);
6516 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6517 exactly, then only do this if flag_unsafe_math_optimizations. */
6518 if (exact_real_truncate (TYPE_MODE (type), value)
6519 || flag_unsafe_math_optimizations)
6521 const REAL_VALUE_TYPE value_truncate =
6522 real_value_truncate (TYPE_MODE (type), *value);
6523 if (real_dconstp (arg, &value_truncate))
6524 return build_real (type, dconst1);
6527 /* Special case, optimize logN(expN(x)) = x. */
6528 if (flag_unsafe_math_optimizations
6529 && ((value == &dconste
6530 && (fcode == BUILT_IN_EXP
6531 || fcode == BUILT_IN_EXPF
6532 || fcode == BUILT_IN_EXPL))
6533 || (value == &dconst2
6534 && (fcode == BUILT_IN_EXP2
6535 || fcode == BUILT_IN_EXP2F
6536 || fcode == BUILT_IN_EXP2L))
6537 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6538 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6540 /* Optimize logN(func()) for various exponential functions. We
6541 want to determine the value "x" and the power "exponent" in
6542 order to transform logN(x**exponent) into exponent*logN(x). */
6543 if (flag_unsafe_math_optimizations)
6545 tree exponent = 0, x = 0;
6547 switch (fcode)
6549 case BUILT_IN_EXP:
6550 case BUILT_IN_EXPF:
6551 case BUILT_IN_EXPL:
6552 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6553 x = build_real (type,
6554 real_value_truncate (TYPE_MODE (type), dconste));
6555 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6556 break;
6557 case BUILT_IN_EXP2:
6558 case BUILT_IN_EXP2F:
6559 case BUILT_IN_EXP2L:
6560 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6561 x = build_real (type, dconst2);
6562 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6563 break;
6564 case BUILT_IN_EXP10:
6565 case BUILT_IN_EXP10F:
6566 case BUILT_IN_EXP10L:
6567 case BUILT_IN_POW10:
6568 case BUILT_IN_POW10F:
6569 case BUILT_IN_POW10L:
6570 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6571 x = build_real (type, dconst10);
6572 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6573 break;
6574 case BUILT_IN_SQRT:
6575 case BUILT_IN_SQRTF:
6576 case BUILT_IN_SQRTL:
6577 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6578 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6579 exponent = build_real (type, dconsthalf);
6580 break;
6581 case BUILT_IN_CBRT:
6582 case BUILT_IN_CBRTF:
6583 case BUILT_IN_CBRTL:
6584 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6585 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6586 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6587 dconstthird));
6588 break;
6589 case BUILT_IN_POW:
6590 case BUILT_IN_POWF:
6591 case BUILT_IN_POWL:
6592 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6593 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6594 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6595 break;
6596 default:
6597 break;
6600 /* Now perform the optimization. */
6601 if (x && exponent)
6603 tree logfn;
6604 arglist = build_tree_list (NULL_TREE, x);
6605 logfn = build_function_call_expr (fndecl, arglist);
6606 return fold (build (MULT_EXPR, type, exponent, logfn));
6611 return 0;
6614 /* A subroutine of fold_builtin to fold the various exponent
6615 functions. EXP is the CALL_EXPR of a call to a builtin function.
6616 VALUE is the value which will be raised to a power. */
6618 static tree
6619 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6621 tree arglist = TREE_OPERAND (exp, 1);
6623 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6625 tree fndecl = get_callee_fndecl (exp);
6626 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6627 tree arg = TREE_VALUE (arglist);
6629 /* Optimize exp*(0.0) = 1.0. */
6630 if (real_zerop (arg))
6631 return build_real (type, dconst1);
6633 /* Optimize expN(1.0) = N. */
6634 if (real_onep (arg))
6636 REAL_VALUE_TYPE cst;
6638 real_convert (&cst, TYPE_MODE (type), value);
6639 return build_real (type, cst);
6642 /* Attempt to evaluate expN(integer) at compile-time. */
6643 if (flag_unsafe_math_optimizations
6644 && TREE_CODE (arg) == REAL_CST
6645 && ! TREE_CONSTANT_OVERFLOW (arg))
6647 REAL_VALUE_TYPE cint;
6648 REAL_VALUE_TYPE c;
6649 HOST_WIDE_INT n;
6651 c = TREE_REAL_CST (arg);
6652 n = real_to_integer (&c);
6653 real_from_integer (&cint, VOIDmode, n,
6654 n < 0 ? -1 : 0, 0);
6655 if (real_identical (&c, &cint))
6657 REAL_VALUE_TYPE x;
6659 real_powi (&x, TYPE_MODE (type), value, n);
6660 return build_real (type, x);
6664 /* Optimize expN(logN(x)) = x. */
6665 if (flag_unsafe_math_optimizations)
6667 const enum built_in_function fcode = builtin_mathfn_code (arg);
6669 if ((value == &dconste
6670 && (fcode == BUILT_IN_LOG
6671 || fcode == BUILT_IN_LOGF
6672 || fcode == BUILT_IN_LOGL))
6673 || (value == &dconst2
6674 && (fcode == BUILT_IN_LOG2
6675 || fcode == BUILT_IN_LOG2F
6676 || fcode == BUILT_IN_LOG2L))
6677 || (value == &dconst10
6678 && (fcode == BUILT_IN_LOG10
6679 || fcode == BUILT_IN_LOG10F
6680 || fcode == BUILT_IN_LOG10L)))
6681 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6685 return 0;
6688 /* Fold function call to builtin memcpy. Return
6689 NULL_TREE if no simplification can be made. */
6691 static tree
6692 fold_builtin_memcpy (tree exp)
6694 tree arglist = TREE_OPERAND (exp, 1);
6695 tree dest, src, len;
6697 if (!validate_arglist (arglist,
6698 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6699 return 0;
6701 dest = TREE_VALUE (arglist);
6702 src = TREE_VALUE (TREE_CHAIN (arglist));
6703 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6705 /* If the LEN parameter is zero, return DEST. */
6706 if (integer_zerop (len))
6707 return omit_one_operand (TREE_TYPE (exp), dest, src);
6709 /* If SRC and DEST are the same (and not volatile), return DEST. */
6710 if (operand_equal_p (src, dest, 0))
6711 return omit_one_operand (TREE_TYPE (exp), dest, len);
6713 return 0;
6716 /* Fold function call to builtin mempcpy. Return
6717 NULL_TREE if no simplification can be made. */
6719 static tree
6720 fold_builtin_mempcpy (tree exp)
6722 tree arglist = TREE_OPERAND (exp, 1);
6723 tree dest, src, len;
6725 if (!validate_arglist (arglist,
6726 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6727 return 0;
6729 dest = TREE_VALUE (arglist);
6730 src = TREE_VALUE (TREE_CHAIN (arglist));
6731 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6733 /* If the LEN parameter is zero, return DEST. */
6734 if (integer_zerop (len))
6735 return omit_one_operand (TREE_TYPE (exp), dest, src);
6737 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6738 if (operand_equal_p (src, dest, 0))
6740 tree temp = fold_convert (TREE_TYPE (dest), len);
6741 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
6742 return fold_convert (TREE_TYPE (exp), temp);
6745 return 0;
6748 /* Fold function call to builtin memmove. Return
6749 NULL_TREE if no simplification can be made. */
6751 static tree
6752 fold_builtin_memmove (tree exp)
6754 tree arglist = TREE_OPERAND (exp, 1);
6755 tree dest, src, len;
6757 if (!validate_arglist (arglist,
6758 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6759 return 0;
6761 dest = TREE_VALUE (arglist);
6762 src = TREE_VALUE (TREE_CHAIN (arglist));
6763 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6765 /* If the LEN parameter is zero, return DEST. */
6766 if (integer_zerop (len))
6767 return omit_one_operand (TREE_TYPE (exp), dest, src);
6769 /* If SRC and DEST are the same (and not volatile), return DEST. */
6770 if (operand_equal_p (src, dest, 0))
6771 return omit_one_operand (TREE_TYPE (exp), dest, len);
6773 return 0;
6776 /* Fold function call to builtin strcpy. Return
6777 NULL_TREE if no simplification can be made. */
6779 static tree
6780 fold_builtin_strcpy (tree exp)
6782 tree arglist = TREE_OPERAND (exp, 1);
6783 tree dest, src;
6785 if (!validate_arglist (arglist,
6786 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6787 return 0;
6789 dest = TREE_VALUE (arglist);
6790 src = TREE_VALUE (TREE_CHAIN (arglist));
6792 /* If SRC and DEST are the same (and not volatile), return DEST. */
6793 if (operand_equal_p (src, dest, 0))
6794 return fold_convert (TREE_TYPE (exp), dest);
6796 return 0;
6799 /* Fold function call to builtin strncpy. Return
6800 NULL_TREE if no simplification can be made. */
6802 static tree
6803 fold_builtin_strncpy (tree exp)
6805 tree arglist = TREE_OPERAND (exp, 1);
6806 tree dest, src, len;
6808 if (!validate_arglist (arglist,
6809 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6810 return 0;
6812 dest = TREE_VALUE (arglist);
6813 src = TREE_VALUE (TREE_CHAIN (arglist));
6814 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6816 /* If the LEN parameter is zero, return DEST. */
6817 if (integer_zerop (len))
6818 return omit_one_operand (TREE_TYPE (exp), dest, src);
6820 return 0;
6823 /* Fold function call to builtin memcmp. Return
6824 NULL_TREE if no simplification can be made. */
6826 static tree
6827 fold_builtin_memcmp (tree exp)
6829 tree arglist = TREE_OPERAND (exp, 1);
6830 tree arg1, arg2, len;
6832 if (!validate_arglist (arglist,
6833 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6834 return 0;
6836 arg1 = TREE_VALUE (arglist);
6837 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6838 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6840 /* If the LEN parameter is zero, return zero. */
6841 if (integer_zerop (len))
6843 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6844 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6847 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6848 if (operand_equal_p (arg1, arg2, 0))
6849 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6851 return 0;
6854 /* Fold function call to builtin strcmp. Return
6855 NULL_TREE if no simplification can be made. */
6857 static tree
6858 fold_builtin_strcmp (tree exp)
6860 tree arglist = TREE_OPERAND (exp, 1);
6861 tree arg1, arg2;
6862 const char *p1, *p2;
6864 if (!validate_arglist (arglist,
6865 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6866 return 0;
6868 arg1 = TREE_VALUE (arglist);
6869 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6871 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6872 if (operand_equal_p (arg1, arg2, 0))
6873 return fold_convert (TREE_TYPE (exp), integer_zero_node);
6875 p1 = c_getstr (arg1);
6876 p2 = c_getstr (arg2);
6878 if (p1 && p2)
6880 tree temp;
6881 const int i = strcmp (p1, p2);
6882 if (i < 0)
6883 temp = integer_minus_one_node;
6884 else if (i > 0)
6885 temp = integer_one_node;
6886 else
6887 temp = integer_zero_node;
6888 return fold_convert (TREE_TYPE (exp), temp);
6891 return 0;
6894 /* Fold function call to builtin strncmp. Return
6895 NULL_TREE if no simplification can be made. */
6897 static tree
6898 fold_builtin_strncmp (tree exp)
6900 tree arglist = TREE_OPERAND (exp, 1);
6901 tree arg1, arg2, len;
6902 const char *p1, *p2;
6904 if (!validate_arglist (arglist,
6905 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6906 return 0;
6908 arg1 = TREE_VALUE (arglist);
6909 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6910 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6912 /* If the LEN parameter is zero, return zero. */
6913 if (integer_zerop (len))
6915 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6916 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6919 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6920 if (operand_equal_p (arg1, arg2, 0))
6921 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6923 p1 = c_getstr (arg1);
6924 p2 = c_getstr (arg2);
6926 if (host_integerp (len, 1) && p1 && p2)
6928 tree temp;
6929 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6930 if (i < 0)
6931 temp = integer_minus_one_node;
6932 else if (i > 0)
6933 temp = integer_one_node;
6934 else
6935 temp = integer_zero_node;
6936 return fold_convert (TREE_TYPE (exp), temp);
6939 return 0;
6942 /* Fold function call to builtin signbit, signbitf or signbitl. Return
6943 NULL_TREE if no simplification can be made. */
6945 static tree
6946 fold_builtin_signbit (tree exp)
6948 tree arglist = TREE_OPERAND (exp, 1);
6949 tree arg, temp;
6951 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6952 return NULL_TREE;
6954 arg = TREE_VALUE (arglist);
6956 /* If ARG is a compile-time constant, determine the result. */
6957 if (TREE_CODE (arg) == REAL_CST
6958 && !TREE_CONSTANT_OVERFLOW (arg))
6960 REAL_VALUE_TYPE c;
6962 c = TREE_REAL_CST (arg);
6963 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
6964 return fold_convert (TREE_TYPE (exp), temp);
6967 /* If ARG is non-negative, the result is always zero. */
6968 if (tree_expr_nonnegative_p (arg))
6969 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
6971 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
6972 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
6973 return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
6974 build_real (TREE_TYPE (arg), dconst0)));
6976 return NULL_TREE;
6979 /* Fold a call to builtin isascii. */
6981 static tree
6982 fold_builtin_isascii (tree arglist)
6984 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6985 return 0;
6986 else
6988 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
6989 tree arg = TREE_VALUE (arglist);
6991 return fold (build (EQ_EXPR, integer_type_node,
6992 build (BIT_AND_EXPR, integer_type_node, arg,
6993 build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
6994 ~ (HOST_WIDE_INT) 0)),
6995 integer_zero_node));
6999 /* Fold a call to builtin toascii. */
7001 static tree
7002 fold_builtin_toascii (tree arglist)
7004 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7005 return 0;
7006 else
7008 /* Transform toascii(c) -> (c & 0x7f). */
7009 tree arg = TREE_VALUE (arglist);
7011 return fold (build (BIT_AND_EXPR, integer_type_node, arg,
7012 build_int_2 (0x7f, 0)));
7016 /* Fold a call to builtin isdigit. */
7018 static tree
7019 fold_builtin_isdigit (tree arglist)
7021 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7022 return 0;
7023 else
7025 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7026 /* According to the C standard, isdigit is unaffected by locale. */
7027 tree arg = TREE_VALUE (arglist);
7028 arg = fold_convert (unsigned_type_node, arg);
7029 arg = build (MINUS_EXPR, unsigned_type_node, arg,
7030 fold_convert (unsigned_type_node,
7031 build_int_2 (TARGET_DIGIT0, 0)));
7032 arg = build (LE_EXPR, integer_type_node, arg,
7033 fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7034 return fold (arg);
7038 /* Used by constant folding to eliminate some builtin calls early. EXP is
7039 the CALL_EXPR of a call to a builtin function. */
7041 tree
7042 fold_builtin (tree exp)
7044 tree fndecl = get_callee_fndecl (exp);
7045 tree arglist = TREE_OPERAND (exp, 1);
7046 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7048 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7049 return 0;
7051 switch (DECL_FUNCTION_CODE (fndecl))
7053 case BUILT_IN_CONSTANT_P:
7054 return fold_builtin_constant_p (arglist);
7056 case BUILT_IN_CLASSIFY_TYPE:
7057 return fold_builtin_classify_type (arglist);
7059 case BUILT_IN_STRLEN:
7060 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7062 tree len = c_strlen (TREE_VALUE (arglist), 0);
7063 if (len)
7065 /* Convert from the internal "sizetype" type to "size_t". */
7066 if (size_type_node)
7067 len = fold_convert (size_type_node, len);
7068 return len;
7071 break;
7073 case BUILT_IN_FABS:
7074 case BUILT_IN_FABSF:
7075 case BUILT_IN_FABSL:
7076 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7077 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
7078 break;
7080 case BUILT_IN_CABS:
7081 case BUILT_IN_CABSF:
7082 case BUILT_IN_CABSL:
7083 return fold_builtin_cabs (arglist, type);
7085 case BUILT_IN_SQRT:
7086 case BUILT_IN_SQRTF:
7087 case BUILT_IN_SQRTL:
7088 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7090 enum built_in_function fcode;
7091 tree arg = TREE_VALUE (arglist);
7093 /* Optimize sqrt of constant value. */
7094 if (TREE_CODE (arg) == REAL_CST
7095 && ! TREE_CONSTANT_OVERFLOW (arg))
7097 REAL_VALUE_TYPE r, x;
7099 x = TREE_REAL_CST (arg);
7100 if (real_sqrt (&r, TYPE_MODE (type), &x)
7101 || (!flag_trapping_math && !flag_errno_math))
7102 return build_real (type, r);
7105 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7106 fcode = builtin_mathfn_code (arg);
7107 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7109 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7110 arg = fold (build (MULT_EXPR, type,
7111 TREE_VALUE (TREE_OPERAND (arg, 1)),
7112 build_real (type, dconsthalf)));
7113 arglist = build_tree_list (NULL_TREE, arg);
7114 return build_function_call_expr (expfn, arglist);
7117 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7118 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7120 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7122 if (powfn)
7124 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7125 tree tree_root;
7126 /* The inner root was either sqrt or cbrt. */
7127 REAL_VALUE_TYPE dconstroot =
7128 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7130 /* Adjust for the outer root. */
7131 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7132 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7133 tree_root = build_real (type, dconstroot);
7134 arglist = tree_cons (NULL_TREE, arg0,
7135 build_tree_list (NULL_TREE, tree_root));
7136 return build_function_call_expr (powfn, arglist);
7140 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
7141 if (flag_unsafe_math_optimizations
7142 && (fcode == BUILT_IN_POW
7143 || fcode == BUILT_IN_POWF
7144 || fcode == BUILT_IN_POWL))
7146 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7147 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7148 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7149 tree narg1 = fold (build (MULT_EXPR, type, arg1,
7150 build_real (type, dconsthalf)));
7151 arglist = tree_cons (NULL_TREE, arg0,
7152 build_tree_list (NULL_TREE, narg1));
7153 return build_function_call_expr (powfn, arglist);
7156 break;
7158 case BUILT_IN_CBRT:
7159 case BUILT_IN_CBRTF:
7160 case BUILT_IN_CBRTL:
7161 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7163 tree arg = TREE_VALUE (arglist);
7164 const enum built_in_function fcode = builtin_mathfn_code (arg);
7166 /* Optimize cbrt of constant value. */
7167 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7168 return arg;
7170 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7171 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7173 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7174 const REAL_VALUE_TYPE third_trunc =
7175 real_value_truncate (TYPE_MODE (type), dconstthird);
7176 arg = fold (build (MULT_EXPR, type,
7177 TREE_VALUE (TREE_OPERAND (arg, 1)),
7178 build_real (type, third_trunc)));
7179 arglist = build_tree_list (NULL_TREE, arg);
7180 return build_function_call_expr (expfn, arglist);
7183 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7184 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
7185 x is negative pow will error but cbrt won't. */
7186 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7188 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7190 if (powfn)
7192 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7193 tree tree_root;
7194 REAL_VALUE_TYPE dconstroot = dconstthird;
7196 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7197 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7198 tree_root = build_real (type, dconstroot);
7199 arglist = tree_cons (NULL_TREE, arg0,
7200 build_tree_list (NULL_TREE, tree_root));
7201 return build_function_call_expr (powfn, arglist);
7206 break;
7208 case BUILT_IN_SIN:
7209 case BUILT_IN_SINF:
7210 case BUILT_IN_SINL:
7211 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7213 tree arg = TREE_VALUE (arglist);
7215 /* Optimize sin(0.0) = 0.0. */
7216 if (real_zerop (arg))
7217 return arg;
7219 break;
7221 case BUILT_IN_COS:
7222 case BUILT_IN_COSF:
7223 case BUILT_IN_COSL:
7224 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7226 tree arg = TREE_VALUE (arglist);
7228 /* Optimize cos(0.0) = 1.0. */
7229 if (real_zerop (arg))
7230 return build_real (type, dconst1);
7232 /* Optimize cos(-x) into cos(x). */
7233 if (TREE_CODE (arg) == NEGATE_EXPR)
7235 tree arglist = build_tree_list (NULL_TREE,
7236 TREE_OPERAND (arg, 0));
7237 return build_function_call_expr (fndecl, arglist);
7240 break;
7242 case BUILT_IN_EXP:
7243 case BUILT_IN_EXPF:
7244 case BUILT_IN_EXPL:
7245 return fold_builtin_exponent (exp, &dconste);
7246 case BUILT_IN_EXP2:
7247 case BUILT_IN_EXP2F:
7248 case BUILT_IN_EXP2L:
7249 return fold_builtin_exponent (exp, &dconst2);
7250 case BUILT_IN_EXP10:
7251 case BUILT_IN_EXP10F:
7252 case BUILT_IN_EXP10L:
7253 case BUILT_IN_POW10:
7254 case BUILT_IN_POW10F:
7255 case BUILT_IN_POW10L:
7256 return fold_builtin_exponent (exp, &dconst10);
7257 case BUILT_IN_LOG:
7258 case BUILT_IN_LOGF:
7259 case BUILT_IN_LOGL:
7260 return fold_builtin_logarithm (exp, &dconste);
7261 break;
7262 case BUILT_IN_LOG2:
7263 case BUILT_IN_LOG2F:
7264 case BUILT_IN_LOG2L:
7265 return fold_builtin_logarithm (exp, &dconst2);
7266 break;
7267 case BUILT_IN_LOG10:
7268 case BUILT_IN_LOG10F:
7269 case BUILT_IN_LOG10L:
7270 return fold_builtin_logarithm (exp, &dconst10);
7271 break;
7273 case BUILT_IN_TAN:
7274 case BUILT_IN_TANF:
7275 case BUILT_IN_TANL:
7276 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7278 enum built_in_function fcode;
7279 tree arg = TREE_VALUE (arglist);
7281 /* Optimize tan(0.0) = 0.0. */
7282 if (real_zerop (arg))
7283 return arg;
7285 /* Optimize tan(atan(x)) = x. */
7286 fcode = builtin_mathfn_code (arg);
7287 if (flag_unsafe_math_optimizations
7288 && (fcode == BUILT_IN_ATAN
7289 || fcode == BUILT_IN_ATANF
7290 || fcode == BUILT_IN_ATANL))
7291 return TREE_VALUE (TREE_OPERAND (arg, 1));
7293 break;
7295 case BUILT_IN_ATAN:
7296 case BUILT_IN_ATANF:
7297 case BUILT_IN_ATANL:
7298 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7300 tree arg = TREE_VALUE (arglist);
7302 /* Optimize atan(0.0) = 0.0. */
7303 if (real_zerop (arg))
7304 return arg;
7306 /* Optimize atan(1.0) = pi/4. */
7307 if (real_onep (arg))
7309 REAL_VALUE_TYPE cst;
7311 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7312 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7313 return build_real (type, cst);
7316 break;
7318 case BUILT_IN_POW:
7319 case BUILT_IN_POWF:
7320 case BUILT_IN_POWL:
7321 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7323 enum built_in_function fcode;
7324 tree arg0 = TREE_VALUE (arglist);
7325 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7327 /* Optimize pow(1.0,y) = 1.0. */
7328 if (real_onep (arg0))
7329 return omit_one_operand (type, build_real (type, dconst1), arg1);
7331 if (TREE_CODE (arg1) == REAL_CST
7332 && ! TREE_CONSTANT_OVERFLOW (arg1))
7334 REAL_VALUE_TYPE c;
7335 c = TREE_REAL_CST (arg1);
7337 /* Optimize pow(x,0.0) = 1.0. */
7338 if (REAL_VALUES_EQUAL (c, dconst0))
7339 return omit_one_operand (type, build_real (type, dconst1),
7340 arg0);
7342 /* Optimize pow(x,1.0) = x. */
7343 if (REAL_VALUES_EQUAL (c, dconst1))
7344 return arg0;
7346 /* Optimize pow(x,-1.0) = 1.0/x. */
7347 if (REAL_VALUES_EQUAL (c, dconstm1))
7348 return fold (build (RDIV_EXPR, type,
7349 build_real (type, dconst1),
7350 arg0));
7352 /* Optimize pow(x,0.5) = sqrt(x). */
7353 if (flag_unsafe_math_optimizations
7354 && REAL_VALUES_EQUAL (c, dconsthalf))
7356 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7358 if (sqrtfn != NULL_TREE)
7360 tree arglist = build_tree_list (NULL_TREE, arg0);
7361 return build_function_call_expr (sqrtfn, arglist);
7365 /* Attempt to evaluate pow at compile-time. */
7366 if (TREE_CODE (arg0) == REAL_CST
7367 && ! TREE_CONSTANT_OVERFLOW (arg0))
7369 REAL_VALUE_TYPE cint;
7370 HOST_WIDE_INT n;
7372 n = real_to_integer (&c);
7373 real_from_integer (&cint, VOIDmode, n,
7374 n < 0 ? -1 : 0, 0);
7375 if (real_identical (&c, &cint))
7377 REAL_VALUE_TYPE x;
7378 bool inexact;
7380 x = TREE_REAL_CST (arg0);
7381 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7382 if (flag_unsafe_math_optimizations || !inexact)
7383 return build_real (type, x);
7388 /* Optimize pow(expN(x),y) = expN(x*y). */
7389 fcode = builtin_mathfn_code (arg0);
7390 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7392 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7393 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7394 arg = fold (build (MULT_EXPR, type, arg, arg1));
7395 arglist = build_tree_list (NULL_TREE, arg);
7396 return build_function_call_expr (expfn, arglist);
7399 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7400 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7402 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7403 tree narg1 = fold (build (MULT_EXPR, type, arg1,
7404 build_real (type, dconsthalf)));
7406 arglist = tree_cons (NULL_TREE, narg0,
7407 build_tree_list (NULL_TREE, narg1));
7408 return build_function_call_expr (fndecl, arglist);
7411 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7412 if (flag_unsafe_math_optimizations
7413 && (fcode == BUILT_IN_POW
7414 || fcode == BUILT_IN_POWF
7415 || fcode == BUILT_IN_POWL))
7417 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7418 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7419 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
7420 arglist = tree_cons (NULL_TREE, arg00,
7421 build_tree_list (NULL_TREE, narg1));
7422 return build_function_call_expr (fndecl, arglist);
7425 break;
7427 case BUILT_IN_INF:
7428 case BUILT_IN_INFF:
7429 case BUILT_IN_INFL:
7430 return fold_builtin_inf (type, true);
7432 case BUILT_IN_HUGE_VAL:
7433 case BUILT_IN_HUGE_VALF:
7434 case BUILT_IN_HUGE_VALL:
7435 return fold_builtin_inf (type, false);
7437 case BUILT_IN_NAN:
7438 case BUILT_IN_NANF:
7439 case BUILT_IN_NANL:
7440 return fold_builtin_nan (arglist, type, true);
7442 case BUILT_IN_NANS:
7443 case BUILT_IN_NANSF:
7444 case BUILT_IN_NANSL:
7445 return fold_builtin_nan (arglist, type, false);
7447 case BUILT_IN_FLOOR:
7448 case BUILT_IN_FLOORF:
7449 case BUILT_IN_FLOORL:
7450 return fold_builtin_floor (exp);
7452 case BUILT_IN_CEIL:
7453 case BUILT_IN_CEILF:
7454 case BUILT_IN_CEILL:
7455 return fold_builtin_ceil (exp);
7457 case BUILT_IN_TRUNC:
7458 case BUILT_IN_TRUNCF:
7459 case BUILT_IN_TRUNCL:
7460 return fold_builtin_trunc (exp);
7462 case BUILT_IN_ROUND:
7463 case BUILT_IN_ROUNDF:
7464 case BUILT_IN_ROUNDL:
7465 return fold_builtin_round (exp);
7467 case BUILT_IN_NEARBYINT:
7468 case BUILT_IN_NEARBYINTF:
7469 case BUILT_IN_NEARBYINTL:
7470 case BUILT_IN_RINT:
7471 case BUILT_IN_RINTF:
7472 case BUILT_IN_RINTL:
7473 return fold_trunc_transparent_mathfn (exp);
7475 case BUILT_IN_LROUND:
7476 case BUILT_IN_LROUNDF:
7477 case BUILT_IN_LROUNDL:
7478 case BUILT_IN_LLROUND:
7479 case BUILT_IN_LLROUNDF:
7480 case BUILT_IN_LLROUNDL:
7481 return fold_builtin_lround (exp);
7483 case BUILT_IN_LRINT:
7484 case BUILT_IN_LRINTF:
7485 case BUILT_IN_LRINTL:
7486 case BUILT_IN_LLRINT:
7487 case BUILT_IN_LLRINTF:
7488 case BUILT_IN_LLRINTL:
7489 return fold_fixed_mathfn (exp);
7491 case BUILT_IN_FFS:
7492 case BUILT_IN_FFSL:
7493 case BUILT_IN_FFSLL:
7494 case BUILT_IN_CLZ:
7495 case BUILT_IN_CLZL:
7496 case BUILT_IN_CLZLL:
7497 case BUILT_IN_CTZ:
7498 case BUILT_IN_CTZL:
7499 case BUILT_IN_CTZLL:
7500 case BUILT_IN_POPCOUNT:
7501 case BUILT_IN_POPCOUNTL:
7502 case BUILT_IN_POPCOUNTLL:
7503 case BUILT_IN_PARITY:
7504 case BUILT_IN_PARITYL:
7505 case BUILT_IN_PARITYLL:
7506 return fold_builtin_bitop (exp);
7508 case BUILT_IN_MEMCPY:
7509 return fold_builtin_memcpy (exp);
7511 case BUILT_IN_MEMPCPY:
7512 return fold_builtin_mempcpy (exp);
7514 case BUILT_IN_MEMMOVE:
7515 return fold_builtin_memmove (exp);
7517 case BUILT_IN_STRCPY:
7518 return fold_builtin_strcpy (exp);
7520 case BUILT_IN_STRNCPY:
7521 return fold_builtin_strncpy (exp);
7523 case BUILT_IN_MEMCMP:
7524 return fold_builtin_memcmp (exp);
7526 case BUILT_IN_STRCMP:
7527 return fold_builtin_strcmp (exp);
7529 case BUILT_IN_STRNCMP:
7530 return fold_builtin_strncmp (exp);
7532 case BUILT_IN_SIGNBIT:
7533 case BUILT_IN_SIGNBITF:
7534 case BUILT_IN_SIGNBITL:
7535 return fold_builtin_signbit (exp);
7537 case BUILT_IN_ISASCII:
7538 return fold_builtin_isascii (arglist);
7540 case BUILT_IN_TOASCII:
7541 return fold_builtin_toascii (arglist);
7543 case BUILT_IN_ISDIGIT:
7544 return fold_builtin_isdigit (arglist);
7546 default:
7547 break;
7550 return 0;
7553 /* Conveniently construct a function call expression. */
7555 tree
7556 build_function_call_expr (tree fn, tree arglist)
7558 tree call_expr;
7560 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7561 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7562 call_expr, arglist);
7563 return fold (call_expr);
7566 /* This function validates the types of a function call argument list
7567 represented as a tree chain of parameters against a specified list
7568 of tree_codes. If the last specifier is a 0, that represents an
7569 ellipses, otherwise the last specifier must be a VOID_TYPE. */
7571 static int
7572 validate_arglist (tree arglist, ...)
7574 enum tree_code code;
7575 int res = 0;
7576 va_list ap;
7578 va_start (ap, arglist);
7582 code = va_arg (ap, enum tree_code);
7583 switch (code)
7585 case 0:
7586 /* This signifies an ellipses, any further arguments are all ok. */
7587 res = 1;
7588 goto end;
7589 case VOID_TYPE:
7590 /* This signifies an endlink, if no arguments remain, return
7591 true, otherwise return false. */
7592 res = arglist == 0;
7593 goto end;
7594 default:
7595 /* If no parameters remain or the parameter's code does not
7596 match the specified code, return false. Otherwise continue
7597 checking any remaining arguments. */
7598 if (arglist == 0
7599 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7600 goto end;
7601 break;
7603 arglist = TREE_CHAIN (arglist);
7605 while (1);
7607 /* We need gotos here since we can only have one VA_CLOSE in a
7608 function. */
7609 end: ;
7610 va_end (ap);
7612 return res;
7615 /* Default target-specific builtin expander that does nothing. */
7618 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7619 rtx target ATTRIBUTE_UNUSED,
7620 rtx subtarget ATTRIBUTE_UNUSED,
7621 enum machine_mode mode ATTRIBUTE_UNUSED,
7622 int ignore ATTRIBUTE_UNUSED)
7624 return NULL_RTX;
7627 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
7629 void
7630 purge_builtin_constant_p (void)
7632 rtx insn, set, arg, new, note;
7634 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7635 if (INSN_P (insn)
7636 && (set = single_set (insn)) != NULL_RTX
7637 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
7638 || (GET_CODE (arg) == SUBREG
7639 && (GET_CODE (arg = SUBREG_REG (arg))
7640 == CONSTANT_P_RTX))))
7642 arg = XEXP (arg, 0);
7643 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
7644 validate_change (insn, &SET_SRC (set), new, 0);
7646 /* Remove the REG_EQUAL note from the insn. */
7647 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
7648 remove_note (insn, note);
7652 /* Returns true is EXP represents data that would potentially reside
7653 in a readonly section. */
7655 static bool
7656 readonly_data_expr (tree exp)
7658 STRIP_NOPS (exp);
7660 if (TREE_CODE (exp) == ADDR_EXPR)
7661 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7662 else
7663 return false;