gcc:
[official-gcc.git] / gcc / builtins.c
blob51e89766ef73619b083dd09db6c27e98d2b2c19b
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
51 /* Register mappings for target machines without register windows. */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
54 #endif
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
57 #endif
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
61 #endif
63 /* Define the names of the builtin function types and codes. */
64 const char *const built_in_class_names[4]
65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) STRINGX(X),
68 const char *const built_in_names[(int) END_BUILTINS] =
70 #include "builtins.def"
72 #undef DEF_BUILTIN
74 /* Setup an array of _DECL trees, make sure each element is
75 initialized to NULL_TREE. */
76 tree built_in_decls[(int) END_BUILTINS];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78 It may be NULL_TREE when this is invalid (for instance runtime is not
79 required to implement the function call in all cases. */
80 tree implicit_built_in_decls[(int) END_BUILTINS];
82 static int get_pointer_alignment PARAMS ((tree, unsigned int));
83 static tree c_strlen PARAMS ((tree));
84 static const char *c_getstr PARAMS ((tree));
85 static rtx c_readstr PARAMS ((const char *,
86 enum machine_mode));
87 static int target_char_cast PARAMS ((tree, char *));
88 static rtx get_memory_rtx PARAMS ((tree));
89 static int apply_args_size PARAMS ((void));
90 static int apply_result_size PARAMS ((void));
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector PARAMS ((int, rtx));
93 #endif
94 static rtx expand_builtin_setjmp PARAMS ((tree, rtx));
95 static void expand_builtin_prefetch PARAMS ((tree));
96 static rtx expand_builtin_apply_args PARAMS ((void));
97 static rtx expand_builtin_apply_args_1 PARAMS ((void));
98 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
99 static void expand_builtin_return PARAMS ((rtx));
100 static enum type_class type_to_class PARAMS ((tree));
101 static rtx expand_builtin_classify_type PARAMS ((tree));
102 static void expand_errno_check PARAMS ((tree, rtx));
103 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
104 static rtx expand_builtin_mathfn_2 PARAMS ((tree, rtx, rtx));
105 static rtx expand_builtin_constant_p PARAMS ((tree));
106 static rtx expand_builtin_args_info PARAMS ((tree));
107 static rtx expand_builtin_next_arg PARAMS ((tree));
108 static rtx expand_builtin_va_start PARAMS ((tree));
109 static rtx expand_builtin_va_end PARAMS ((tree));
110 static rtx expand_builtin_va_copy PARAMS ((tree));
111 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx,
112 enum machine_mode));
113 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
114 enum machine_mode));
115 static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
116 enum machine_mode));
117 static rtx builtin_memcpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
118 enum machine_mode));
119 static rtx expand_builtin_strcat PARAMS ((tree, rtx,
120 enum machine_mode));
121 static rtx expand_builtin_strncat PARAMS ((tree, rtx,
122 enum machine_mode));
123 static rtx expand_builtin_strspn PARAMS ((tree, rtx,
124 enum machine_mode));
125 static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
126 enum machine_mode));
127 static rtx expand_builtin_memcpy PARAMS ((tree, rtx,
128 enum machine_mode, int));
129 static rtx expand_builtin_strcpy PARAMS ((tree, rtx,
130 enum machine_mode));
131 static rtx expand_builtin_stpcpy PARAMS ((tree, rtx,
132 enum machine_mode));
133 static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
134 enum machine_mode));
135 static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
136 enum machine_mode));
137 static rtx builtin_memset_read_str PARAMS ((PTR, HOST_WIDE_INT,
138 enum machine_mode));
139 static rtx builtin_memset_gen_str PARAMS ((PTR, HOST_WIDE_INT,
140 enum machine_mode));
141 static rtx expand_builtin_memset PARAMS ((tree, rtx,
142 enum machine_mode));
143 static rtx expand_builtin_bzero PARAMS ((tree));
144 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
145 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
146 enum machine_mode));
147 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
148 enum machine_mode));
149 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
150 enum machine_mode));
151 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
152 enum machine_mode));
153 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
154 static rtx expand_builtin_unop PARAMS ((enum machine_mode,
155 tree, rtx, rtx, optab));
156 static rtx expand_builtin_frame_address PARAMS ((tree));
157 static rtx expand_builtin_fputs PARAMS ((tree, int, int));
158 static tree stabilize_va_list PARAMS ((tree, int));
159 static rtx expand_builtin_expect PARAMS ((tree, rtx));
160 static tree fold_builtin_constant_p PARAMS ((tree));
161 static tree fold_builtin_classify_type PARAMS ((tree));
162 static tree fold_builtin_inf PARAMS ((tree, int));
163 static tree fold_builtin_nan PARAMS ((tree, tree, int));
164 static int validate_arglist PARAMS ((tree, ...));
165 static tree fold_trunc_transparent_mathfn PARAMS ((tree));
167 /* Return the alignment in bits of EXP, a pointer valued expression.
168 But don't return more than MAX_ALIGN no matter what.
169 The alignment returned is, by default, the alignment of the thing that
170 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
172 Otherwise, look at the expression to see if we can do better, i.e., if the
173 expression is actually pointing at an object whose alignment is tighter. */
175 static int
176 get_pointer_alignment (exp, max_align)
177 tree exp;
178 unsigned int max_align;
180 unsigned int align, inner;
182 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
183 return 0;
185 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
186 align = MIN (align, max_align);
188 while (1)
190 switch (TREE_CODE (exp))
192 case NOP_EXPR:
193 case CONVERT_EXPR:
194 case NON_LVALUE_EXPR:
195 exp = TREE_OPERAND (exp, 0);
196 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
197 return align;
199 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
200 align = MIN (inner, max_align);
201 break;
203 case PLUS_EXPR:
204 /* If sum of pointer + int, restrict our maximum alignment to that
205 imposed by the integer. If not, we can't do any better than
206 ALIGN. */
207 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
208 return align;
210 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
211 & (max_align / BITS_PER_UNIT - 1))
212 != 0)
213 max_align >>= 1;
215 exp = TREE_OPERAND (exp, 0);
216 break;
218 case ADDR_EXPR:
219 /* See what we are pointing at and look at its alignment. */
220 exp = TREE_OPERAND (exp, 0);
221 if (TREE_CODE (exp) == FUNCTION_DECL)
222 align = FUNCTION_BOUNDARY;
223 else if (DECL_P (exp))
224 align = DECL_ALIGN (exp);
225 #ifdef CONSTANT_ALIGNMENT
226 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
227 align = CONSTANT_ALIGNMENT (exp, align);
228 #endif
229 return MIN (align, max_align);
231 default:
232 return align;
237 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
238 way, because it could contain a zero byte in the middle.
239 TREE_STRING_LENGTH is the size of the character array, not the string.
241 The value returned is of type `ssizetype'.
243 Unfortunately, string_constant can't access the values of const char
244 arrays with initializers, so neither can we do so here. */
246 static tree
247 c_strlen (src)
248 tree src;
250 tree offset_node;
251 HOST_WIDE_INT offset;
252 int max;
253 const char *ptr;
255 src = string_constant (src, &offset_node);
256 if (src == 0)
257 return 0;
259 max = TREE_STRING_LENGTH (src) - 1;
260 ptr = TREE_STRING_POINTER (src);
262 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
264 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
265 compute the offset to the following null if we don't know where to
266 start searching for it. */
267 int i;
269 for (i = 0; i < max; i++)
270 if (ptr[i] == 0)
271 return 0;
273 /* We don't know the starting offset, but we do know that the string
274 has no internal zero bytes. We can assume that the offset falls
275 within the bounds of the string; otherwise, the programmer deserves
276 what he gets. Subtract the offset from the length of the string,
277 and return that. This would perhaps not be valid if we were dealing
278 with named arrays in addition to literal string constants. */
280 return size_diffop (size_int (max), offset_node);
283 /* We have a known offset into the string. Start searching there for
284 a null character if we can represent it as a single HOST_WIDE_INT. */
285 if (offset_node == 0)
286 offset = 0;
287 else if (! host_integerp (offset_node, 0))
288 offset = -1;
289 else
290 offset = tree_low_cst (offset_node, 0);
292 /* If the offset is known to be out of bounds, warn, and call strlen at
293 runtime. */
294 if (offset < 0 || offset > max)
296 warning ("offset outside bounds of constant string");
297 return 0;
300 /* Use strlen to search for the first zero byte. Since any strings
301 constructed with build_string will have nulls appended, we win even
302 if we get handed something like (char[4])"abcd".
304 Since OFFSET is our starting index into the string, no further
305 calculation is needed. */
306 return ssize_int (strlen (ptr + offset));
309 /* Return a char pointer for a C string if it is a string constant
310 or sum of string constant and integer constant. */
312 static const char *
313 c_getstr (src)
314 tree src;
316 tree offset_node;
318 src = string_constant (src, &offset_node);
319 if (src == 0)
320 return 0;
322 if (offset_node == 0)
323 return TREE_STRING_POINTER (src);
324 else if (!host_integerp (offset_node, 1)
325 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
326 return 0;
328 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
331 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
332 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
334 static rtx
335 c_readstr (str, mode)
336 const char *str;
337 enum machine_mode mode;
339 HOST_WIDE_INT c[2];
340 HOST_WIDE_INT ch;
341 unsigned int i, j;
343 if (GET_MODE_CLASS (mode) != MODE_INT)
344 abort ();
345 c[0] = 0;
346 c[1] = 0;
347 ch = 1;
348 for (i = 0; i < GET_MODE_SIZE (mode); i++)
350 j = i;
351 if (WORDS_BIG_ENDIAN)
352 j = GET_MODE_SIZE (mode) - i - 1;
353 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
354 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
355 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
356 j *= BITS_PER_UNIT;
357 if (j > 2 * HOST_BITS_PER_WIDE_INT)
358 abort ();
359 if (ch)
360 ch = (unsigned char) str[i];
361 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
363 return immed_double_const (c[0], c[1], mode);
366 /* Cast a target constant CST to target CHAR and if that value fits into
367 host char type, return zero and put that value into variable pointed by
368 P. */
370 static int
371 target_char_cast (cst, p)
372 tree cst;
373 char *p;
375 unsigned HOST_WIDE_INT val, hostval;
377 if (!host_integerp (cst, 1)
378 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
379 return 1;
381 val = tree_low_cst (cst, 1);
382 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
383 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
385 hostval = val;
386 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
387 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
389 if (val != hostval)
390 return 1;
392 *p = hostval;
393 return 0;
396 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
397 times to get the address of either a higher stack frame, or a return
398 address located within it (depending on FNDECL_CODE). */
401 expand_builtin_return_addr (fndecl_code, count, tem)
402 enum built_in_function fndecl_code;
403 int count;
404 rtx tem;
406 int i;
408 /* Some machines need special handling before we can access
409 arbitrary frames. For example, on the sparc, we must first flush
410 all register windows to the stack. */
411 #ifdef SETUP_FRAME_ADDRESSES
412 if (count > 0)
413 SETUP_FRAME_ADDRESSES ();
414 #endif
416 /* On the sparc, the return address is not in the frame, it is in a
417 register. There is no way to access it off of the current frame
418 pointer, but it can be accessed off the previous frame pointer by
419 reading the value from the register window save area. */
420 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
421 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
422 count--;
423 #endif
425 /* Scan back COUNT frames to the specified frame. */
426 for (i = 0; i < count; i++)
428 /* Assume the dynamic chain pointer is in the word that the
429 frame address points to, unless otherwise specified. */
430 #ifdef DYNAMIC_CHAIN_ADDRESS
431 tem = DYNAMIC_CHAIN_ADDRESS (tem);
432 #endif
433 tem = memory_address (Pmode, tem);
434 tem = gen_rtx_MEM (Pmode, tem);
435 set_mem_alias_set (tem, get_frame_alias_set ());
436 tem = copy_to_reg (tem);
439 /* For __builtin_frame_address, return what we've got. */
440 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
441 return tem;
443 /* For __builtin_return_address, Get the return address from that
444 frame. */
445 #ifdef RETURN_ADDR_RTX
446 tem = RETURN_ADDR_RTX (count, tem);
447 #else
448 tem = memory_address (Pmode,
449 plus_constant (tem, GET_MODE_SIZE (Pmode)));
450 tem = gen_rtx_MEM (Pmode, tem);
451 set_mem_alias_set (tem, get_frame_alias_set ());
452 #endif
453 return tem;
456 /* Alias set used for setjmp buffer. */
457 static HOST_WIDE_INT setjmp_alias_set = -1;
459 /* Construct the leading half of a __builtin_setjmp call. Control will
460 return to RECEIVER_LABEL. This is used directly by sjlj exception
461 handling code. */
463 void
464 expand_builtin_setjmp_setup (buf_addr, receiver_label)
465 rtx buf_addr;
466 rtx receiver_label;
468 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
469 rtx stack_save;
470 rtx mem;
472 if (setjmp_alias_set == -1)
473 setjmp_alias_set = new_alias_set ();
475 #ifdef POINTERS_EXTEND_UNSIGNED
476 if (GET_MODE (buf_addr) != Pmode)
477 buf_addr = convert_memory_address (Pmode, buf_addr);
478 #endif
480 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
482 emit_queue ();
484 /* We store the frame pointer and the address of receiver_label in
485 the buffer and use the rest of it for the stack save area, which
486 is machine-dependent. */
488 #ifndef BUILTIN_SETJMP_FRAME_VALUE
489 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
490 #endif
492 mem = gen_rtx_MEM (Pmode, buf_addr);
493 set_mem_alias_set (mem, setjmp_alias_set);
494 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
496 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
497 set_mem_alias_set (mem, setjmp_alias_set);
499 emit_move_insn (validize_mem (mem),
500 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
502 stack_save = gen_rtx_MEM (sa_mode,
503 plus_constant (buf_addr,
504 2 * GET_MODE_SIZE (Pmode)));
505 set_mem_alias_set (stack_save, setjmp_alias_set);
506 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
508 /* If there is further processing to do, do it. */
509 #ifdef HAVE_builtin_setjmp_setup
510 if (HAVE_builtin_setjmp_setup)
511 emit_insn (gen_builtin_setjmp_setup (buf_addr));
512 #endif
514 /* Tell optimize_save_area_alloca that extra work is going to
515 need to go on during alloca. */
516 current_function_calls_setjmp = 1;
518 /* Set this so all the registers get saved in our frame; we need to be
519 able to copy the saved values for any registers from frames we unwind. */
520 current_function_has_nonlocal_label = 1;
523 /* Construct the trailing part of a __builtin_setjmp call.
524 This is used directly by sjlj exception handling code. */
526 void
527 expand_builtin_setjmp_receiver (receiver_label)
528 rtx receiver_label ATTRIBUTE_UNUSED;
530 /* Clobber the FP when we get here, so we have to make sure it's
531 marked as used by this function. */
532 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
534 /* Mark the static chain as clobbered here so life information
535 doesn't get messed up for it. */
536 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
538 /* Now put in the code to restore the frame pointer, and argument
539 pointer, if needed. The code below is from expand_end_bindings
540 in stmt.c; see detailed documentation there. */
541 #ifdef HAVE_nonlocal_goto
542 if (! HAVE_nonlocal_goto)
543 #endif
544 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
546 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
547 if (fixed_regs[ARG_POINTER_REGNUM])
549 #ifdef ELIMINABLE_REGS
550 size_t i;
551 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
553 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
554 if (elim_regs[i].from == ARG_POINTER_REGNUM
555 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
556 break;
558 if (i == ARRAY_SIZE (elim_regs))
559 #endif
561 /* Now restore our arg pointer from the address at which it
562 was saved in our stack frame. */
563 emit_move_insn (virtual_incoming_args_rtx,
564 copy_to_reg (get_arg_pointer_save_area (cfun)));
567 #endif
569 #ifdef HAVE_builtin_setjmp_receiver
570 if (HAVE_builtin_setjmp_receiver)
571 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
572 else
573 #endif
574 #ifdef HAVE_nonlocal_goto_receiver
575 if (HAVE_nonlocal_goto_receiver)
576 emit_insn (gen_nonlocal_goto_receiver ());
577 else
578 #endif
579 { /* Nothing */ }
581 /* @@@ This is a kludge. Not all machine descriptions define a blockage
582 insn, but we must not allow the code we just generated to be reordered
583 by scheduling. Specifically, the update of the frame pointer must
584 happen immediately, not later. So emit an ASM_INPUT to act as blockage
585 insn. */
586 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
589 /* __builtin_setjmp is passed a pointer to an array of five words (not
590 all will be used on all machines). It operates similarly to the C
591 library function of the same name, but is more efficient. Much of
592 the code below (and for longjmp) is copied from the handling of
593 non-local gotos.
595 NOTE: This is intended for use by GNAT and the exception handling
596 scheme in the compiler and will only work in the method used by
597 them. */
599 static rtx
600 expand_builtin_setjmp (arglist, target)
601 tree arglist;
602 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. */
621 emit_move_insn (target, const0_rtx);
622 emit_jump_insn (gen_jump (cont_lab));
623 emit_barrier ();
624 emit_label (next_lab);
626 expand_builtin_setjmp_receiver (next_lab);
628 /* Set TARGET to one. */
629 emit_move_insn (target, const1_rtx);
630 emit_label (cont_lab);
632 /* Tell flow about the strange goings on. Putting `next_lab' on
633 `nonlocal_goto_handler_labels' to indicates that function
634 calls may traverse the arc back to this label. */
636 current_function_has_nonlocal_label = 1;
637 nonlocal_goto_handler_labels
638 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
640 return target;
643 /* __builtin_longjmp is passed a pointer to an array of five words (not
644 all will be used on all machines). It operates similarly to the C
645 library function of the same name, but is more efficient. Much of
646 the code below is copied from the handling of non-local gotos.
648 NOTE: This is intended for use by GNAT and the exception handling
649 scheme in the compiler and will only work in the method used by
650 them. */
652 void
653 expand_builtin_longjmp (buf_addr, value)
654 rtx buf_addr, 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 #ifdef POINTERS_EXTEND_UNSIGNED
663 if (GET_MODE (buf_addr) != Pmode)
664 buf_addr = convert_memory_address (Pmode, buf_addr);
665 #endif
667 buf_addr = force_reg (Pmode, buf_addr);
669 /* We used to store value in static_chain_rtx, but that fails if pointers
670 are smaller than integers. We instead require that the user must pass
671 a second argument of 1, because that is what builtin_setjmp will
672 return. This also makes EH slightly more efficient, since we are no
673 longer copying around a value that we don't care about. */
674 if (value != const1_rtx)
675 abort ();
677 current_function_calls_longjmp = 1;
679 last = get_last_insn ();
680 #ifdef HAVE_builtin_longjmp
681 if (HAVE_builtin_longjmp)
682 emit_insn (gen_builtin_longjmp (buf_addr));
683 else
684 #endif
686 fp = gen_rtx_MEM (Pmode, buf_addr);
687 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
688 GET_MODE_SIZE (Pmode)));
690 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
691 2 * GET_MODE_SIZE (Pmode)));
692 set_mem_alias_set (fp, setjmp_alias_set);
693 set_mem_alias_set (lab, setjmp_alias_set);
694 set_mem_alias_set (stack, setjmp_alias_set);
696 /* Pick up FP, label, and SP from the block and jump. This code is
697 from expand_goto in stmt.c; see there for detailed comments. */
698 #if HAVE_nonlocal_goto
699 if (HAVE_nonlocal_goto)
700 /* We have to pass a value to the nonlocal_goto pattern that will
701 get copied into the static_chain pointer, but it does not matter
702 what that value is, because builtin_setjmp does not use it. */
703 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
704 else
705 #endif
707 lab = copy_to_reg (lab);
709 emit_move_insn (hard_frame_pointer_rtx, fp);
710 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
712 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
713 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
714 emit_indirect_jump (lab);
718 /* Search backwards and mark the jump insn as a non-local goto.
719 Note that this precludes the use of __builtin_longjmp to a
720 __builtin_setjmp target in the same function. However, we've
721 already cautioned the user that these functions are for
722 internal exception handling use only. */
723 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
725 if (insn == last)
726 abort ();
727 if (GET_CODE (insn) == JUMP_INSN)
729 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
730 REG_NOTES (insn));
731 break;
733 else if (GET_CODE (insn) == CALL_INSN)
734 break;
738 /* Expand a call to __builtin_prefetch. For a target that does not support
739 data prefetch, evaluate the memory address argument in case it has side
740 effects. */
742 static void
743 expand_builtin_prefetch (arglist)
744 tree arglist;
746 tree arg0, arg1, arg2;
747 rtx op0, op1, op2;
749 if (!validate_arglist (arglist, POINTER_TYPE, 0))
750 return;
752 arg0 = TREE_VALUE (arglist);
753 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
754 zero (read) and argument 2 (locality) defaults to 3 (high degree of
755 locality). */
756 if (TREE_CHAIN (arglist))
758 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
759 if (TREE_CHAIN (TREE_CHAIN (arglist)))
760 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
761 else
762 arg2 = build_int_2 (3, 0);
764 else
766 arg1 = integer_zero_node;
767 arg2 = build_int_2 (3, 0);
770 /* Argument 0 is an address. */
771 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
773 /* Argument 1 (read/write flag) must be a compile-time constant int. */
774 if (TREE_CODE (arg1) != INTEGER_CST)
776 error ("second arg to `__builtin_prefetch' must be a constant");
777 arg1 = integer_zero_node;
779 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
780 /* Argument 1 must be either zero or one. */
781 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
783 warning ("invalid second arg to __builtin_prefetch; using zero");
784 op1 = const0_rtx;
787 /* Argument 2 (locality) must be a compile-time constant int. */
788 if (TREE_CODE (arg2) != INTEGER_CST)
790 error ("third arg to `__builtin_prefetch' must be a constant");
791 arg2 = integer_zero_node;
793 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
794 /* Argument 2 must be 0, 1, 2, or 3. */
795 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
797 warning ("invalid third arg to __builtin_prefetch; using zero");
798 op2 = const0_rtx;
801 #ifdef HAVE_prefetch
802 if (HAVE_prefetch)
804 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
805 (op0,
806 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
807 || (GET_MODE(op0) != Pmode))
809 #ifdef POINTERS_EXTEND_UNSIGNED
810 if (GET_MODE(op0) != Pmode)
811 op0 = convert_memory_address (Pmode, op0);
812 #endif
813 op0 = force_reg (Pmode, op0);
815 emit_insn (gen_prefetch (op0, op1, op2));
817 else
818 #endif
819 op0 = protect_from_queue (op0, 0);
820 /* Don't do anything with direct references to volatile memory, but
821 generate code to handle other side effects. */
822 if (GET_CODE (op0) != MEM && side_effects_p (op0))
823 emit_insn (op0);
826 /* Get a MEM rtx for expression EXP which is the address of an operand
827 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
829 static rtx
830 get_memory_rtx (exp)
831 tree exp;
833 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
834 rtx mem;
836 #ifdef POINTERS_EXTEND_UNSIGNED
837 if (GET_MODE (addr) != Pmode)
838 addr = convert_memory_address (Pmode, addr);
839 #endif
841 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
843 /* Get an expression we can use to find the attributes to assign to MEM.
844 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
845 we can. First remove any nops. */
846 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
847 || TREE_CODE (exp) == NON_LVALUE_EXPR)
848 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
849 exp = TREE_OPERAND (exp, 0);
851 if (TREE_CODE (exp) == ADDR_EXPR)
853 exp = TREE_OPERAND (exp, 0);
854 set_mem_attributes (mem, exp, 0);
856 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
858 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
859 /* memcpy, memset and other builtin stringops can alias with anything. */
860 set_mem_alias_set (mem, 0);
863 return mem;
866 /* Built-in functions to perform an untyped call and return. */
868 /* For each register that may be used for calling a function, this
869 gives a mode used to copy the register's value. VOIDmode indicates
870 the register is not used for calling a function. If the machine
871 has register windows, this gives only the outbound registers.
872 INCOMING_REGNO gives the corresponding inbound register. */
873 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
875 /* For each register that may be used for returning values, this gives
876 a mode used to copy the register's value. VOIDmode indicates the
877 register is not used for returning values. If the machine has
878 register windows, this gives only the outbound registers.
879 INCOMING_REGNO gives the corresponding inbound register. */
880 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
882 /* For each register that may be used for calling a function, this
883 gives the offset of that register into the block returned by
884 __builtin_apply_args. 0 indicates that the register is not
885 used for calling a function. */
886 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
888 /* Return the offset of register REGNO into the block returned by
889 __builtin_apply_args. This is not declared static, since it is
890 needed in objc-act.c. */
893 apply_args_register_offset (regno)
894 int regno;
896 apply_args_size ();
898 /* Arguments are always put in outgoing registers (in the argument
899 block) if such make sense. */
900 #ifdef OUTGOING_REGNO
901 regno = OUTGOING_REGNO (regno);
902 #endif
903 return apply_args_reg_offset[regno];
906 /* Return the size required for the block returned by __builtin_apply_args,
907 and initialize apply_args_mode. */
909 static int
910 apply_args_size ()
912 static int size = -1;
913 int align;
914 unsigned int regno;
915 enum machine_mode mode;
917 /* The values computed by this function never change. */
918 if (size < 0)
920 /* The first value is the incoming arg-pointer. */
921 size = GET_MODE_SIZE (Pmode);
923 /* The second value is the structure value address unless this is
924 passed as an "invisible" first argument. */
925 if (struct_value_rtx)
926 size += GET_MODE_SIZE (Pmode);
928 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
929 if (FUNCTION_ARG_REGNO_P (regno))
931 /* Search for the proper mode for copying this register's
932 value. I'm not sure this is right, but it works so far. */
933 enum machine_mode best_mode = VOIDmode;
935 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
936 mode != VOIDmode;
937 mode = GET_MODE_WIDER_MODE (mode))
938 if (HARD_REGNO_MODE_OK (regno, mode)
939 && HARD_REGNO_NREGS (regno, mode) == 1)
940 best_mode = mode;
942 if (best_mode == VOIDmode)
943 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
944 mode != VOIDmode;
945 mode = GET_MODE_WIDER_MODE (mode))
946 if (HARD_REGNO_MODE_OK (regno, mode)
947 && have_insn_for (SET, mode))
948 best_mode = mode;
950 if (best_mode == VOIDmode)
951 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
952 mode != VOIDmode;
953 mode = GET_MODE_WIDER_MODE (mode))
954 if (HARD_REGNO_MODE_OK (regno, mode)
955 && have_insn_for (SET, mode))
956 best_mode = mode;
958 if (best_mode == VOIDmode)
959 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
960 mode != VOIDmode;
961 mode = GET_MODE_WIDER_MODE (mode))
962 if (HARD_REGNO_MODE_OK (regno, mode)
963 && have_insn_for (SET, mode))
964 best_mode = mode;
966 mode = best_mode;
967 if (mode == VOIDmode)
968 abort ();
970 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
971 if (size % align != 0)
972 size = CEIL (size, align) * align;
973 apply_args_reg_offset[regno] = size;
974 size += GET_MODE_SIZE (mode);
975 apply_args_mode[regno] = mode;
977 else
979 apply_args_mode[regno] = VOIDmode;
980 apply_args_reg_offset[regno] = 0;
983 return size;
986 /* Return the size required for the block returned by __builtin_apply,
987 and initialize apply_result_mode. */
989 static int
990 apply_result_size ()
992 static int size = -1;
993 int align, regno;
994 enum machine_mode mode;
996 /* The values computed by this function never change. */
997 if (size < 0)
999 size = 0;
1001 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1002 if (FUNCTION_VALUE_REGNO_P (regno))
1004 /* Search for the proper mode for copying this register's
1005 value. I'm not sure this is right, but it works so far. */
1006 enum machine_mode best_mode = VOIDmode;
1008 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1009 mode != TImode;
1010 mode = GET_MODE_WIDER_MODE (mode))
1011 if (HARD_REGNO_MODE_OK (regno, mode))
1012 best_mode = mode;
1014 if (best_mode == VOIDmode)
1015 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1016 mode != VOIDmode;
1017 mode = GET_MODE_WIDER_MODE (mode))
1018 if (HARD_REGNO_MODE_OK (regno, mode)
1019 && have_insn_for (SET, mode))
1020 best_mode = mode;
1022 if (best_mode == VOIDmode)
1023 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1024 mode != VOIDmode;
1025 mode = GET_MODE_WIDER_MODE (mode))
1026 if (HARD_REGNO_MODE_OK (regno, mode)
1027 && have_insn_for (SET, mode))
1028 best_mode = mode;
1030 if (best_mode == VOIDmode)
1031 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1032 mode != VOIDmode;
1033 mode = GET_MODE_WIDER_MODE (mode))
1034 if (HARD_REGNO_MODE_OK (regno, mode)
1035 && have_insn_for (SET, mode))
1036 best_mode = mode;
1038 mode = best_mode;
1039 if (mode == VOIDmode)
1040 abort ();
1042 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1043 if (size % align != 0)
1044 size = CEIL (size, align) * align;
1045 size += GET_MODE_SIZE (mode);
1046 apply_result_mode[regno] = mode;
1048 else
1049 apply_result_mode[regno] = VOIDmode;
1051 /* Allow targets that use untyped_call and untyped_return to override
1052 the size so that machine-specific information can be stored here. */
1053 #ifdef APPLY_RESULT_SIZE
1054 size = APPLY_RESULT_SIZE;
1055 #endif
1057 return size;
1060 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1061 /* Create a vector describing the result block RESULT. If SAVEP is true,
1062 the result block is used to save the values; otherwise it is used to
1063 restore the values. */
1065 static rtx
1066 result_vector (savep, result)
1067 int savep;
1068 rtx result;
1070 int regno, size, align, nelts;
1071 enum machine_mode mode;
1072 rtx reg, mem;
1073 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1075 size = nelts = 0;
1076 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1077 if ((mode = apply_result_mode[regno]) != VOIDmode)
1079 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1080 if (size % align != 0)
1081 size = CEIL (size, align) * align;
1082 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1083 mem = adjust_address (result, mode, size);
1084 savevec[nelts++] = (savep
1085 ? gen_rtx_SET (VOIDmode, mem, reg)
1086 : gen_rtx_SET (VOIDmode, reg, mem));
1087 size += GET_MODE_SIZE (mode);
1089 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1091 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1093 /* Save the state required to perform an untyped call with the same
1094 arguments as were passed to the current function. */
1096 static rtx
1097 expand_builtin_apply_args_1 ()
1099 rtx registers;
1100 int size, align, regno;
1101 enum machine_mode mode;
1103 /* Create a block where the arg-pointer, structure value address,
1104 and argument registers can be saved. */
1105 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1107 /* Walk past the arg-pointer and structure value address. */
1108 size = GET_MODE_SIZE (Pmode);
1109 if (struct_value_rtx)
1110 size += GET_MODE_SIZE (Pmode);
1112 /* Save each register used in calling a function to the block. */
1113 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1114 if ((mode = apply_args_mode[regno]) != VOIDmode)
1116 rtx tem;
1118 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1119 if (size % align != 0)
1120 size = CEIL (size, align) * align;
1122 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1124 emit_move_insn (adjust_address (registers, mode, size), tem);
1125 size += GET_MODE_SIZE (mode);
1128 /* Save the arg pointer to the block. */
1129 emit_move_insn (adjust_address (registers, Pmode, 0),
1130 copy_to_reg (virtual_incoming_args_rtx));
1131 size = GET_MODE_SIZE (Pmode);
1133 /* Save the structure value address unless this is passed as an
1134 "invisible" first argument. */
1135 if (struct_value_incoming_rtx)
1137 emit_move_insn (adjust_address (registers, Pmode, size),
1138 copy_to_reg (struct_value_incoming_rtx));
1139 size += GET_MODE_SIZE (Pmode);
1142 /* Return the address of the block. */
1143 return copy_addr_to_reg (XEXP (registers, 0));
1146 /* __builtin_apply_args returns block of memory allocated on
1147 the stack into which is stored the arg pointer, structure
1148 value address, static chain, and all the registers that might
1149 possibly be used in performing a function call. The code is
1150 moved to the start of the function so the incoming values are
1151 saved. */
1153 static rtx
1154 expand_builtin_apply_args ()
1156 /* Don't do __builtin_apply_args more than once in a function.
1157 Save the result of the first call and reuse it. */
1158 if (apply_args_value != 0)
1159 return apply_args_value;
1161 /* When this function is called, it means that registers must be
1162 saved on entry to this function. So we migrate the
1163 call to the first insn of this function. */
1164 rtx temp;
1165 rtx seq;
1167 start_sequence ();
1168 temp = expand_builtin_apply_args_1 ();
1169 seq = get_insns ();
1170 end_sequence ();
1172 apply_args_value = temp;
1174 /* Put the insns after the NOTE that starts the function.
1175 If this is inside a start_sequence, make the outer-level insn
1176 chain current, so the code is placed at the start of the
1177 function. */
1178 push_topmost_sequence ();
1179 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1180 pop_topmost_sequence ();
1181 return temp;
1185 /* Perform an untyped call and save the state required to perform an
1186 untyped return of whatever value was returned by the given function. */
1188 static rtx
1189 expand_builtin_apply (function, arguments, argsize)
1190 rtx function, arguments, argsize;
1192 int size, align, regno;
1193 enum machine_mode mode;
1194 rtx incoming_args, result, reg, dest, src, call_insn;
1195 rtx old_stack_level = 0;
1196 rtx call_fusage = 0;
1198 #ifdef POINTERS_EXTEND_UNSIGNED
1199 if (GET_MODE (arguments) != Pmode)
1200 arguments = convert_memory_address (Pmode, arguments);
1201 #endif
1203 /* Create a block where the return registers can be saved. */
1204 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1206 /* Fetch the arg pointer from the ARGUMENTS block. */
1207 incoming_args = gen_reg_rtx (Pmode);
1208 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1209 #ifndef STACK_GROWS_DOWNWARD
1210 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1211 incoming_args, 0, OPTAB_LIB_WIDEN);
1212 #endif
1214 /* Perform postincrements before actually calling the function. */
1215 emit_queue ();
1217 /* Push a new argument block and copy the arguments. Do not allow
1218 the (potential) memcpy call below to interfere with our stack
1219 manipulations. */
1220 do_pending_stack_adjust ();
1221 NO_DEFER_POP;
1223 /* Save the stack with nonlocal if available */
1224 #ifdef HAVE_save_stack_nonlocal
1225 if (HAVE_save_stack_nonlocal)
1226 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1227 else
1228 #endif
1229 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1231 /* Push a block of memory onto the stack to store the memory arguments.
1232 Save the address in a register, and copy the memory arguments. ??? I
1233 haven't figured out how the calling convention macros effect this,
1234 but it's likely that the source and/or destination addresses in
1235 the block copy will need updating in machine specific ways. */
1236 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1237 dest = gen_rtx_MEM (BLKmode, dest);
1238 set_mem_align (dest, PARM_BOUNDARY);
1239 src = gen_rtx_MEM (BLKmode, incoming_args);
1240 set_mem_align (src, PARM_BOUNDARY);
1241 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1243 /* Refer to the argument block. */
1244 apply_args_size ();
1245 arguments = gen_rtx_MEM (BLKmode, arguments);
1246 set_mem_align (arguments, PARM_BOUNDARY);
1248 /* Walk past the arg-pointer and structure value address. */
1249 size = GET_MODE_SIZE (Pmode);
1250 if (struct_value_rtx)
1251 size += GET_MODE_SIZE (Pmode);
1253 /* Restore each of the registers previously saved. Make USE insns
1254 for each of these registers for use in making the call. */
1255 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1256 if ((mode = apply_args_mode[regno]) != VOIDmode)
1258 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1259 if (size % align != 0)
1260 size = CEIL (size, align) * align;
1261 reg = gen_rtx_REG (mode, regno);
1262 emit_move_insn (reg, adjust_address (arguments, mode, size));
1263 use_reg (&call_fusage, reg);
1264 size += GET_MODE_SIZE (mode);
1267 /* Restore the structure value address unless this is passed as an
1268 "invisible" first argument. */
1269 size = GET_MODE_SIZE (Pmode);
1270 if (struct_value_rtx)
1272 rtx value = gen_reg_rtx (Pmode);
1273 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1274 emit_move_insn (struct_value_rtx, value);
1275 if (GET_CODE (struct_value_rtx) == REG)
1276 use_reg (&call_fusage, struct_value_rtx);
1277 size += GET_MODE_SIZE (Pmode);
1280 /* All arguments and registers used for the call are set up by now! */
1281 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1283 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1284 and we don't want to load it into a register as an optimization,
1285 because prepare_call_address already did it if it should be done. */
1286 if (GET_CODE (function) != SYMBOL_REF)
1287 function = memory_address (FUNCTION_MODE, function);
1289 /* Generate the actual call instruction and save the return value. */
1290 #ifdef HAVE_untyped_call
1291 if (HAVE_untyped_call)
1292 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1293 result, result_vector (1, result)));
1294 else
1295 #endif
1296 #ifdef HAVE_call_value
1297 if (HAVE_call_value)
1299 rtx valreg = 0;
1301 /* Locate the unique return register. It is not possible to
1302 express a call that sets more than one return register using
1303 call_value; use untyped_call for that. In fact, untyped_call
1304 only needs to save the return registers in the given block. */
1305 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1306 if ((mode = apply_result_mode[regno]) != VOIDmode)
1308 if (valreg)
1309 abort (); /* HAVE_untyped_call required. */
1310 valreg = gen_rtx_REG (mode, regno);
1313 emit_call_insn (GEN_CALL_VALUE (valreg,
1314 gen_rtx_MEM (FUNCTION_MODE, function),
1315 const0_rtx, NULL_RTX, const0_rtx));
1317 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1319 else
1320 #endif
1321 abort ();
1323 /* Find the CALL insn we just emitted. */
1324 for (call_insn = get_last_insn ();
1325 call_insn && GET_CODE (call_insn) != CALL_INSN;
1326 call_insn = PREV_INSN (call_insn))
1329 if (! call_insn)
1330 abort ();
1332 /* Put the register usage information on the CALL. If there is already
1333 some usage information, put ours at the end. */
1334 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1336 rtx link;
1338 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1339 link = XEXP (link, 1))
1342 XEXP (link, 1) = call_fusage;
1344 else
1345 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1347 /* Restore the stack. */
1348 #ifdef HAVE_save_stack_nonlocal
1349 if (HAVE_save_stack_nonlocal)
1350 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1351 else
1352 #endif
1353 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1355 OK_DEFER_POP;
1357 /* Return the address of the result block. */
1358 return copy_addr_to_reg (XEXP (result, 0));
1361 /* Perform an untyped return. */
1363 static void
1364 expand_builtin_return (result)
1365 rtx result;
1367 int size, align, regno;
1368 enum machine_mode mode;
1369 rtx reg;
1370 rtx call_fusage = 0;
1372 #ifdef POINTERS_EXTEND_UNSIGNED
1373 if (GET_MODE (result) != Pmode)
1374 result = convert_memory_address (Pmode, result);
1375 #endif
1377 apply_result_size ();
1378 result = gen_rtx_MEM (BLKmode, result);
1380 #ifdef HAVE_untyped_return
1381 if (HAVE_untyped_return)
1383 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1384 emit_barrier ();
1385 return;
1387 #endif
1389 /* Restore the return value and note that each value is used. */
1390 size = 0;
1391 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1392 if ((mode = apply_result_mode[regno]) != VOIDmode)
1394 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1395 if (size % align != 0)
1396 size = CEIL (size, align) * align;
1397 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1398 emit_move_insn (reg, adjust_address (result, mode, size));
1400 push_to_sequence (call_fusage);
1401 emit_insn (gen_rtx_USE (VOIDmode, reg));
1402 call_fusage = get_insns ();
1403 end_sequence ();
1404 size += GET_MODE_SIZE (mode);
1407 /* Put the USE insns before the return. */
1408 emit_insn (call_fusage);
1410 /* Return whatever values was restored by jumping directly to the end
1411 of the function. */
1412 expand_null_return ();
1415 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1417 static enum type_class
1418 type_to_class (type)
1419 tree type;
1421 switch (TREE_CODE (type))
1423 case VOID_TYPE: return void_type_class;
1424 case INTEGER_TYPE: return integer_type_class;
1425 case CHAR_TYPE: return char_type_class;
1426 case ENUMERAL_TYPE: return enumeral_type_class;
1427 case BOOLEAN_TYPE: return boolean_type_class;
1428 case POINTER_TYPE: return pointer_type_class;
1429 case REFERENCE_TYPE: return reference_type_class;
1430 case OFFSET_TYPE: return offset_type_class;
1431 case REAL_TYPE: return real_type_class;
1432 case COMPLEX_TYPE: return complex_type_class;
1433 case FUNCTION_TYPE: return function_type_class;
1434 case METHOD_TYPE: return method_type_class;
1435 case RECORD_TYPE: return record_type_class;
1436 case UNION_TYPE:
1437 case QUAL_UNION_TYPE: return union_type_class;
1438 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1439 ? string_type_class : array_type_class);
1440 case SET_TYPE: return set_type_class;
1441 case FILE_TYPE: return file_type_class;
1442 case LANG_TYPE: return lang_type_class;
1443 default: return no_type_class;
1447 /* Expand a call to __builtin_classify_type with arguments found in
1448 ARGLIST. */
1450 static rtx
1451 expand_builtin_classify_type (arglist)
1452 tree arglist;
1454 if (arglist != 0)
1455 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1456 return GEN_INT (no_type_class);
1459 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1461 static rtx
1462 expand_builtin_constant_p (exp)
1463 tree exp;
1465 tree arglist = TREE_OPERAND (exp, 1);
1466 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1467 rtx tmp;
1469 if (arglist == 0)
1470 return const0_rtx;
1471 arglist = TREE_VALUE (arglist);
1473 /* We have taken care of the easy cases during constant folding. This
1474 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1475 get a chance to see if it can deduce whether ARGLIST is constant. */
1477 current_function_calls_constant_p = 1;
1479 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1480 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1481 return tmp;
1484 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1485 if available. */
1486 tree
1487 mathfn_built_in (type, fn)
1488 tree type;
1489 enum built_in_function fn;
1491 enum built_in_function fcode = NOT_BUILT_IN;
1492 if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
1493 switch (fn)
1495 case BUILT_IN_SQRT:
1496 case BUILT_IN_SQRTF:
1497 case BUILT_IN_SQRTL:
1498 fcode = BUILT_IN_SQRT;
1499 break;
1500 case BUILT_IN_SIN:
1501 case BUILT_IN_SINF:
1502 case BUILT_IN_SINL:
1503 fcode = BUILT_IN_SIN;
1504 break;
1505 case BUILT_IN_COS:
1506 case BUILT_IN_COSF:
1507 case BUILT_IN_COSL:
1508 fcode = BUILT_IN_COS;
1509 break;
1510 case BUILT_IN_EXP:
1511 case BUILT_IN_EXPF:
1512 case BUILT_IN_EXPL:
1513 fcode = BUILT_IN_EXP;
1514 break;
1515 case BUILT_IN_LOG:
1516 case BUILT_IN_LOGF:
1517 case BUILT_IN_LOGL:
1518 fcode = BUILT_IN_LOG;
1519 break;
1520 case BUILT_IN_FLOOR:
1521 case BUILT_IN_FLOORF:
1522 case BUILT_IN_FLOORL:
1523 fcode = BUILT_IN_FLOOR;
1524 break;
1525 case BUILT_IN_CEIL:
1526 case BUILT_IN_CEILF:
1527 case BUILT_IN_CEILL:
1528 fcode = BUILT_IN_CEIL;
1529 break;
1530 case BUILT_IN_TRUNC:
1531 case BUILT_IN_TRUNCF:
1532 case BUILT_IN_TRUNCL:
1533 fcode = BUILT_IN_TRUNC;
1534 break;
1535 case BUILT_IN_ROUND:
1536 case BUILT_IN_ROUNDF:
1537 case BUILT_IN_ROUNDL:
1538 fcode = BUILT_IN_ROUND;
1539 break;
1540 case BUILT_IN_NEARBYINT:
1541 case BUILT_IN_NEARBYINTF:
1542 case BUILT_IN_NEARBYINTL:
1543 fcode = BUILT_IN_NEARBYINT;
1544 break;
1545 default:
1546 abort ();
1548 else if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
1549 switch (fn)
1551 case BUILT_IN_SQRT:
1552 case BUILT_IN_SQRTF:
1553 case BUILT_IN_SQRTL:
1554 fcode = BUILT_IN_SQRTF;
1555 break;
1556 case BUILT_IN_SIN:
1557 case BUILT_IN_SINF:
1558 case BUILT_IN_SINL:
1559 fcode = BUILT_IN_SINF;
1560 break;
1561 case BUILT_IN_COS:
1562 case BUILT_IN_COSF:
1563 case BUILT_IN_COSL:
1564 fcode = BUILT_IN_COSF;
1565 break;
1566 case BUILT_IN_EXP:
1567 case BUILT_IN_EXPF:
1568 case BUILT_IN_EXPL:
1569 fcode = BUILT_IN_EXPF;
1570 break;
1571 case BUILT_IN_LOG:
1572 case BUILT_IN_LOGF:
1573 case BUILT_IN_LOGL:
1574 fcode = BUILT_IN_LOGF;
1575 break;
1576 case BUILT_IN_FLOOR:
1577 case BUILT_IN_FLOORF:
1578 case BUILT_IN_FLOORL:
1579 fcode = BUILT_IN_FLOORF;
1580 break;
1581 case BUILT_IN_CEIL:
1582 case BUILT_IN_CEILF:
1583 case BUILT_IN_CEILL:
1584 fcode = BUILT_IN_CEILF;
1585 break;
1586 case BUILT_IN_TRUNC:
1587 case BUILT_IN_TRUNCF:
1588 case BUILT_IN_TRUNCL:
1589 fcode = BUILT_IN_TRUNCF;
1590 break;
1591 case BUILT_IN_ROUND:
1592 case BUILT_IN_ROUNDF:
1593 case BUILT_IN_ROUNDL:
1594 fcode = BUILT_IN_ROUNDF;
1595 break;
1596 case BUILT_IN_NEARBYINT:
1597 case BUILT_IN_NEARBYINTF:
1598 case BUILT_IN_NEARBYINTL:
1599 fcode = BUILT_IN_NEARBYINTF;
1600 break;
1601 default:
1602 abort ();
1604 else if (TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
1605 switch (fn)
1607 case BUILT_IN_SQRT:
1608 case BUILT_IN_SQRTF:
1609 case BUILT_IN_SQRTL:
1610 fcode = BUILT_IN_SQRTL;
1611 break;
1612 case BUILT_IN_SIN:
1613 case BUILT_IN_SINF:
1614 case BUILT_IN_SINL:
1615 fcode = BUILT_IN_SINL;
1616 break;
1617 case BUILT_IN_COS:
1618 case BUILT_IN_COSF:
1619 case BUILT_IN_COSL:
1620 fcode = BUILT_IN_COSL;
1621 break;
1622 case BUILT_IN_EXP:
1623 case BUILT_IN_EXPF:
1624 case BUILT_IN_EXPL:
1625 fcode = BUILT_IN_EXPL;
1626 break;
1627 case BUILT_IN_LOG:
1628 case BUILT_IN_LOGF:
1629 case BUILT_IN_LOGL:
1630 fcode = BUILT_IN_LOGL;
1631 break;
1632 case BUILT_IN_FLOOR:
1633 case BUILT_IN_FLOORF:
1634 case BUILT_IN_FLOORL:
1635 fcode = BUILT_IN_FLOORL;
1636 break;
1637 case BUILT_IN_CEIL:
1638 case BUILT_IN_CEILF:
1639 case BUILT_IN_CEILL:
1640 fcode = BUILT_IN_CEILL;
1641 break;
1642 case BUILT_IN_TRUNC:
1643 case BUILT_IN_TRUNCF:
1644 case BUILT_IN_TRUNCL:
1645 fcode = BUILT_IN_TRUNCL;
1646 break;
1647 case BUILT_IN_ROUND:
1648 case BUILT_IN_ROUNDF:
1649 case BUILT_IN_ROUNDL:
1650 fcode = BUILT_IN_ROUNDL;
1651 break;
1652 case BUILT_IN_NEARBYINT:
1653 case BUILT_IN_NEARBYINTF:
1654 case BUILT_IN_NEARBYINTL:
1655 fcode = BUILT_IN_NEARBYINTL;
1656 break;
1657 default:
1658 abort ();
1660 return implicit_built_in_decls[fcode];
1663 /* If errno must be maintained, expand the RTL to check if the result,
1664 TARGET, of a built-in function call, EXP, is NaN, and if so set
1665 errno to EDOM. */
1667 static void
1668 expand_errno_check (exp, target)
1669 tree exp;
1670 rtx target;
1672 rtx lab;
1674 if (flag_errno_math && HONOR_NANS (GET_MODE (target)))
1676 lab = gen_label_rtx ();
1678 /* Test the result; if it is NaN, set errno=EDOM because
1679 the argument was not in the domain. */
1680 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1681 0, lab);
1683 #ifdef TARGET_EDOM
1685 #ifdef GEN_ERRNO_RTX
1686 rtx errno_rtx = GEN_ERRNO_RTX;
1687 #else
1688 rtx errno_rtx
1689 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1690 #endif
1692 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1694 #else
1695 /* We can't set errno=EDOM directly; let the library call do it.
1696 Pop the arguments right away in case the call gets deleted. */
1697 NO_DEFER_POP;
1698 expand_call (exp, target, 0);
1699 OK_DEFER_POP;
1700 #endif
1702 emit_label (lab);
1707 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1708 Return 0 if a normal call should be emitted rather than expanding the
1709 function in-line. EXP is the expression that is a call to the builtin
1710 function; if convenient, the result should be placed in TARGET.
1711 SUBTARGET may be used as the target for computing one of EXP's operands. */
1713 static rtx
1714 expand_builtin_mathfn (exp, target, subtarget)
1715 tree exp;
1716 rtx target, subtarget;
1718 optab builtin_optab;
1719 rtx op0, insns;
1720 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1721 tree arglist = TREE_OPERAND (exp, 1);
1722 enum machine_mode argmode;
1723 bool errno_set = true;
1725 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1726 return 0;
1728 /* Stabilize and compute the argument. */
1729 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1730 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1732 exp = copy_node (exp);
1733 TREE_OPERAND (exp, 1) = arglist;
1734 /* Wrap the computation of the argument in a SAVE_EXPR. That
1735 way, if we need to expand the argument again (as in the
1736 flag_errno_math case below where we cannot directly set
1737 errno), we will not perform side-effects more than once.
1738 Note that here we're mutating the original EXP as well as the
1739 copy; that's the right thing to do in case the original EXP
1740 is expanded later. */
1741 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1742 arglist = copy_node (arglist);
1744 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1746 /* Make a suitable register to place result in. */
1747 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1749 emit_queue ();
1750 start_sequence ();
1752 switch (DECL_FUNCTION_CODE (fndecl))
1754 case BUILT_IN_SIN:
1755 case BUILT_IN_SINF:
1756 case BUILT_IN_SINL:
1757 builtin_optab = sin_optab; break;
1758 case BUILT_IN_COS:
1759 case BUILT_IN_COSF:
1760 case BUILT_IN_COSL:
1761 builtin_optab = cos_optab; break;
1762 case BUILT_IN_SQRT:
1763 case BUILT_IN_SQRTF:
1764 case BUILT_IN_SQRTL:
1765 builtin_optab = sqrt_optab; break;
1766 case BUILT_IN_EXP:
1767 case BUILT_IN_EXPF:
1768 case BUILT_IN_EXPL:
1769 builtin_optab = exp_optab; break;
1770 case BUILT_IN_LOG:
1771 case BUILT_IN_LOGF:
1772 case BUILT_IN_LOGL:
1773 builtin_optab = log_optab; break;
1774 case BUILT_IN_FLOOR:
1775 case BUILT_IN_FLOORF:
1776 case BUILT_IN_FLOORL:
1777 errno_set = false ; builtin_optab = floor_optab; break;
1778 case BUILT_IN_CEIL:
1779 case BUILT_IN_CEILF:
1780 case BUILT_IN_CEILL:
1781 errno_set = false ; builtin_optab = ceil_optab; break;
1782 case BUILT_IN_TRUNC:
1783 case BUILT_IN_TRUNCF:
1784 case BUILT_IN_TRUNCL:
1785 errno_set = false ; builtin_optab = trunc_optab; break;
1786 case BUILT_IN_ROUND:
1787 case BUILT_IN_ROUNDF:
1788 case BUILT_IN_ROUNDL:
1789 errno_set = false ; builtin_optab = round_optab; break;
1790 case BUILT_IN_NEARBYINT:
1791 case BUILT_IN_NEARBYINTF:
1792 case BUILT_IN_NEARBYINTL:
1793 errno_set = false ; builtin_optab = nearbyint_optab; break;
1794 default:
1795 abort ();
1798 /* Compute into TARGET.
1799 Set TARGET to wherever the result comes back. */
1800 argmode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
1801 target = expand_unop (argmode, builtin_optab, op0, target, 0);
1803 /* If we were unable to expand via the builtin, stop the
1804 sequence (without outputting the insns) and return 0, causing
1805 a call to the library function. */
1806 if (target == 0)
1808 end_sequence ();
1809 return 0;
1812 if (errno_set)
1813 expand_errno_check (exp, target);
1815 /* Output the entire sequence. */
1816 insns = get_insns ();
1817 end_sequence ();
1818 emit_insn (insns);
1820 return target;
1823 /* Expand a call to the builtin binary math functions (pow and atan2).
1824 Return 0 if a normal call should be emitted rather than expanding the
1825 function in-line. EXP is the expression that is a call to the builtin
1826 function; if convenient, the result should be placed in TARGET.
1827 SUBTARGET may be used as the target for computing one of EXP's
1828 operands. */
1830 static rtx
1831 expand_builtin_mathfn_2 (exp, target, subtarget)
1832 tree exp;
1833 rtx target, subtarget;
1835 optab builtin_optab;
1836 rtx op0, op1, insns;
1837 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1838 tree arglist = TREE_OPERAND (exp, 1);
1839 tree arg0, arg1;
1840 enum machine_mode argmode;
1841 bool errno_set = true;
1842 bool stable = true;
1844 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1845 return 0;
1847 arg0 = TREE_VALUE (arglist);
1848 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1850 /* Stabilize the arguments. */
1851 if (TREE_CODE (arg0) != VAR_DECL && TREE_CODE (arg0) != PARM_DECL)
1853 arg0 = save_expr (arg0);
1854 TREE_VALUE (arglist) = arg0;
1855 stable = false;
1857 if (TREE_CODE (arg1) != VAR_DECL && TREE_CODE (arg1) != PARM_DECL)
1859 arg1 = save_expr (arg1);
1860 TREE_VALUE (TREE_CHAIN (arglist)) = arg1;
1861 stable = false;
1864 if (! stable)
1866 exp = copy_node (exp);
1867 arglist = tree_cons (NULL_TREE, arg0,
1868 build_tree_list (NULL_TREE, arg1));
1869 TREE_OPERAND (exp, 1) = arglist;
1872 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1873 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1875 /* Make a suitable register to place result in. */
1876 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1878 emit_queue ();
1879 start_sequence ();
1881 switch (DECL_FUNCTION_CODE (fndecl))
1883 case BUILT_IN_POW:
1884 case BUILT_IN_POWF:
1885 case BUILT_IN_POWL:
1886 builtin_optab = pow_optab; break;
1887 case BUILT_IN_ATAN2:
1888 case BUILT_IN_ATAN2F:
1889 case BUILT_IN_ATAN2L:
1890 builtin_optab = atan2_optab; break;
1891 default:
1892 abort ();
1895 /* Compute into TARGET.
1896 Set TARGET to wherever the result comes back. */
1897 argmode = TYPE_MODE (TREE_TYPE (arg0));
1898 target = expand_binop (argmode, builtin_optab, op0, op1,
1899 target, 0, OPTAB_DIRECT);
1901 /* If we were unable to expand via the builtin, stop the
1902 sequence (without outputting the insns) and return 0, causing
1903 a call to the library function. */
1904 if (target == 0)
1906 end_sequence ();
1907 return 0;
1910 if (errno_set)
1911 expand_errno_check (exp, target);
1913 /* Output the entire sequence. */
1914 insns = get_insns ();
1915 end_sequence ();
1916 emit_insn (insns);
1918 return target;
1921 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1922 if we failed the caller should emit a normal call, otherwise
1923 try to get the result in TARGET, if convenient. */
1925 static rtx
1926 expand_builtin_strlen (exp, target)
1927 tree exp;
1928 rtx target;
1930 tree arglist = TREE_OPERAND (exp, 1);
1931 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1933 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1934 return 0;
1935 else
1937 rtx pat;
1938 tree src = TREE_VALUE (arglist);
1940 int align
1941 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1943 rtx result, src_reg, char_rtx, before_strlen;
1944 enum machine_mode insn_mode = value_mode, char_mode;
1945 enum insn_code icode = CODE_FOR_nothing;
1947 /* If SRC is not a pointer type, don't do this operation inline. */
1948 if (align == 0)
1949 return 0;
1951 /* Bail out if we can't compute strlen in the right mode. */
1952 while (insn_mode != VOIDmode)
1954 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1955 if (icode != CODE_FOR_nothing)
1956 break;
1958 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1960 if (insn_mode == VOIDmode)
1961 return 0;
1963 /* Make a place to write the result of the instruction. */
1964 result = target;
1965 if (! (result != 0
1966 && GET_CODE (result) == REG
1967 && GET_MODE (result) == insn_mode
1968 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1969 result = gen_reg_rtx (insn_mode);
1971 /* Make a place to hold the source address. We will not expand
1972 the actual source until we are sure that the expansion will
1973 not fail -- there are trees that cannot be expanded twice. */
1974 src_reg = gen_reg_rtx (Pmode);
1976 /* Mark the beginning of the strlen sequence so we can emit the
1977 source operand later. */
1978 before_strlen = get_last_insn ();
1980 char_rtx = const0_rtx;
1981 char_mode = insn_data[(int) icode].operand[2].mode;
1982 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1983 char_mode))
1984 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1986 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1987 char_rtx, GEN_INT (align));
1988 if (! pat)
1989 return 0;
1990 emit_insn (pat);
1992 /* Now that we are assured of success, expand the source. */
1993 start_sequence ();
1994 pat = memory_address (BLKmode,
1995 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1996 if (pat != src_reg)
1997 emit_move_insn (src_reg, pat);
1998 pat = get_insns ();
1999 end_sequence ();
2001 if (before_strlen)
2002 emit_insn_after (pat, before_strlen);
2003 else
2004 emit_insn_before (pat, get_insns ());
2006 /* Return the value in the proper mode for this function. */
2007 if (GET_MODE (result) == value_mode)
2008 target = result;
2009 else if (target != 0)
2010 convert_move (target, result, 0);
2011 else
2012 target = convert_to_mode (value_mode, result, 0);
2014 return target;
2018 /* Expand a call to the strstr builtin. Return 0 if we failed the
2019 caller should emit a normal call, otherwise try to get the result
2020 in TARGET, if convenient (and in mode MODE if that's convenient). */
2022 static rtx
2023 expand_builtin_strstr (arglist, target, mode)
2024 tree arglist;
2025 rtx target;
2026 enum machine_mode mode;
2028 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2029 return 0;
2030 else
2032 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2033 tree fn;
2034 const char *p1, *p2;
2036 p2 = c_getstr (s2);
2037 if (p2 == NULL)
2038 return 0;
2040 p1 = c_getstr (s1);
2041 if (p1 != NULL)
2043 const char *r = strstr (p1, p2);
2045 if (r == NULL)
2046 return const0_rtx;
2048 /* Return an offset into the constant string argument. */
2049 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2050 s1, ssize_int (r - p1))),
2051 target, mode, EXPAND_NORMAL);
2054 if (p2[0] == '\0')
2055 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2057 if (p2[1] != '\0')
2058 return 0;
2060 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2061 if (!fn)
2062 return 0;
2064 /* New argument list transforming strstr(s1, s2) to
2065 strchr(s1, s2[0]). */
2066 arglist =
2067 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2068 arglist = tree_cons (NULL_TREE, s1, arglist);
2069 return expand_expr (build_function_call_expr (fn, arglist),
2070 target, mode, EXPAND_NORMAL);
2074 /* Expand a call to the strchr builtin. Return 0 if we failed the
2075 caller should emit a normal call, otherwise try to get the result
2076 in TARGET, if convenient (and in mode MODE if that's convenient). */
2078 static rtx
2079 expand_builtin_strchr (arglist, target, mode)
2080 tree arglist;
2081 rtx target;
2082 enum machine_mode mode;
2084 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2085 return 0;
2086 else
2088 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2089 const char *p1;
2091 if (TREE_CODE (s2) != INTEGER_CST)
2092 return 0;
2094 p1 = c_getstr (s1);
2095 if (p1 != NULL)
2097 char c;
2098 const char *r;
2100 if (target_char_cast (s2, &c))
2101 return 0;
2103 r = strchr (p1, c);
2105 if (r == NULL)
2106 return const0_rtx;
2108 /* Return an offset into the constant string argument. */
2109 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2110 s1, ssize_int (r - p1))),
2111 target, mode, EXPAND_NORMAL);
2114 /* FIXME: Should use here strchrM optab so that ports can optimize
2115 this. */
2116 return 0;
2120 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2121 caller should emit a normal call, otherwise try to get the result
2122 in TARGET, if convenient (and in mode MODE if that's convenient). */
2124 static rtx
2125 expand_builtin_strrchr (arglist, target, mode)
2126 tree arglist;
2127 rtx target;
2128 enum machine_mode mode;
2130 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2131 return 0;
2132 else
2134 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2135 tree fn;
2136 const char *p1;
2138 if (TREE_CODE (s2) != INTEGER_CST)
2139 return 0;
2141 p1 = c_getstr (s1);
2142 if (p1 != NULL)
2144 char c;
2145 const char *r;
2147 if (target_char_cast (s2, &c))
2148 return 0;
2150 r = strrchr (p1, c);
2152 if (r == NULL)
2153 return const0_rtx;
2155 /* Return an offset into the constant string argument. */
2156 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2157 s1, ssize_int (r - p1))),
2158 target, mode, EXPAND_NORMAL);
2161 if (! integer_zerop (s2))
2162 return 0;
2164 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2165 if (!fn)
2166 return 0;
2168 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2169 return expand_expr (build_function_call_expr (fn, arglist),
2170 target, mode, EXPAND_NORMAL);
2174 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2175 caller should emit a normal call, otherwise try to get the result
2176 in TARGET, if convenient (and in mode MODE if that's convenient). */
2178 static rtx
2179 expand_builtin_strpbrk (arglist, target, mode)
2180 tree arglist;
2181 rtx target;
2182 enum machine_mode mode;
2184 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2185 return 0;
2186 else
2188 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2189 tree fn;
2190 const char *p1, *p2;
2192 p2 = c_getstr (s2);
2193 if (p2 == NULL)
2194 return 0;
2196 p1 = c_getstr (s1);
2197 if (p1 != NULL)
2199 const char *r = strpbrk (p1, p2);
2201 if (r == NULL)
2202 return const0_rtx;
2204 /* Return an offset into the constant string argument. */
2205 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2206 s1, ssize_int (r - p1))),
2207 target, mode, EXPAND_NORMAL);
2210 if (p2[0] == '\0')
2212 /* strpbrk(x, "") == NULL.
2213 Evaluate and ignore the arguments in case they had
2214 side-effects. */
2215 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2216 return const0_rtx;
2219 if (p2[1] != '\0')
2220 return 0; /* Really call strpbrk. */
2222 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2223 if (!fn)
2224 return 0;
2226 /* New argument list transforming strpbrk(s1, s2) to
2227 strchr(s1, s2[0]). */
2228 arglist =
2229 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2230 arglist = tree_cons (NULL_TREE, s1, arglist);
2231 return expand_expr (build_function_call_expr (fn, arglist),
2232 target, mode, EXPAND_NORMAL);
2236 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2237 bytes from constant string DATA + OFFSET and return it as target
2238 constant. */
2240 static rtx
2241 builtin_memcpy_read_str (data, offset, mode)
2242 PTR data;
2243 HOST_WIDE_INT offset;
2244 enum machine_mode mode;
2246 const char *str = (const char *) data;
2248 if (offset < 0
2249 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2250 > strlen (str) + 1))
2251 abort (); /* Attempt to read past the end of constant string. */
2253 return c_readstr (str + offset, mode);
2256 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2257 Return 0 if we failed, the caller should emit a normal call,
2258 otherwise try to get the result in TARGET, if convenient (and in
2259 mode MODE if that's convenient). If ENDP is 0 return the
2260 destination pointer, if ENDP is 1 return the end pointer ala
2261 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2262 stpcpy. */
2263 static rtx
2264 expand_builtin_memcpy (arglist, target, mode, endp)
2265 tree arglist;
2266 rtx target;
2267 enum machine_mode mode;
2268 int endp;
2270 if (!validate_arglist (arglist,
2271 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2272 return 0;
2273 else
2275 tree dest = TREE_VALUE (arglist);
2276 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2277 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2278 const char *src_str;
2280 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2281 unsigned int dest_align
2282 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2283 rtx dest_mem, src_mem, dest_addr, len_rtx;
2285 /* If DEST is not a pointer type, call the normal function. */
2286 if (dest_align == 0)
2287 return 0;
2289 /* If the LEN parameter is zero, return DEST. */
2290 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2292 /* Evaluate and ignore SRC in case it has side-effects. */
2293 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2294 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2297 /* If either SRC is not a pointer type, don't do this
2298 operation in-line. */
2299 if (src_align == 0)
2300 return 0;
2302 dest_mem = get_memory_rtx (dest);
2303 set_mem_align (dest_mem, dest_align);
2304 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2305 src_str = c_getstr (src);
2307 /* If SRC is a string constant and block move would be done
2308 by pieces, we can avoid loading the string from memory
2309 and only stored the computed constants. */
2310 if (src_str
2311 && GET_CODE (len_rtx) == CONST_INT
2312 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2313 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2314 (PTR) src_str, dest_align))
2316 store_by_pieces (dest_mem, INTVAL (len_rtx),
2317 builtin_memcpy_read_str,
2318 (PTR) src_str, dest_align);
2319 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2320 #ifdef POINTERS_EXTEND_UNSIGNED
2321 if (GET_MODE (dest_mem) != ptr_mode)
2322 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2323 #endif
2324 if (endp)
2326 rtx result = gen_rtx_PLUS (GET_MODE(dest_mem), dest_mem, len_rtx);
2327 if (endp == 2)
2328 result = simplify_gen_binary (MINUS, GET_MODE(result), result, const1_rtx);
2329 return result;
2331 else
2332 return dest_mem;
2335 src_mem = get_memory_rtx (src);
2336 set_mem_align (src_mem, src_align);
2338 /* Copy word part most expediently. */
2339 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2340 BLOCK_OP_NORMAL);
2342 if (dest_addr == 0)
2344 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2345 #ifdef POINTERS_EXTEND_UNSIGNED
2346 if (GET_MODE (dest_addr) != ptr_mode)
2347 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2348 #endif
2351 if (endp)
2353 rtx result = gen_rtx_PLUS (GET_MODE (dest_addr), dest_addr, len_rtx);
2354 if (endp == 2)
2355 result = simplify_gen_binary (MINUS, GET_MODE(result), result, const1_rtx);
2356 return result;
2358 else
2359 return dest_addr;
2363 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2364 if we failed the caller should emit a normal call, otherwise try to get
2365 the result in TARGET, if convenient (and in mode MODE if that's
2366 convenient). */
2368 static rtx
2369 expand_builtin_strcpy (exp, target, mode)
2370 tree exp;
2371 rtx target;
2372 enum machine_mode mode;
2374 tree arglist = TREE_OPERAND (exp, 1);
2375 tree fn, len;
2377 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2378 return 0;
2380 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2381 if (!fn)
2382 return 0;
2384 len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2385 if (len == 0)
2386 return 0;
2388 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2389 chainon (arglist, build_tree_list (NULL_TREE, len));
2390 return expand_expr (build_function_call_expr (fn, arglist),
2391 target, mode, EXPAND_NORMAL);
2394 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2395 Return 0 if we failed the caller should emit a normal call,
2396 otherwise try to get the result in TARGET, if convenient (and in
2397 mode MODE if that's convenient). */
2399 static rtx
2400 expand_builtin_stpcpy (arglist, target, mode)
2401 tree arglist;
2402 rtx target;
2403 enum machine_mode mode;
2405 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2406 return 0;
2407 else
2409 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2410 if (len == 0)
2411 return 0;
2413 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2414 chainon (arglist, build_tree_list (NULL_TREE, len));
2415 return expand_builtin_memcpy (arglist, target, mode, /*endp=*/2);
2419 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2420 bytes from constant string DATA + OFFSET and return it as target
2421 constant. */
2423 static rtx
2424 builtin_strncpy_read_str (data, offset, mode)
2425 PTR data;
2426 HOST_WIDE_INT offset;
2427 enum machine_mode mode;
2429 const char *str = (const char *) data;
2431 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2432 return const0_rtx;
2434 return c_readstr (str + offset, mode);
2437 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2438 if we failed the caller should emit a normal call. */
2440 static rtx
2441 expand_builtin_strncpy (arglist, target, mode)
2442 tree arglist;
2443 rtx target;
2444 enum machine_mode mode;
2446 if (!validate_arglist (arglist,
2447 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2448 return 0;
2449 else
2451 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2452 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2453 tree fn;
2455 /* We must be passed a constant len parameter. */
2456 if (TREE_CODE (len) != INTEGER_CST)
2457 return 0;
2459 /* If the len parameter is zero, return the dst parameter. */
2460 if (integer_zerop (len))
2462 /* Evaluate and ignore the src argument in case it has
2463 side-effects. */
2464 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2465 VOIDmode, EXPAND_NORMAL);
2466 /* Return the dst parameter. */
2467 return expand_expr (TREE_VALUE (arglist), target, mode,
2468 EXPAND_NORMAL);
2471 /* Now, we must be passed a constant src ptr parameter. */
2472 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2473 return 0;
2475 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2477 /* We're required to pad with trailing zeros if the requested
2478 len is greater than strlen(s2)+1. In that case try to
2479 use store_by_pieces, if it fails, punt. */
2480 if (tree_int_cst_lt (slen, len))
2482 tree dest = TREE_VALUE (arglist);
2483 unsigned int dest_align
2484 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2485 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2486 rtx dest_mem;
2488 if (!p || dest_align == 0 || !host_integerp (len, 1)
2489 || !can_store_by_pieces (tree_low_cst (len, 1),
2490 builtin_strncpy_read_str,
2491 (PTR) p, dest_align))
2492 return 0;
2494 dest_mem = get_memory_rtx (dest);
2495 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2496 builtin_strncpy_read_str,
2497 (PTR) p, dest_align);
2498 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2499 #ifdef POINTERS_EXTEND_UNSIGNED
2500 if (GET_MODE (dest_mem) != ptr_mode)
2501 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2502 #endif
2503 return dest_mem;
2506 /* OK transform into builtin memcpy. */
2507 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2508 if (!fn)
2509 return 0;
2510 return expand_expr (build_function_call_expr (fn, arglist),
2511 target, mode, EXPAND_NORMAL);
2515 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2516 bytes from constant string DATA + OFFSET and return it as target
2517 constant. */
2519 static rtx
2520 builtin_memset_read_str (data, offset, mode)
2521 PTR data;
2522 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2523 enum machine_mode mode;
2525 const char *c = (const char *) data;
2526 char *p = alloca (GET_MODE_SIZE (mode));
2528 memset (p, *c, GET_MODE_SIZE (mode));
2530 return c_readstr (p, mode);
2533 /* Callback routine for store_by_pieces. Return the RTL of a register
2534 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2535 char value given in the RTL register data. For example, if mode is
2536 4 bytes wide, return the RTL for 0x01010101*data. */
2538 static rtx
2539 builtin_memset_gen_str (data, offset, mode)
2540 PTR data;
2541 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2542 enum machine_mode mode;
2544 rtx target, coeff;
2545 size_t size;
2546 char *p;
2548 size = GET_MODE_SIZE (mode);
2549 if (size == 1)
2550 return (rtx) data;
2552 p = alloca (size);
2553 memset (p, 1, size);
2554 coeff = c_readstr (p, mode);
2556 target = convert_to_mode (mode, (rtx) data, 1);
2557 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2558 return force_reg (mode, target);
2561 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2562 if we failed the caller should emit a normal call, otherwise try to get
2563 the result in TARGET, if convenient (and in mode MODE if that's
2564 convenient). */
2566 static rtx
2567 expand_builtin_memset (exp, target, mode)
2568 tree exp;
2569 rtx target;
2570 enum machine_mode mode;
2572 tree arglist = TREE_OPERAND (exp, 1);
2574 if (!validate_arglist (arglist,
2575 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2576 return 0;
2577 else
2579 tree dest = TREE_VALUE (arglist);
2580 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2581 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2582 char c;
2584 unsigned int dest_align
2585 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2586 rtx dest_mem, dest_addr, len_rtx;
2588 /* If DEST is not a pointer type, don't do this
2589 operation in-line. */
2590 if (dest_align == 0)
2591 return 0;
2593 /* If the LEN parameter is zero, return DEST. */
2594 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2596 /* Evaluate and ignore VAL in case it has side-effects. */
2597 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2598 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2601 if (TREE_CODE (val) != INTEGER_CST)
2603 rtx val_rtx;
2605 if (!host_integerp (len, 1))
2606 return 0;
2608 if (optimize_size && tree_low_cst (len, 1) > 1)
2609 return 0;
2611 /* Assume that we can memset by pieces if we can store the
2612 * the coefficients by pieces (in the required modes).
2613 * We can't pass builtin_memset_gen_str as that emits RTL. */
2614 c = 1;
2615 if (!can_store_by_pieces (tree_low_cst (len, 1),
2616 builtin_memset_read_str,
2617 (PTR) &c, dest_align))
2618 return 0;
2620 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
2621 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
2622 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
2623 val_rtx);
2624 dest_mem = get_memory_rtx (dest);
2625 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2626 builtin_memset_gen_str,
2627 (PTR) val_rtx, dest_align);
2628 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2629 #ifdef POINTERS_EXTEND_UNSIGNED
2630 if (GET_MODE (dest_mem) != ptr_mode)
2631 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2632 #endif
2633 return dest_mem;
2636 if (target_char_cast (val, &c))
2637 return 0;
2639 if (c)
2641 if (!host_integerp (len, 1))
2642 return 0;
2643 if (!can_store_by_pieces (tree_low_cst (len, 1),
2644 builtin_memset_read_str, (PTR) &c,
2645 dest_align))
2646 return 0;
2648 dest_mem = get_memory_rtx (dest);
2649 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2650 builtin_memset_read_str,
2651 (PTR) &c, dest_align);
2652 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2653 #ifdef POINTERS_EXTEND_UNSIGNED
2654 if (GET_MODE (dest_mem) != ptr_mode)
2655 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2656 #endif
2657 return dest_mem;
2660 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2662 dest_mem = get_memory_rtx (dest);
2663 set_mem_align (dest_mem, dest_align);
2664 dest_addr = clear_storage (dest_mem, len_rtx);
2666 if (dest_addr == 0)
2668 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2669 #ifdef POINTERS_EXTEND_UNSIGNED
2670 if (GET_MODE (dest_addr) != ptr_mode)
2671 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2672 #endif
2675 return dest_addr;
2679 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2680 if we failed the caller should emit a normal call. */
2682 static rtx
2683 expand_builtin_bzero (exp)
2684 tree exp;
2686 tree arglist = TREE_OPERAND (exp, 1);
2687 tree dest, size, newarglist;
2688 rtx result;
2690 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2691 return NULL_RTX;
2693 dest = TREE_VALUE (arglist);
2694 size = TREE_VALUE (TREE_CHAIN (arglist));
2696 /* New argument list transforming bzero(ptr x, int y) to
2697 memset(ptr x, int 0, size_t y). This is done this way
2698 so that if it isn't expanded inline, we fallback to
2699 calling bzero instead of memset. */
2701 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2702 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2703 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2705 TREE_OPERAND (exp, 1) = newarglist;
2706 result = expand_builtin_memset (exp, const0_rtx, VOIDmode);
2708 /* Always restore the original arguments. */
2709 TREE_OPERAND (exp, 1) = arglist;
2711 return result;
2714 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2715 ARGLIST is the argument list for this call. Return 0 if we failed and the
2716 caller should emit a normal call, otherwise try to get the result in
2717 TARGET, if convenient (and in mode MODE, if that's convenient). */
2719 static rtx
2720 expand_builtin_memcmp (exp, arglist, target, mode)
2721 tree exp ATTRIBUTE_UNUSED;
2722 tree arglist;
2723 rtx target;
2724 enum machine_mode mode;
2726 tree arg1, arg2, len;
2727 const char *p1, *p2;
2729 if (!validate_arglist (arglist,
2730 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2731 return 0;
2733 arg1 = TREE_VALUE (arglist);
2734 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2735 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2737 /* If the len parameter is zero, return zero. */
2738 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2740 /* Evaluate and ignore arg1 and arg2 in case they have
2741 side-effects. */
2742 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2743 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2744 return const0_rtx;
2747 p1 = c_getstr (arg1);
2748 p2 = c_getstr (arg2);
2750 /* If all arguments are constant, and the value of len is not greater
2751 than the lengths of arg1 and arg2, evaluate at compile-time. */
2752 if (host_integerp (len, 1) && p1 && p2
2753 && compare_tree_int (len, strlen (p1) + 1) <= 0
2754 && compare_tree_int (len, strlen (p2) + 1) <= 0)
2756 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
2758 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2761 /* If len parameter is one, return an expression corresponding to
2762 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2763 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
2765 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2766 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2767 tree ind1 =
2768 fold (build1 (CONVERT_EXPR, integer_type_node,
2769 build1 (INDIRECT_REF, cst_uchar_node,
2770 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2771 tree ind2 =
2772 fold (build1 (CONVERT_EXPR, integer_type_node,
2773 build1 (INDIRECT_REF, cst_uchar_node,
2774 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2775 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2776 return expand_expr (result, target, mode, EXPAND_NORMAL);
2779 #ifdef HAVE_cmpstrsi
2781 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2782 rtx result;
2783 rtx insn;
2785 int arg1_align
2786 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2787 int arg2_align
2788 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2789 enum machine_mode insn_mode
2790 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2792 /* If we don't have POINTER_TYPE, call the function. */
2793 if (arg1_align == 0 || arg2_align == 0)
2794 return 0;
2796 /* Make a place to write the result of the instruction. */
2797 result = target;
2798 if (! (result != 0
2799 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2800 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2801 result = gen_reg_rtx (insn_mode);
2803 arg1_rtx = get_memory_rtx (arg1);
2804 arg2_rtx = get_memory_rtx (arg2);
2805 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2806 if (!HAVE_cmpstrsi)
2807 insn = NULL_RTX;
2808 else
2809 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2810 GEN_INT (MIN (arg1_align, arg2_align)));
2812 if (insn)
2813 emit_insn (insn);
2814 else
2815 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2816 TYPE_MODE (integer_type_node), 3,
2817 XEXP (arg1_rtx, 0), Pmode,
2818 XEXP (arg2_rtx, 0), Pmode,
2819 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2820 TREE_UNSIGNED (sizetype)),
2821 TYPE_MODE (sizetype));
2823 /* Return the value in the proper mode for this function. */
2824 mode = TYPE_MODE (TREE_TYPE (exp));
2825 if (GET_MODE (result) == mode)
2826 return result;
2827 else if (target != 0)
2829 convert_move (target, result, 0);
2830 return target;
2832 else
2833 return convert_to_mode (mode, result, 0);
2835 #endif
2837 return 0;
2840 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2841 if we failed the caller should emit a normal call, otherwise try to get
2842 the result in TARGET, if convenient. */
2844 static rtx
2845 expand_builtin_strcmp (exp, target, mode)
2846 tree exp;
2847 rtx target;
2848 enum machine_mode mode;
2850 tree arglist = TREE_OPERAND (exp, 1);
2851 tree arg1, arg2, len, len2, fn;
2852 const char *p1, *p2;
2854 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2855 return 0;
2857 arg1 = TREE_VALUE (arglist);
2858 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2860 p1 = c_getstr (arg1);
2861 p2 = c_getstr (arg2);
2863 if (p1 && p2)
2865 const int i = strcmp (p1, p2);
2866 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2869 /* If either arg is "", return an expression corresponding to
2870 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2871 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2873 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2874 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2875 tree ind1 =
2876 fold (build1 (CONVERT_EXPR, integer_type_node,
2877 build1 (INDIRECT_REF, cst_uchar_node,
2878 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2879 tree ind2 =
2880 fold (build1 (CONVERT_EXPR, integer_type_node,
2881 build1 (INDIRECT_REF, cst_uchar_node,
2882 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2883 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2884 return expand_expr (result, target, mode, EXPAND_NORMAL);
2887 len = c_strlen (arg1);
2888 len2 = c_strlen (arg2);
2890 if (len)
2891 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2893 if (len2)
2894 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2896 /* If we don't have a constant length for the first, use the length
2897 of the second, if we know it. We don't require a constant for
2898 this case; some cost analysis could be done if both are available
2899 but neither is constant. For now, assume they're equally cheap
2900 unless one has side effects.
2902 If both strings have constant lengths, use the smaller. This
2903 could arise if optimization results in strcpy being called with
2904 two fixed strings, or if the code was machine-generated. We should
2905 add some code to the `memcmp' handler below to deal with such
2906 situations, someday. */
2908 if (!len || TREE_CODE (len) != INTEGER_CST)
2910 if (len2 && !TREE_SIDE_EFFECTS (len2))
2911 len = len2;
2912 else if (len == 0)
2913 return 0;
2915 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2916 && tree_int_cst_lt (len2, len))
2917 len = len2;
2919 /* If both arguments have side effects, we cannot optimize. */
2920 if (TREE_SIDE_EFFECTS (len))
2921 return 0;
2923 fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2924 if (!fn)
2925 return 0;
2927 chainon (arglist, build_tree_list (NULL_TREE, len));
2928 return expand_expr (build_function_call_expr (fn, arglist),
2929 target, mode, EXPAND_NORMAL);
2932 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2933 if we failed the caller should emit a normal call, otherwise try to get
2934 the result in TARGET, if convenient. */
2936 static rtx
2937 expand_builtin_strncmp (exp, target, mode)
2938 tree exp;
2939 rtx target;
2940 enum machine_mode mode;
2942 tree arglist = TREE_OPERAND (exp, 1);
2943 tree fn, newarglist, len = 0;
2944 tree arg1, arg2, arg3;
2945 const char *p1, *p2;
2947 if (!validate_arglist (arglist,
2948 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2949 return 0;
2951 arg1 = TREE_VALUE (arglist);
2952 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2953 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2955 /* If the len parameter is zero, return zero. */
2956 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2958 /* Evaluate and ignore arg1 and arg2 in case they have
2959 side-effects. */
2960 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2961 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2962 return const0_rtx;
2965 p1 = c_getstr (arg1);
2966 p2 = c_getstr (arg2);
2968 /* If all arguments are constant, evaluate at compile-time. */
2969 if (host_integerp (arg3, 1) && p1 && p2)
2971 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2972 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2975 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2976 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2977 if (host_integerp (arg3, 1)
2978 && (tree_low_cst (arg3, 1) == 1
2979 || (tree_low_cst (arg3, 1) > 1
2980 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2982 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2983 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2984 tree ind1 =
2985 fold (build1 (CONVERT_EXPR, integer_type_node,
2986 build1 (INDIRECT_REF, cst_uchar_node,
2987 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2988 tree ind2 =
2989 fold (build1 (CONVERT_EXPR, integer_type_node,
2990 build1 (INDIRECT_REF, cst_uchar_node,
2991 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2992 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2993 return expand_expr (result, target, mode, EXPAND_NORMAL);
2996 /* If c_strlen can determine an expression for one of the string
2997 lengths, and it doesn't have side effects, then call
2998 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
3000 /* Perhaps one of the strings is really constant, if so prefer
3001 that constant length over the other string's length. */
3002 if (p1)
3003 len = c_strlen (arg1);
3004 else if (p2)
3005 len = c_strlen (arg2);
3007 /* If we still don't have a len, try either string arg as long
3008 as they don't have side effects. */
3009 if (!len && !TREE_SIDE_EFFECTS (arg1))
3010 len = c_strlen (arg1);
3011 if (!len && !TREE_SIDE_EFFECTS (arg2))
3012 len = c_strlen (arg2);
3013 /* If we still don't have a length, punt. */
3014 if (!len)
3015 return 0;
3017 fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
3018 if (!fn)
3019 return 0;
3021 /* Add one to the string length. */
3022 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
3024 /* The actual new length parameter is MIN(len,arg3). */
3025 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3027 newarglist = build_tree_list (NULL_TREE, len);
3028 newarglist = tree_cons (NULL_TREE, arg2, newarglist);
3029 newarglist = tree_cons (NULL_TREE, arg1, newarglist);
3030 return expand_expr (build_function_call_expr (fn, newarglist),
3031 target, mode, EXPAND_NORMAL);
3034 /* Expand expression EXP, which is a call to the strcat builtin.
3035 Return 0 if we failed the caller should emit a normal call,
3036 otherwise try to get the result in TARGET, if convenient. */
3038 static rtx
3039 expand_builtin_strcat (arglist, target, mode)
3040 tree arglist;
3041 rtx target;
3042 enum machine_mode mode;
3044 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3045 return 0;
3046 else
3048 tree dst = TREE_VALUE (arglist),
3049 src = TREE_VALUE (TREE_CHAIN (arglist));
3050 const char *p = c_getstr (src);
3052 /* If the string length is zero, return the dst parameter. */
3053 if (p && *p == '\0')
3054 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3056 return 0;
3060 /* Expand expression EXP, which is a call to the strncat builtin.
3061 Return 0 if we failed the caller should emit a normal call,
3062 otherwise try to get the result in TARGET, if convenient. */
3064 static rtx
3065 expand_builtin_strncat (arglist, target, mode)
3066 tree arglist;
3067 rtx target;
3068 enum machine_mode mode;
3070 if (!validate_arglist (arglist,
3071 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3072 return 0;
3073 else
3075 tree dst = TREE_VALUE (arglist),
3076 src = TREE_VALUE (TREE_CHAIN (arglist)),
3077 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3078 const char *p = c_getstr (src);
3080 /* If the requested length is zero, or the src parameter string
3081 length is zero, return the dst parameter. */
3082 if (integer_zerop (len) || (p && *p == '\0'))
3084 /* Evaluate and ignore the src and len parameters in case
3085 they have side-effects. */
3086 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3087 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3088 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3091 /* If the requested len is greater than or equal to the string
3092 length, call strcat. */
3093 if (TREE_CODE (len) == INTEGER_CST && p
3094 && compare_tree_int (len, strlen (p)) >= 0)
3096 tree newarglist
3097 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3098 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3100 /* If the replacement _DECL isn't initialized, don't do the
3101 transformation. */
3102 if (!fn)
3103 return 0;
3105 return expand_expr (build_function_call_expr (fn, newarglist),
3106 target, mode, EXPAND_NORMAL);
3108 return 0;
3112 /* Expand expression EXP, which is a call to the strspn builtin.
3113 Return 0 if we failed the caller should emit a normal call,
3114 otherwise try to get the result in TARGET, if convenient. */
3116 static rtx
3117 expand_builtin_strspn (arglist, target, mode)
3118 tree arglist;
3119 rtx target;
3120 enum machine_mode mode;
3122 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3123 return 0;
3124 else
3126 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3127 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3129 /* If both arguments are constants, evaluate at compile-time. */
3130 if (p1 && p2)
3132 const size_t r = strspn (p1, p2);
3133 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3136 /* If either argument is "", return 0. */
3137 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3139 /* Evaluate and ignore both arguments in case either one has
3140 side-effects. */
3141 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3142 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3143 return const0_rtx;
3145 return 0;
3149 /* Expand expression EXP, which is a call to the strcspn builtin.
3150 Return 0 if we failed the caller should emit a normal call,
3151 otherwise try to get the result in TARGET, if convenient. */
3153 static rtx
3154 expand_builtin_strcspn (arglist, target, mode)
3155 tree arglist;
3156 rtx target;
3157 enum machine_mode mode;
3159 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3160 return 0;
3161 else
3163 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3164 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3166 /* If both arguments are constants, evaluate at compile-time. */
3167 if (p1 && p2)
3169 const size_t r = strcspn (p1, p2);
3170 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3173 /* If the first argument is "", return 0. */
3174 if (p1 && *p1 == '\0')
3176 /* Evaluate and ignore argument s2 in case it has
3177 side-effects. */
3178 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3179 return const0_rtx;
3182 /* If the second argument is "", return __builtin_strlen(s1). */
3183 if (p2 && *p2 == '\0')
3185 tree newarglist = build_tree_list (NULL_TREE, s1),
3186 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3188 /* If the replacement _DECL isn't initialized, don't do the
3189 transformation. */
3190 if (!fn)
3191 return 0;
3193 return expand_expr (build_function_call_expr (fn, newarglist),
3194 target, mode, EXPAND_NORMAL);
3196 return 0;
3200 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3201 if that's convenient. */
3204 expand_builtin_saveregs ()
3206 rtx val, seq;
3208 /* Don't do __builtin_saveregs more than once in a function.
3209 Save the result of the first call and reuse it. */
3210 if (saveregs_value != 0)
3211 return saveregs_value;
3213 /* When this function is called, it means that registers must be
3214 saved on entry to this function. So we migrate the call to the
3215 first insn of this function. */
3217 start_sequence ();
3219 #ifdef EXPAND_BUILTIN_SAVEREGS
3220 /* Do whatever the machine needs done in this case. */
3221 val = EXPAND_BUILTIN_SAVEREGS ();
3222 #else
3223 /* ??? We used to try and build up a call to the out of line function,
3224 guessing about what registers needed saving etc. This became much
3225 harder with __builtin_va_start, since we don't have a tree for a
3226 call to __builtin_saveregs to fall back on. There was exactly one
3227 port (i860) that used this code, and I'm unconvinced it could actually
3228 handle the general case. So we no longer try to handle anything
3229 weird and make the backend absorb the evil. */
3231 error ("__builtin_saveregs not supported by this target");
3232 val = const0_rtx;
3233 #endif
3235 seq = get_insns ();
3236 end_sequence ();
3238 saveregs_value = val;
3240 /* Put the insns after the NOTE that starts the function. If this
3241 is inside a start_sequence, make the outer-level insn chain current, so
3242 the code is placed at the start of the function. */
3243 push_topmost_sequence ();
3244 emit_insn_after (seq, get_insns ());
3245 pop_topmost_sequence ();
3247 return val;
3250 /* __builtin_args_info (N) returns word N of the arg space info
3251 for the current function. The number and meanings of words
3252 is controlled by the definition of CUMULATIVE_ARGS. */
3254 static rtx
3255 expand_builtin_args_info (exp)
3256 tree exp;
3258 tree arglist = TREE_OPERAND (exp, 1);
3259 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3260 int *word_ptr = (int *) &current_function_args_info;
3262 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3263 abort ();
3265 if (arglist != 0)
3267 if (!host_integerp (TREE_VALUE (arglist), 0))
3268 error ("argument of `__builtin_args_info' must be constant");
3269 else
3271 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3273 if (wordnum < 0 || wordnum >= nwords)
3274 error ("argument of `__builtin_args_info' out of range");
3275 else
3276 return GEN_INT (word_ptr[wordnum]);
3279 else
3280 error ("missing argument in `__builtin_args_info'");
3282 return const0_rtx;
3285 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3287 static rtx
3288 expand_builtin_next_arg (arglist)
3289 tree arglist;
3291 tree fntype = TREE_TYPE (current_function_decl);
3293 if (TYPE_ARG_TYPES (fntype) == 0
3294 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3295 == void_type_node))
3297 error ("`va_start' used in function with fixed args");
3298 return const0_rtx;
3301 if (arglist)
3303 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3304 tree arg = TREE_VALUE (arglist);
3306 /* Strip off all nops for the sake of the comparison. This
3307 is not quite the same as STRIP_NOPS. It does more.
3308 We must also strip off INDIRECT_EXPR for C++ reference
3309 parameters. */
3310 while (TREE_CODE (arg) == NOP_EXPR
3311 || TREE_CODE (arg) == CONVERT_EXPR
3312 || TREE_CODE (arg) == NON_LVALUE_EXPR
3313 || TREE_CODE (arg) == INDIRECT_REF)
3314 arg = TREE_OPERAND (arg, 0);
3315 if (arg != last_parm)
3316 warning ("second parameter of `va_start' not last named argument");
3318 else
3319 /* Evidently an out of date version of <stdarg.h>; can't validate
3320 va_start's second argument, but can still work as intended. */
3321 warning ("`__builtin_next_arg' called without an argument");
3323 return expand_binop (Pmode, add_optab,
3324 current_function_internal_arg_pointer,
3325 current_function_arg_offset_rtx,
3326 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3329 /* Make it easier for the backends by protecting the valist argument
3330 from multiple evaluations. */
3332 static tree
3333 stabilize_va_list (valist, needs_lvalue)
3334 tree valist;
3335 int needs_lvalue;
3337 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3339 if (TREE_SIDE_EFFECTS (valist))
3340 valist = save_expr (valist);
3342 /* For this case, the backends will be expecting a pointer to
3343 TREE_TYPE (va_list_type_node), but it's possible we've
3344 actually been given an array (an actual va_list_type_node).
3345 So fix it. */
3346 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3348 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3349 tree p2 = build_pointer_type (va_list_type_node);
3351 valist = build1 (ADDR_EXPR, p2, valist);
3352 valist = fold (build1 (NOP_EXPR, p1, valist));
3355 else
3357 tree pt;
3359 if (! needs_lvalue)
3361 if (! TREE_SIDE_EFFECTS (valist))
3362 return valist;
3364 pt = build_pointer_type (va_list_type_node);
3365 valist = fold (build1 (ADDR_EXPR, pt, valist));
3366 TREE_SIDE_EFFECTS (valist) = 1;
3369 if (TREE_SIDE_EFFECTS (valist))
3370 valist = save_expr (valist);
3371 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3372 valist));
3375 return valist;
3378 /* The "standard" implementation of va_start: just assign `nextarg' to
3379 the variable. */
3381 void
3382 std_expand_builtin_va_start (valist, nextarg)
3383 tree valist;
3384 rtx nextarg;
3386 tree t;
3388 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3389 make_tree (ptr_type_node, nextarg));
3390 TREE_SIDE_EFFECTS (t) = 1;
3392 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3395 /* Expand ARGLIST, from a call to __builtin_va_start. */
3397 static rtx
3398 expand_builtin_va_start (arglist)
3399 tree arglist;
3401 rtx nextarg;
3402 tree chain, valist;
3404 chain = TREE_CHAIN (arglist);
3406 if (TREE_CHAIN (chain))
3407 error ("too many arguments to function `va_start'");
3409 nextarg = expand_builtin_next_arg (chain);
3410 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3412 #ifdef EXPAND_BUILTIN_VA_START
3413 EXPAND_BUILTIN_VA_START (valist, nextarg);
3414 #else
3415 std_expand_builtin_va_start (valist, nextarg);
3416 #endif
3418 return const0_rtx;
3421 /* The "standard" implementation of va_arg: read the value from the
3422 current (padded) address and increment by the (padded) size. */
3425 std_expand_builtin_va_arg (valist, type)
3426 tree valist, type;
3428 tree addr_tree, t, type_size = NULL;
3429 tree align, alignm1;
3430 tree rounded_size;
3431 rtx addr;
3433 /* Compute the rounded size of the type. */
3434 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3435 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3436 if (type == error_mark_node
3437 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3438 || TREE_OVERFLOW (type_size))
3439 rounded_size = size_zero_node;
3440 else
3441 rounded_size = fold (build (MULT_EXPR, sizetype,
3442 fold (build (TRUNC_DIV_EXPR, sizetype,
3443 fold (build (PLUS_EXPR, sizetype,
3444 type_size, alignm1)),
3445 align)),
3446 align));
3448 /* Get AP. */
3449 addr_tree = valist;
3450 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3452 /* Small args are padded downward. */
3453 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3454 fold (build (COND_EXPR, sizetype,
3455 fold (build (GT_EXPR, sizetype,
3456 rounded_size,
3457 align)),
3458 size_zero_node,
3459 fold (build (MINUS_EXPR, sizetype,
3460 rounded_size,
3461 type_size))))));
3464 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3465 addr = copy_to_reg (addr);
3467 /* Compute new value for AP. */
3468 if (! integer_zerop (rounded_size))
3470 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3471 build (PLUS_EXPR, TREE_TYPE (valist), valist,
3472 rounded_size));
3473 TREE_SIDE_EFFECTS (t) = 1;
3474 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3477 return addr;
3480 /* Expand __builtin_va_arg, which is not really a builtin function, but
3481 a very special sort of operator. */
3484 expand_builtin_va_arg (valist, type)
3485 tree valist, type;
3487 rtx addr, result;
3488 tree promoted_type, want_va_type, have_va_type;
3490 /* Verify that valist is of the proper type. */
3492 want_va_type = va_list_type_node;
3493 have_va_type = TREE_TYPE (valist);
3494 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3496 /* If va_list is an array type, the argument may have decayed
3497 to a pointer type, e.g. by being passed to another function.
3498 In that case, unwrap both types so that we can compare the
3499 underlying records. */
3500 if (TREE_CODE (have_va_type) == ARRAY_TYPE
3501 || TREE_CODE (have_va_type) == POINTER_TYPE)
3503 want_va_type = TREE_TYPE (want_va_type);
3504 have_va_type = TREE_TYPE (have_va_type);
3507 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3509 error ("first argument to `va_arg' not of type `va_list'");
3510 addr = const0_rtx;
3513 /* Generate a diagnostic for requesting data of a type that cannot
3514 be passed through `...' due to type promotion at the call site. */
3515 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3516 != type)
3518 const char *name = "<anonymous type>", *pname = 0;
3519 static bool gave_help;
3521 if (TYPE_NAME (type))
3523 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3524 name = IDENTIFIER_POINTER (TYPE_NAME (type));
3525 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3526 && DECL_NAME (TYPE_NAME (type)))
3527 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3529 if (TYPE_NAME (promoted_type))
3531 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3532 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3533 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3534 && DECL_NAME (TYPE_NAME (promoted_type)))
3535 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3538 /* Unfortunately, this is merely undefined, rather than a constraint
3539 violation, so we cannot make this an error. If this call is never
3540 executed, the program is still strictly conforming. */
3541 warning ("`%s' is promoted to `%s' when passed through `...'",
3542 name, pname);
3543 if (! gave_help)
3545 gave_help = true;
3546 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3547 pname, name);
3550 /* We can, however, treat "undefined" any way we please.
3551 Call abort to encourage the user to fix the program. */
3552 expand_builtin_trap ();
3554 /* This is dead code, but go ahead and finish so that the
3555 mode of the result comes out right. */
3556 addr = const0_rtx;
3558 else
3560 /* Make it easier for the backends by protecting the valist argument
3561 from multiple evaluations. */
3562 valist = stabilize_va_list (valist, 0);
3564 #ifdef EXPAND_BUILTIN_VA_ARG
3565 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
3566 #else
3567 addr = std_expand_builtin_va_arg (valist, type);
3568 #endif
3571 #ifdef POINTERS_EXTEND_UNSIGNED
3572 if (GET_MODE (addr) != Pmode)
3573 addr = convert_memory_address (Pmode, addr);
3574 #endif
3576 result = gen_rtx_MEM (TYPE_MODE (type), addr);
3577 set_mem_alias_set (result, get_varargs_alias_set ());
3579 return result;
3582 /* Expand ARGLIST, from a call to __builtin_va_end. */
3584 static rtx
3585 expand_builtin_va_end (arglist)
3586 tree arglist;
3588 tree valist = TREE_VALUE (arglist);
3590 #ifdef EXPAND_BUILTIN_VA_END
3591 valist = stabilize_va_list (valist, 0);
3592 EXPAND_BUILTIN_VA_END (arglist);
3593 #else
3594 /* Evaluate for side effects, if needed. I hate macros that don't
3595 do that. */
3596 if (TREE_SIDE_EFFECTS (valist))
3597 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
3598 #endif
3600 return const0_rtx;
3603 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3604 builtin rather than just as an assignment in stdarg.h because of the
3605 nastiness of array-type va_list types. */
3607 static rtx
3608 expand_builtin_va_copy (arglist)
3609 tree arglist;
3611 tree dst, src, t;
3613 dst = TREE_VALUE (arglist);
3614 src = TREE_VALUE (TREE_CHAIN (arglist));
3616 dst = stabilize_va_list (dst, 1);
3617 src = stabilize_va_list (src, 0);
3619 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3621 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3622 TREE_SIDE_EFFECTS (t) = 1;
3623 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3625 else
3627 rtx dstb, srcb, size;
3629 /* Evaluate to pointers. */
3630 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3631 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3632 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3633 VOIDmode, EXPAND_NORMAL);
3635 #ifdef POINTERS_EXTEND_UNSIGNED
3636 if (GET_MODE (dstb) != Pmode)
3637 dstb = convert_memory_address (Pmode, dstb);
3639 if (GET_MODE (srcb) != Pmode)
3640 srcb = convert_memory_address (Pmode, srcb);
3641 #endif
3643 /* "Dereference" to BLKmode memories. */
3644 dstb = gen_rtx_MEM (BLKmode, dstb);
3645 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3646 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
3647 srcb = gen_rtx_MEM (BLKmode, srcb);
3648 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3649 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
3651 /* Copy. */
3652 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
3655 return const0_rtx;
3658 /* Expand a call to one of the builtin functions __builtin_frame_address or
3659 __builtin_return_address. */
3661 static rtx
3662 expand_builtin_frame_address (exp)
3663 tree exp;
3665 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3666 tree arglist = TREE_OPERAND (exp, 1);
3668 /* The argument must be a nonnegative integer constant.
3669 It counts the number of frames to scan up the stack.
3670 The value is the return address saved in that frame. */
3671 if (arglist == 0)
3672 /* Warning about missing arg was already issued. */
3673 return const0_rtx;
3674 else if (! host_integerp (TREE_VALUE (arglist), 1))
3676 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3677 error ("invalid arg to `__builtin_frame_address'");
3678 else
3679 error ("invalid arg to `__builtin_return_address'");
3680 return const0_rtx;
3682 else
3684 rtx tem
3685 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3686 tree_low_cst (TREE_VALUE (arglist), 1),
3687 hard_frame_pointer_rtx);
3689 /* Some ports cannot access arbitrary stack frames. */
3690 if (tem == NULL)
3692 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3693 warning ("unsupported arg to `__builtin_frame_address'");
3694 else
3695 warning ("unsupported arg to `__builtin_return_address'");
3696 return const0_rtx;
3699 /* For __builtin_frame_address, return what we've got. */
3700 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3701 return tem;
3703 if (GET_CODE (tem) != REG
3704 && ! CONSTANT_P (tem))
3705 tem = copy_to_mode_reg (Pmode, tem);
3706 return tem;
3710 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3711 we failed and the caller should emit a normal call, otherwise try to get
3712 the result in TARGET, if convenient. */
3714 static rtx
3715 expand_builtin_alloca (arglist, target)
3716 tree arglist;
3717 rtx target;
3719 rtx op0;
3720 rtx result;
3722 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3723 return 0;
3725 /* Compute the argument. */
3726 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3728 /* Allocate the desired space. */
3729 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3731 #ifdef POINTERS_EXTEND_UNSIGNED
3732 if (GET_MODE (result) != ptr_mode)
3733 result = convert_memory_address (ptr_mode, result);
3734 #endif
3736 return result;
3739 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
3740 Return 0 if a normal call should be emitted rather than expanding the
3741 function in-line. If convenient, the result should be placed in TARGET.
3742 SUBTARGET may be used as the target for computing one of EXP's operands. */
3744 static rtx
3745 expand_builtin_unop (target_mode, arglist, target, subtarget, op_optab)
3746 enum machine_mode target_mode;
3747 tree arglist;
3748 rtx target, subtarget;
3749 optab op_optab;
3751 rtx op0;
3752 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3753 return 0;
3755 /* Compute the argument. */
3756 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3757 /* Compute op, into TARGET if possible.
3758 Set TARGET to wherever the result comes back. */
3759 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3760 op_optab, op0, target, 1);
3761 if (target == 0)
3762 abort ();
3764 return convert_to_mode (target_mode, target, 0);
3767 /* If the string passed to fputs is a constant and is one character
3768 long, we attempt to transform this call into __builtin_fputc(). */
3770 static rtx
3771 expand_builtin_fputs (arglist, ignore, unlocked)
3772 tree arglist;
3773 int ignore;
3774 int unlocked;
3776 tree len, fn;
3777 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
3778 : implicit_built_in_decls[BUILT_IN_FPUTC];
3779 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
3780 : implicit_built_in_decls[BUILT_IN_FWRITE];
3782 /* If the return value is used, or the replacement _DECL isn't
3783 initialized, don't do the transformation. */
3784 if (!ignore || !fn_fputc || !fn_fwrite)
3785 return 0;
3787 /* Verify the arguments in the original call. */
3788 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3789 return 0;
3791 /* Get the length of the string passed to fputs. If the length
3792 can't be determined, punt. */
3793 if (!(len = c_strlen (TREE_VALUE (arglist)))
3794 || TREE_CODE (len) != INTEGER_CST)
3795 return 0;
3797 switch (compare_tree_int (len, 1))
3799 case -1: /* length is 0, delete the call entirely . */
3801 /* Evaluate and ignore the argument in case it has
3802 side-effects. */
3803 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3804 VOIDmode, EXPAND_NORMAL);
3805 return const0_rtx;
3807 case 0: /* length is 1, call fputc. */
3809 const char *p = c_getstr (TREE_VALUE (arglist));
3811 if (p != NULL)
3813 /* New argument list transforming fputs(string, stream) to
3814 fputc(string[0], stream). */
3815 arglist =
3816 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3817 arglist =
3818 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3819 fn = fn_fputc;
3820 break;
3823 /* FALLTHROUGH */
3824 case 1: /* length is greater than 1, call fwrite. */
3826 tree string_arg;
3828 /* If optimizing for size keep fputs. */
3829 if (optimize_size)
3830 return 0;
3831 string_arg = TREE_VALUE (arglist);
3832 /* New argument list transforming fputs(string, stream) to
3833 fwrite(string, 1, len, stream). */
3834 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3835 arglist = tree_cons (NULL_TREE, len, arglist);
3836 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3837 arglist = tree_cons (NULL_TREE, string_arg, arglist);
3838 fn = fn_fwrite;
3839 break;
3841 default:
3842 abort ();
3845 return expand_expr (build_function_call_expr (fn, arglist),
3846 (ignore ? const0_rtx : NULL_RTX),
3847 VOIDmode, EXPAND_NORMAL);
3850 /* Expand a call to __builtin_expect. We return our argument and emit a
3851 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3852 a non-jump context. */
3854 static rtx
3855 expand_builtin_expect (arglist, target)
3856 tree arglist;
3857 rtx target;
3859 tree exp, c;
3860 rtx note, rtx_c;
3862 if (arglist == NULL_TREE
3863 || TREE_CHAIN (arglist) == NULL_TREE)
3864 return const0_rtx;
3865 exp = TREE_VALUE (arglist);
3866 c = TREE_VALUE (TREE_CHAIN (arglist));
3868 if (TREE_CODE (c) != INTEGER_CST)
3870 error ("second arg to `__builtin_expect' must be a constant");
3871 c = integer_zero_node;
3874 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3876 /* Don't bother with expected value notes for integral constants. */
3877 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
3879 /* We do need to force this into a register so that we can be
3880 moderately sure to be able to correctly interpret the branch
3881 condition later. */
3882 target = force_reg (GET_MODE (target), target);
3884 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3886 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3887 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3890 return target;
3893 /* Like expand_builtin_expect, except do this in a jump context. This is
3894 called from do_jump if the conditional is a __builtin_expect. Return either
3895 a list of insns to emit the jump or NULL if we cannot optimize
3896 __builtin_expect. We need to optimize this at jump time so that machines
3897 like the PowerPC don't turn the test into a SCC operation, and then jump
3898 based on the test being 0/1. */
3901 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3902 tree exp;
3903 rtx if_false_label;
3904 rtx if_true_label;
3906 tree arglist = TREE_OPERAND (exp, 1);
3907 tree arg0 = TREE_VALUE (arglist);
3908 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3909 rtx ret = NULL_RTX;
3911 /* Only handle __builtin_expect (test, 0) and
3912 __builtin_expect (test, 1). */
3913 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3914 && (integer_zerop (arg1) || integer_onep (arg1)))
3916 int num_jumps = 0;
3917 rtx insn;
3919 /* If we fail to locate an appropriate conditional jump, we'll
3920 fall back to normal evaluation. Ensure that the expression
3921 can be re-evaluated. */
3922 switch (unsafe_for_reeval (arg0))
3924 case 0: /* Safe. */
3925 break;
3927 case 1: /* Mildly unsafe. */
3928 arg0 = unsave_expr (arg0);
3929 break;
3931 case 2: /* Wildly unsafe. */
3932 return NULL_RTX;
3935 /* Expand the jump insns. */
3936 start_sequence ();
3937 do_jump (arg0, if_false_label, if_true_label);
3938 ret = get_insns ();
3939 end_sequence ();
3941 /* Now that the __builtin_expect has been validated, go through and add
3942 the expect's to each of the conditional jumps. If we run into an
3943 error, just give up and generate the 'safe' code of doing a SCC
3944 operation and then doing a branch on that. */
3945 insn = ret;
3946 while (insn != NULL_RTX)
3948 rtx next = NEXT_INSN (insn);
3949 rtx pattern;
3951 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3952 && (pattern = pc_set (insn)) != NULL_RTX)
3954 rtx ifelse = SET_SRC (pattern);
3955 rtx label;
3956 int taken;
3958 if (GET_CODE (ifelse) != IF_THEN_ELSE)
3959 goto do_next_insn;
3961 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3963 taken = 1;
3964 label = XEXP (XEXP (ifelse, 1), 0);
3966 /* An inverted jump reverses the probabilities. */
3967 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3969 taken = 0;
3970 label = XEXP (XEXP (ifelse, 2), 0);
3972 /* We shouldn't have to worry about conditional returns during
3973 the expansion stage, but handle it gracefully anyway. */
3974 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3976 taken = 1;
3977 label = NULL_RTX;
3979 /* An inverted return reverses the probabilities. */
3980 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3982 taken = 0;
3983 label = NULL_RTX;
3985 else
3986 goto do_next_insn;
3988 /* If the test is expected to fail, reverse the
3989 probabilities. */
3990 if (integer_zerop (arg1))
3991 taken = 1 - taken;
3993 /* If we are jumping to the false label, reverse the
3994 probabilities. */
3995 if (label == NULL_RTX)
3996 ; /* conditional return */
3997 else if (label == if_false_label)
3998 taken = 1 - taken;
3999 else if (label != if_true_label)
4000 goto do_next_insn;
4002 num_jumps++;
4003 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4006 do_next_insn:
4007 insn = next;
4010 /* If no jumps were modified, fail and do __builtin_expect the normal
4011 way. */
4012 if (num_jumps == 0)
4013 ret = NULL_RTX;
4016 return ret;
4019 void
4020 expand_builtin_trap ()
4022 #ifdef HAVE_trap
4023 if (HAVE_trap)
4024 emit_insn (gen_trap ());
4025 else
4026 #endif
4027 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4028 emit_barrier ();
4031 /* Expand an expression EXP that calls a built-in function,
4032 with result going to TARGET if that's convenient
4033 (and in mode MODE if that's convenient).
4034 SUBTARGET may be used as the target for computing one of EXP's operands.
4035 IGNORE is nonzero if the value is to be ignored. */
4038 expand_builtin (exp, target, subtarget, mode, ignore)
4039 tree exp;
4040 rtx target;
4041 rtx subtarget;
4042 enum machine_mode mode;
4043 int ignore;
4045 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4046 tree arglist = TREE_OPERAND (exp, 1);
4047 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4048 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4050 /* Perform postincrements before expanding builtin functions.  */
4051 emit_queue ();
4053 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4054 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4056 /* When not optimizing, generate calls to library functions for a certain
4057 set of builtins. */
4058 if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
4059 switch (fcode)
4061 case BUILT_IN_SQRT:
4062 case BUILT_IN_SQRTF:
4063 case BUILT_IN_SQRTL:
4064 case BUILT_IN_SIN:
4065 case BUILT_IN_SINF:
4066 case BUILT_IN_SINL:
4067 case BUILT_IN_COS:
4068 case BUILT_IN_COSF:
4069 case BUILT_IN_COSL:
4070 case BUILT_IN_EXP:
4071 case BUILT_IN_EXPF:
4072 case BUILT_IN_EXPL:
4073 case BUILT_IN_LOG:
4074 case BUILT_IN_LOGF:
4075 case BUILT_IN_LOGL:
4076 case BUILT_IN_POW:
4077 case BUILT_IN_POWF:
4078 case BUILT_IN_POWL:
4079 case BUILT_IN_ATAN2:
4080 case BUILT_IN_ATAN2F:
4081 case BUILT_IN_ATAN2L:
4082 case BUILT_IN_MEMSET:
4083 case BUILT_IN_MEMCPY:
4084 case BUILT_IN_MEMCMP:
4085 case BUILT_IN_MEMPCPY:
4086 case BUILT_IN_BCMP:
4087 case BUILT_IN_BZERO:
4088 case BUILT_IN_INDEX:
4089 case BUILT_IN_RINDEX:
4090 case BUILT_IN_STPCPY:
4091 case BUILT_IN_STRCHR:
4092 case BUILT_IN_STRRCHR:
4093 case BUILT_IN_STRLEN:
4094 case BUILT_IN_STRCPY:
4095 case BUILT_IN_STRNCPY:
4096 case BUILT_IN_STRNCMP:
4097 case BUILT_IN_STRSTR:
4098 case BUILT_IN_STRPBRK:
4099 case BUILT_IN_STRCAT:
4100 case BUILT_IN_STRNCAT:
4101 case BUILT_IN_STRSPN:
4102 case BUILT_IN_STRCSPN:
4103 case BUILT_IN_STRCMP:
4104 case BUILT_IN_FFS:
4105 case BUILT_IN_PUTCHAR:
4106 case BUILT_IN_PUTS:
4107 case BUILT_IN_PRINTF:
4108 case BUILT_IN_FPUTC:
4109 case BUILT_IN_FPUTS:
4110 case BUILT_IN_FWRITE:
4111 case BUILT_IN_PUTCHAR_UNLOCKED:
4112 case BUILT_IN_PUTS_UNLOCKED:
4113 case BUILT_IN_PRINTF_UNLOCKED:
4114 case BUILT_IN_FPUTC_UNLOCKED:
4115 case BUILT_IN_FPUTS_UNLOCKED:
4116 case BUILT_IN_FWRITE_UNLOCKED:
4117 case BUILT_IN_FLOOR:
4118 case BUILT_IN_FLOORF:
4119 case BUILT_IN_FLOORL:
4120 case BUILT_IN_CEIL:
4121 case BUILT_IN_CEILF:
4122 case BUILT_IN_CEILL:
4123 case BUILT_IN_TRUNC:
4124 case BUILT_IN_TRUNCF:
4125 case BUILT_IN_TRUNCL:
4126 case BUILT_IN_ROUND:
4127 case BUILT_IN_ROUNDF:
4128 case BUILT_IN_ROUNDL:
4129 case BUILT_IN_NEARBYINT:
4130 case BUILT_IN_NEARBYINTF:
4131 case BUILT_IN_NEARBYINTL:
4132 return expand_call (exp, target, ignore);
4134 default:
4135 break;
4138 switch (fcode)
4140 case BUILT_IN_ABS:
4141 case BUILT_IN_LABS:
4142 case BUILT_IN_LLABS:
4143 case BUILT_IN_IMAXABS:
4144 case BUILT_IN_FABS:
4145 case BUILT_IN_FABSF:
4146 case BUILT_IN_FABSL:
4147 /* build_function_call changes these into ABS_EXPR. */
4148 abort ();
4150 case BUILT_IN_CONJ:
4151 case BUILT_IN_CONJF:
4152 case BUILT_IN_CONJL:
4153 case BUILT_IN_CREAL:
4154 case BUILT_IN_CREALF:
4155 case BUILT_IN_CREALL:
4156 case BUILT_IN_CIMAG:
4157 case BUILT_IN_CIMAGF:
4158 case BUILT_IN_CIMAGL:
4159 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4160 and IMAGPART_EXPR. */
4161 abort ();
4163 case BUILT_IN_SIN:
4164 case BUILT_IN_SINF:
4165 case BUILT_IN_SINL:
4166 case BUILT_IN_COS:
4167 case BUILT_IN_COSF:
4168 case BUILT_IN_COSL:
4169 case BUILT_IN_EXP:
4170 case BUILT_IN_EXPF:
4171 case BUILT_IN_EXPL:
4172 case BUILT_IN_LOG:
4173 case BUILT_IN_LOGF:
4174 case BUILT_IN_LOGL:
4175 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4176 because of possible accuracy problems. */
4177 if (! flag_unsafe_math_optimizations)
4178 break;
4179 case BUILT_IN_SQRT:
4180 case BUILT_IN_SQRTF:
4181 case BUILT_IN_SQRTL:
4182 case BUILT_IN_FLOOR:
4183 case BUILT_IN_FLOORF:
4184 case BUILT_IN_FLOORL:
4185 case BUILT_IN_CEIL:
4186 case BUILT_IN_CEILF:
4187 case BUILT_IN_CEILL:
4188 case BUILT_IN_TRUNC:
4189 case BUILT_IN_TRUNCF:
4190 case BUILT_IN_TRUNCL:
4191 case BUILT_IN_ROUND:
4192 case BUILT_IN_ROUNDF:
4193 case BUILT_IN_ROUNDL:
4194 case BUILT_IN_NEARBYINT:
4195 case BUILT_IN_NEARBYINTF:
4196 case BUILT_IN_NEARBYINTL:
4197 target = expand_builtin_mathfn (exp, target, subtarget);
4198 if (target)
4199 return target;
4200 break;
4202 case BUILT_IN_POW:
4203 case BUILT_IN_POWF:
4204 case BUILT_IN_POWL:
4205 case BUILT_IN_ATAN2:
4206 case BUILT_IN_ATAN2F:
4207 case BUILT_IN_ATAN2L:
4208 if (! flag_unsafe_math_optimizations)
4209 break;
4210 target = expand_builtin_mathfn_2 (exp, target, subtarget);
4211 if (target)
4212 return target;
4213 break;
4215 case BUILT_IN_APPLY_ARGS:
4216 return expand_builtin_apply_args ();
4218 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4219 FUNCTION with a copy of the parameters described by
4220 ARGUMENTS, and ARGSIZE. It returns a block of memory
4221 allocated on the stack into which is stored all the registers
4222 that might possibly be used for returning the result of a
4223 function. ARGUMENTS is the value returned by
4224 __builtin_apply_args. ARGSIZE is the number of bytes of
4225 arguments that must be copied. ??? How should this value be
4226 computed? We'll also need a safe worst case value for varargs
4227 functions. */
4228 case BUILT_IN_APPLY:
4229 if (!validate_arglist (arglist, POINTER_TYPE,
4230 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4231 && !validate_arglist (arglist, REFERENCE_TYPE,
4232 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4233 return const0_rtx;
4234 else
4236 int i;
4237 tree t;
4238 rtx ops[3];
4240 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4241 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4243 return expand_builtin_apply (ops[0], ops[1], ops[2]);
4246 /* __builtin_return (RESULT) causes the function to return the
4247 value described by RESULT. RESULT is address of the block of
4248 memory returned by __builtin_apply. */
4249 case BUILT_IN_RETURN:
4250 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4251 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4252 NULL_RTX, VOIDmode, 0));
4253 return const0_rtx;
4255 case BUILT_IN_SAVEREGS:
4256 return expand_builtin_saveregs ();
4258 case BUILT_IN_ARGS_INFO:
4259 return expand_builtin_args_info (exp);
4261 /* Return the address of the first anonymous stack arg. */
4262 case BUILT_IN_NEXT_ARG:
4263 return expand_builtin_next_arg (arglist);
4265 case BUILT_IN_CLASSIFY_TYPE:
4266 return expand_builtin_classify_type (arglist);
4268 case BUILT_IN_CONSTANT_P:
4269 return expand_builtin_constant_p (exp);
4271 case BUILT_IN_FRAME_ADDRESS:
4272 case BUILT_IN_RETURN_ADDRESS:
4273 return expand_builtin_frame_address (exp);
4275 /* Returns the address of the area where the structure is returned.
4276 0 otherwise. */
4277 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
4278 if (arglist != 0
4279 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
4280 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
4281 return const0_rtx;
4282 else
4283 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
4285 case BUILT_IN_ALLOCA:
4286 target = expand_builtin_alloca (arglist, target);
4287 if (target)
4288 return target;
4289 break;
4291 case BUILT_IN_FFS:
4292 case BUILT_IN_FFSL:
4293 case BUILT_IN_FFSLL:
4294 target = expand_builtin_unop (target_mode, arglist, target,
4295 subtarget, ffs_optab);
4296 if (target)
4297 return target;
4298 break;
4300 case BUILT_IN_CLZ:
4301 case BUILT_IN_CLZL:
4302 case BUILT_IN_CLZLL:
4303 target = expand_builtin_unop (target_mode, arglist, target,
4304 subtarget, clz_optab);
4305 if (target)
4306 return target;
4307 break;
4309 case BUILT_IN_CTZ:
4310 case BUILT_IN_CTZL:
4311 case BUILT_IN_CTZLL:
4312 target = expand_builtin_unop (target_mode, arglist, target,
4313 subtarget, ctz_optab);
4314 if (target)
4315 return target;
4316 break;
4318 case BUILT_IN_POPCOUNT:
4319 case BUILT_IN_POPCOUNTL:
4320 case BUILT_IN_POPCOUNTLL:
4321 target = expand_builtin_unop (target_mode, arglist, target,
4322 subtarget, popcount_optab);
4323 if (target)
4324 return target;
4325 break;
4327 case BUILT_IN_PARITY:
4328 case BUILT_IN_PARITYL:
4329 case BUILT_IN_PARITYLL:
4330 target = expand_builtin_unop (target_mode, arglist, target,
4331 subtarget, parity_optab);
4332 if (target)
4333 return target;
4334 break;
4336 case BUILT_IN_STRLEN:
4337 target = expand_builtin_strlen (exp, target);
4338 if (target)
4339 return target;
4340 break;
4342 case BUILT_IN_STRCPY:
4343 target = expand_builtin_strcpy (exp, target, mode);
4344 if (target)
4345 return target;
4346 break;
4348 case BUILT_IN_STRNCPY:
4349 target = expand_builtin_strncpy (arglist, target, mode);
4350 if (target)
4351 return target;
4352 break;
4354 case BUILT_IN_STPCPY:
4355 target = expand_builtin_stpcpy (arglist, target, mode);
4356 if (target)
4357 return target;
4358 break;
4360 case BUILT_IN_STRCAT:
4361 target = expand_builtin_strcat (arglist, target, mode);
4362 if (target)
4363 return target;
4364 break;
4366 case BUILT_IN_STRNCAT:
4367 target = expand_builtin_strncat (arglist, target, mode);
4368 if (target)
4369 return target;
4370 break;
4372 case BUILT_IN_STRSPN:
4373 target = expand_builtin_strspn (arglist, target, mode);
4374 if (target)
4375 return target;
4376 break;
4378 case BUILT_IN_STRCSPN:
4379 target = expand_builtin_strcspn (arglist, target, mode);
4380 if (target)
4381 return target;
4382 break;
4384 case BUILT_IN_STRSTR:
4385 target = expand_builtin_strstr (arglist, target, mode);
4386 if (target)
4387 return target;
4388 break;
4390 case BUILT_IN_STRPBRK:
4391 target = expand_builtin_strpbrk (arglist, target, mode);
4392 if (target)
4393 return target;
4394 break;
4396 case BUILT_IN_INDEX:
4397 case BUILT_IN_STRCHR:
4398 target = expand_builtin_strchr (arglist, target, mode);
4399 if (target)
4400 return target;
4401 break;
4403 case BUILT_IN_RINDEX:
4404 case BUILT_IN_STRRCHR:
4405 target = expand_builtin_strrchr (arglist, target, mode);
4406 if (target)
4407 return target;
4408 break;
4410 case BUILT_IN_MEMCPY:
4411 target = expand_builtin_memcpy (arglist, target, mode, /*endp=*/0);
4412 if (target)
4413 return target;
4414 break;
4416 case BUILT_IN_MEMPCPY:
4417 target = expand_builtin_memcpy (arglist, target, mode, /*endp=*/1);
4418 if (target)
4419 return target;
4420 break;
4422 case BUILT_IN_MEMSET:
4423 target = expand_builtin_memset (exp, target, mode);
4424 if (target)
4425 return target;
4426 break;
4428 case BUILT_IN_BZERO:
4429 target = expand_builtin_bzero (exp);
4430 if (target)
4431 return target;
4432 break;
4434 case BUILT_IN_STRCMP:
4435 target = expand_builtin_strcmp (exp, target, mode);
4436 if (target)
4437 return target;
4438 break;
4440 case BUILT_IN_STRNCMP:
4441 target = expand_builtin_strncmp (exp, target, mode);
4442 if (target)
4443 return target;
4444 break;
4446 case BUILT_IN_BCMP:
4447 case BUILT_IN_MEMCMP:
4448 target = expand_builtin_memcmp (exp, arglist, target, mode);
4449 if (target)
4450 return target;
4451 break;
4453 case BUILT_IN_SETJMP:
4454 target = expand_builtin_setjmp (arglist, target);
4455 if (target)
4456 return target;
4457 break;
4459 /* __builtin_longjmp is passed a pointer to an array of five words.
4460 It's similar to the C library longjmp function but works with
4461 __builtin_setjmp above. */
4462 case BUILT_IN_LONGJMP:
4463 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4464 break;
4465 else
4467 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
4468 VOIDmode, 0);
4469 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
4470 NULL_RTX, VOIDmode, 0);
4472 if (value != const1_rtx)
4474 error ("__builtin_longjmp second argument must be 1");
4475 return const0_rtx;
4478 expand_builtin_longjmp (buf_addr, value);
4479 return const0_rtx;
4482 case BUILT_IN_TRAP:
4483 expand_builtin_trap ();
4484 return const0_rtx;
4486 case BUILT_IN_FPUTS:
4487 target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
4488 if (target)
4489 return target;
4490 break;
4491 case BUILT_IN_FPUTS_UNLOCKED:
4492 target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
4493 if (target)
4494 return target;
4495 break;
4497 /* Various hooks for the DWARF 2 __throw routine. */
4498 case BUILT_IN_UNWIND_INIT:
4499 expand_builtin_unwind_init ();
4500 return const0_rtx;
4501 case BUILT_IN_DWARF_CFA:
4502 return virtual_cfa_rtx;
4503 #ifdef DWARF2_UNWIND_INFO
4504 case BUILT_IN_DWARF_FP_REGNUM:
4505 return expand_builtin_dwarf_fp_regnum ();
4506 case BUILT_IN_INIT_DWARF_REG_SIZES:
4507 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
4508 return const0_rtx;
4509 #endif
4510 case BUILT_IN_FROB_RETURN_ADDR:
4511 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
4512 case BUILT_IN_EXTRACT_RETURN_ADDR:
4513 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
4514 case BUILT_IN_EH_RETURN:
4515 expand_builtin_eh_return (TREE_VALUE (arglist),
4516 TREE_VALUE (TREE_CHAIN (arglist)));
4517 return const0_rtx;
4518 #ifdef EH_RETURN_DATA_REGNO
4519 case BUILT_IN_EH_RETURN_DATA_REGNO:
4520 return expand_builtin_eh_return_data_regno (arglist);
4521 #endif
4522 case BUILT_IN_VA_START:
4523 case BUILT_IN_STDARG_START:
4524 return expand_builtin_va_start (arglist);
4525 case BUILT_IN_VA_END:
4526 return expand_builtin_va_end (arglist);
4527 case BUILT_IN_VA_COPY:
4528 return expand_builtin_va_copy (arglist);
4529 case BUILT_IN_EXPECT:
4530 return expand_builtin_expect (arglist, target);
4531 case BUILT_IN_PREFETCH:
4532 expand_builtin_prefetch (arglist);
4533 return const0_rtx;
4536 default: /* just do library call, if unknown builtin */
4537 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
4538 error ("built-in function `%s' not currently supported",
4539 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
4542 /* The switch statement above can drop through to cause the function
4543 to be called normally. */
4544 return expand_call (exp, target, ignore);
4547 /* Determine whether a tree node represents a call to a built-in
4548 math function. If the tree T is a call to a built-in function
4549 taking a single real argument, then the return value is the
4550 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
4551 the return value is END_BUILTINS. */
4553 enum built_in_function
4554 builtin_mathfn_code (t)
4555 tree t;
4557 tree fndecl, arglist;
4559 if (TREE_CODE (t) != CALL_EXPR
4560 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
4561 return END_BUILTINS;
4563 fndecl = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
4564 if (TREE_CODE (fndecl) != FUNCTION_DECL
4565 || ! DECL_BUILT_IN (fndecl)
4566 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4567 return END_BUILTINS;
4569 arglist = TREE_OPERAND (t, 1);
4570 if (! arglist
4571 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
4572 return END_BUILTINS;
4574 arglist = TREE_CHAIN (arglist);
4575 switch (DECL_FUNCTION_CODE (fndecl))
4577 case BUILT_IN_POW:
4578 case BUILT_IN_POWF:
4579 case BUILT_IN_POWL:
4580 case BUILT_IN_ATAN2:
4581 case BUILT_IN_ATAN2F:
4582 case BUILT_IN_ATAN2L:
4583 if (! arglist
4584 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
4585 || TREE_CHAIN (arglist))
4586 return END_BUILTINS;
4587 break;
4589 default:
4590 if (arglist)
4591 return END_BUILTINS;
4592 break;
4595 return DECL_FUNCTION_CODE (fndecl);
4598 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4599 constant. ARGLIST is the argument list of the call. */
4601 static tree
4602 fold_builtin_constant_p (arglist)
4603 tree arglist;
4605 if (arglist == 0)
4606 return 0;
4608 arglist = TREE_VALUE (arglist);
4610 /* We return 1 for a numeric type that's known to be a constant
4611 value at compile-time or for an aggregate type that's a
4612 literal constant. */
4613 STRIP_NOPS (arglist);
4615 /* If we know this is a constant, emit the constant of one. */
4616 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
4617 || (TREE_CODE (arglist) == CONSTRUCTOR
4618 && TREE_CONSTANT (arglist))
4619 || (TREE_CODE (arglist) == ADDR_EXPR
4620 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
4621 return integer_one_node;
4623 /* If we aren't going to be running CSE or this expression
4624 has side effects, show we don't know it to be a constant.
4625 Likewise if it's a pointer or aggregate type since in those
4626 case we only want literals, since those are only optimized
4627 when generating RTL, not later.
4628 And finally, if we are compiling an initializer, not code, we
4629 need to return a definite result now; there's not going to be any
4630 more optimization done. */
4631 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
4632 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
4633 || POINTER_TYPE_P (TREE_TYPE (arglist))
4634 || cfun == 0)
4635 return integer_zero_node;
4637 return 0;
4640 /* Fold a call to __builtin_classify_type. */
4642 static tree
4643 fold_builtin_classify_type (arglist)
4644 tree arglist;
4646 if (arglist == 0)
4647 return build_int_2 (no_type_class, 0);
4649 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
4652 /* Fold a call to __builtin_inf or __builtin_huge_val. */
4654 static tree
4655 fold_builtin_inf (type, warn)
4656 tree type;
4657 int warn;
4659 REAL_VALUE_TYPE real;
4661 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
4662 warning ("target format does not support infinity");
4664 real_inf (&real);
4665 return build_real (type, real);
4668 /* Fold a call to __builtin_nan or __builtin_nans. */
4670 static tree
4671 fold_builtin_nan (arglist, type, quiet)
4672 tree arglist, type;
4673 int quiet;
4675 REAL_VALUE_TYPE real;
4676 const char *str;
4678 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4679 return 0;
4680 str = c_getstr (TREE_VALUE (arglist));
4681 if (!str)
4682 return 0;
4684 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
4685 return 0;
4687 return build_real (type, real);
4690 /* EXP is assumed to me builtin call where truncation can be propagated
4691 across (for instance floor((double)f) == (double)floorf (f).
4692 Do the transformation. */
4693 static tree
4694 fold_trunc_transparent_mathfn (exp)
4695 tree exp;
4697 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4698 tree arglist = TREE_OPERAND (exp, 1);
4699 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4701 if (optimize && validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4703 tree arg0 = strip_float_extensions (TREE_VALUE (arglist));
4704 tree ftype = TREE_TYPE (exp);
4705 tree newtype = TREE_TYPE (arg0);
4706 tree decl;
4708 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
4709 && (decl = mathfn_built_in (newtype, fcode)))
4711 arglist =
4712 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
4713 return convert (ftype,
4714 build_function_call_expr (decl, arglist));
4717 return 0;
4720 /* Used by constant folding to eliminate some builtin calls early. EXP is
4721 the CALL_EXPR of a call to a builtin function. */
4723 tree
4724 fold_builtin (exp)
4725 tree exp;
4727 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4728 tree arglist = TREE_OPERAND (exp, 1);
4729 tree type = TREE_TYPE (TREE_TYPE (fndecl));
4731 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4732 return 0;
4734 switch (DECL_FUNCTION_CODE (fndecl))
4736 case BUILT_IN_CONSTANT_P:
4737 return fold_builtin_constant_p (arglist);
4739 case BUILT_IN_CLASSIFY_TYPE:
4740 return fold_builtin_classify_type (arglist);
4742 case BUILT_IN_STRLEN:
4743 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4745 tree len = c_strlen (TREE_VALUE (arglist));
4746 if (len)
4748 /* Convert from the internal "sizetype" type to "size_t". */
4749 if (size_type_node)
4750 len = convert (size_type_node, len);
4751 return len;
4754 break;
4756 case BUILT_IN_SQRT:
4757 case BUILT_IN_SQRTF:
4758 case BUILT_IN_SQRTL:
4759 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4761 enum built_in_function fcode;
4762 tree arg = TREE_VALUE (arglist);
4764 /* Optimize sqrt of constant value. */
4765 if (TREE_CODE (arg) == REAL_CST
4766 && ! TREE_CONSTANT_OVERFLOW (arg))
4768 enum machine_mode mode;
4769 REAL_VALUE_TYPE r, x;
4771 x = TREE_REAL_CST (arg);
4772 mode = TYPE_MODE (type);
4773 if (real_sqrt (&r, mode, &x)
4774 || (!flag_trapping_math && !flag_errno_math))
4775 return build_real (type, r);
4778 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
4779 fcode = builtin_mathfn_code (arg);
4780 if (flag_unsafe_math_optimizations
4781 && (fcode == BUILT_IN_EXP
4782 || fcode == BUILT_IN_EXPF
4783 || fcode == BUILT_IN_EXPL))
4785 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
4786 arg = fold (build (MULT_EXPR, type,
4787 TREE_VALUE (TREE_OPERAND (arg, 1)),
4788 build_real (type, dconsthalf)));
4789 arglist = build_tree_list (NULL_TREE, arg);
4790 return build_function_call_expr (expfn, arglist);
4793 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
4794 if (flag_unsafe_math_optimizations
4795 && (fcode == BUILT_IN_POW
4796 || fcode == BUILT_IN_POWF
4797 || fcode == BUILT_IN_POWL))
4799 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
4800 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
4801 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
4802 tree narg1 = fold (build (MULT_EXPR, type, arg1,
4803 build_real (type, dconsthalf)));
4804 arglist = tree_cons (NULL_TREE, arg0,
4805 build_tree_list (NULL_TREE, narg1));
4806 return build_function_call_expr (powfn, arglist);
4809 break;
4811 case BUILT_IN_SIN:
4812 case BUILT_IN_SINF:
4813 case BUILT_IN_SINL:
4814 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4816 tree arg = TREE_VALUE (arglist);
4818 /* Optimize sin(0.0) = 0.0. */
4819 if (real_zerop (arg))
4820 return build_real (type, dconst0);
4822 break;
4824 case BUILT_IN_COS:
4825 case BUILT_IN_COSF:
4826 case BUILT_IN_COSL:
4827 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4829 tree arg = TREE_VALUE (arglist);
4831 /* Optimize cos(0.0) = 1.0. */
4832 if (real_zerop (arg))
4833 return build_real (type, dconst1);
4835 break;
4837 case BUILT_IN_EXP:
4838 case BUILT_IN_EXPF:
4839 case BUILT_IN_EXPL:
4840 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4842 enum built_in_function fcode;
4843 tree arg = TREE_VALUE (arglist);
4845 /* Optimize exp(0.0) = 1.0. */
4846 if (real_zerop (arg))
4847 return build_real (type, dconst1);
4849 /* Optimize exp(log(x)) = x. */
4850 fcode = builtin_mathfn_code (arg);
4851 if (flag_unsafe_math_optimizations
4852 && (fcode == BUILT_IN_LOG
4853 || fcode == BUILT_IN_LOGF
4854 || fcode == BUILT_IN_LOGL))
4855 return TREE_VALUE (TREE_OPERAND (arg, 1));
4857 break;
4859 case BUILT_IN_LOG:
4860 case BUILT_IN_LOGF:
4861 case BUILT_IN_LOGL:
4862 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4864 enum built_in_function fcode;
4865 tree arg = TREE_VALUE (arglist);
4867 /* Optimize log(1.0) = 0.0. */
4868 if (real_onep (arg))
4869 return build_real (type, dconst0);
4871 /* Optimize log(exp(x)) = x. */
4872 fcode = builtin_mathfn_code (arg);
4873 if (flag_unsafe_math_optimizations
4874 && (fcode == BUILT_IN_EXP
4875 || fcode == BUILT_IN_EXPF
4876 || fcode == BUILT_IN_EXPL))
4877 return TREE_VALUE (TREE_OPERAND (arg, 1));
4879 /* Optimize log(sqrt(x)) = log(x)*0.5. */
4880 if (flag_unsafe_math_optimizations
4881 && (fcode == BUILT_IN_SQRT
4882 || fcode == BUILT_IN_SQRTF
4883 || fcode == BUILT_IN_SQRTL))
4885 tree logfn = build_function_call_expr (fndecl,
4886 TREE_OPERAND (arg, 1));
4887 return fold (build (MULT_EXPR, type, logfn,
4888 build_real (type, dconsthalf)));
4891 /* Optimize log(pow(x,y)) = y*log(x). */
4892 if (flag_unsafe_math_optimizations
4893 && (fcode == BUILT_IN_POW
4894 || fcode == BUILT_IN_POWF
4895 || fcode == BUILT_IN_POWL))
4897 tree arg0, arg1, logfn;
4899 arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
4900 arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
4901 arglist = build_tree_list (NULL_TREE, arg0);
4902 logfn = build_function_call_expr (fndecl, arglist);
4903 return fold (build (MULT_EXPR, type, arg1, logfn));
4906 break;
4908 case BUILT_IN_POW:
4909 case BUILT_IN_POWF:
4910 case BUILT_IN_POWL:
4911 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4913 enum built_in_function fcode;
4914 tree arg0 = TREE_VALUE (arglist);
4915 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4917 /* Optimize pow(1.0,y) = 1.0. */
4918 if (real_onep (arg0))
4919 return omit_one_operand (type, build_real (type, dconst1), arg1);
4921 if (TREE_CODE (arg1) == REAL_CST
4922 && ! TREE_CONSTANT_OVERFLOW (arg1))
4924 REAL_VALUE_TYPE c;
4925 c = TREE_REAL_CST (arg1);
4927 /* Optimize pow(x,0.0) = 1.0. */
4928 if (REAL_VALUES_EQUAL (c, dconst0))
4929 return omit_one_operand (type, build_real (type, dconst1),
4930 arg0);
4932 /* Optimize pow(x,1.0) = x. */
4933 if (REAL_VALUES_EQUAL (c, dconst1))
4934 return arg0;
4936 /* Optimize pow(x,-1.0) = 1.0/x. */
4937 if (REAL_VALUES_EQUAL (c, dconstm1))
4938 return fold (build (RDIV_EXPR, type,
4939 build_real (type, dconst1),
4940 arg0));
4942 /* Optimize pow(x,2.0) = x*x. */
4943 if (REAL_VALUES_EQUAL (c, dconst2)
4944 && (*lang_hooks.decls.global_bindings_p) () == 0
4945 && ! contains_placeholder_p (arg0))
4947 arg0 = save_expr (arg0);
4948 return fold (build (MULT_EXPR, type, arg0, arg0));
4951 /* Optimize pow(x,-2.0) = 1.0/(x*x). */
4952 if (flag_unsafe_math_optimizations
4953 && REAL_VALUES_EQUAL (c, dconstm2)
4954 && (*lang_hooks.decls.global_bindings_p) () == 0
4955 && ! contains_placeholder_p (arg0))
4957 arg0 = save_expr (arg0);
4958 return fold (build (RDIV_EXPR, type,
4959 build_real (type, dconst1),
4960 fold (build (MULT_EXPR, type,
4961 arg0, arg0))));
4964 /* Optimize pow(x,0.5) = sqrt(x). */
4965 if (flag_unsafe_math_optimizations
4966 && REAL_VALUES_EQUAL (c, dconsthalf))
4968 tree sqrtfn;
4970 fcode = DECL_FUNCTION_CODE (fndecl);
4971 if (fcode == BUILT_IN_POW)
4972 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
4973 else if (fcode == BUILT_IN_POWF)
4974 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
4975 else if (fcode == BUILT_IN_POWL)
4976 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
4977 else
4978 sqrtfn = NULL_TREE;
4980 if (sqrtfn != NULL_TREE)
4982 tree arglist = build_tree_list (NULL_TREE, arg0);
4983 return build_function_call_expr (sqrtfn, arglist);
4988 /* Optimize pow(exp(x),y) = exp(x*y). */
4989 fcode = builtin_mathfn_code (arg0);
4990 if (flag_unsafe_math_optimizations
4991 && (fcode == BUILT_IN_EXP
4992 || fcode == BUILT_IN_EXPF
4993 || fcode == BUILT_IN_EXPL))
4995 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
4996 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
4997 arg = fold (build (MULT_EXPR, type, arg, arg1));
4998 arglist = build_tree_list (NULL_TREE, arg);
4999 return build_function_call_expr (expfn, arglist);
5002 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
5003 if (flag_unsafe_math_optimizations
5004 && (fcode == BUILT_IN_SQRT
5005 || fcode == BUILT_IN_SQRTF
5006 || fcode == BUILT_IN_SQRTL))
5008 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
5009 tree narg1 = fold (build (MULT_EXPR, type, arg1,
5010 build_real (type, dconsthalf)));
5012 arglist = tree_cons (NULL_TREE, narg0,
5013 build_tree_list (NULL_TREE, narg1));
5014 return build_function_call_expr (fndecl, arglist);
5017 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
5018 if (flag_unsafe_math_optimizations
5019 && (fcode == BUILT_IN_POW
5020 || fcode == BUILT_IN_POWF
5021 || fcode == BUILT_IN_POWL))
5023 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
5024 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
5025 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
5026 arglist = tree_cons (NULL_TREE, arg00,
5027 build_tree_list (NULL_TREE, narg1));
5028 return build_function_call_expr (fndecl, arglist);
5031 break;
5033 case BUILT_IN_INF:
5034 case BUILT_IN_INFF:
5035 case BUILT_IN_INFL:
5036 return fold_builtin_inf (type, true);
5038 case BUILT_IN_HUGE_VAL:
5039 case BUILT_IN_HUGE_VALF:
5040 case BUILT_IN_HUGE_VALL:
5041 return fold_builtin_inf (type, false);
5043 case BUILT_IN_NAN:
5044 case BUILT_IN_NANF:
5045 case BUILT_IN_NANL:
5046 return fold_builtin_nan (arglist, type, true);
5048 case BUILT_IN_NANS:
5049 case BUILT_IN_NANSF:
5050 case BUILT_IN_NANSL:
5051 return fold_builtin_nan (arglist, type, false);
5053 case BUILT_IN_FLOOR:
5054 case BUILT_IN_FLOORF:
5055 case BUILT_IN_FLOORL:
5056 case BUILT_IN_CEIL:
5057 case BUILT_IN_CEILF:
5058 case BUILT_IN_CEILL:
5059 case BUILT_IN_TRUNC:
5060 case BUILT_IN_TRUNCF:
5061 case BUILT_IN_TRUNCL:
5062 case BUILT_IN_ROUND:
5063 case BUILT_IN_ROUNDF:
5064 case BUILT_IN_ROUNDL:
5065 case BUILT_IN_NEARBYINT:
5066 case BUILT_IN_NEARBYINTF:
5067 case BUILT_IN_NEARBYINTL:
5068 return fold_trunc_transparent_mathfn (exp);
5070 default:
5071 break;
5074 return 0;
5077 /* Conveniently construct a function call expression. */
5079 tree
5080 build_function_call_expr (fn, arglist)
5081 tree fn, arglist;
5083 tree call_expr;
5085 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
5086 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
5087 call_expr, arglist);
5088 TREE_SIDE_EFFECTS (call_expr) = 1;
5089 return fold (call_expr);
5092 /* This function validates the types of a function call argument list
5093 represented as a tree chain of parameters against a specified list
5094 of tree_codes. If the last specifier is a 0, that represents an
5095 ellipses, otherwise the last specifier must be a VOID_TYPE. */
5097 static int
5098 validate_arglist VPARAMS ((tree arglist, ...))
5100 enum tree_code code;
5101 int res = 0;
5103 VA_OPEN (ap, arglist);
5104 VA_FIXEDARG (ap, tree, arglist);
5108 code = va_arg (ap, enum tree_code);
5109 switch (code)
5111 case 0:
5112 /* This signifies an ellipses, any further arguments are all ok. */
5113 res = 1;
5114 goto end;
5115 case VOID_TYPE:
5116 /* This signifies an endlink, if no arguments remain, return
5117 true, otherwise return false. */
5118 res = arglist == 0;
5119 goto end;
5120 default:
5121 /* If no parameters remain or the parameter's code does not
5122 match the specified code, return false. Otherwise continue
5123 checking any remaining arguments. */
5124 if (arglist == 0
5125 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
5126 goto end;
5127 break;
5129 arglist = TREE_CHAIN (arglist);
5131 while (1);
5133 /* We need gotos here since we can only have one VA_CLOSE in a
5134 function. */
5135 end: ;
5136 VA_CLOSE (ap);
5138 return res;
5141 /* Default version of target-specific builtin setup that does nothing. */
5143 void
5144 default_init_builtins ()
5148 /* Default target-specific builtin expander that does nothing. */
5151 default_expand_builtin (exp, target, subtarget, mode, ignore)
5152 tree exp ATTRIBUTE_UNUSED;
5153 rtx target ATTRIBUTE_UNUSED;
5154 rtx subtarget ATTRIBUTE_UNUSED;
5155 enum machine_mode mode ATTRIBUTE_UNUSED;
5156 int ignore ATTRIBUTE_UNUSED;
5158 return NULL_RTX;
5161 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
5163 void
5164 purge_builtin_constant_p ()
5166 rtx insn, set, arg, new, note;
5168 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5169 if (INSN_P (insn)
5170 && (set = single_set (insn)) != NULL_RTX
5171 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
5172 || (GET_CODE (arg) == SUBREG
5173 && (GET_CODE (arg = SUBREG_REG (arg))
5174 == CONSTANT_P_RTX))))
5176 arg = XEXP (arg, 0);
5177 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
5178 validate_change (insn, &SET_SRC (set), new, 0);
5180 /* Remove the REG_EQUAL note from the insn. */
5181 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
5182 remove_note (insn, note);