* java/util/zip/ZipFile.java (finalize): New method.
[official-gcc.git] / gcc / builtins.c
blob25ae873e1415e73e53b81026c8b9be6b1b671986
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));
129 static rtx expand_builtin_strcpy PARAMS ((tree, rtx,
130 enum machine_mode));
131 static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
132 enum machine_mode));
133 static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
134 enum machine_mode));
135 static rtx builtin_memset_read_str PARAMS ((PTR, HOST_WIDE_INT,
136 enum machine_mode));
137 static rtx builtin_memset_gen_str PARAMS ((PTR, HOST_WIDE_INT,
138 enum machine_mode));
139 static rtx expand_builtin_memset PARAMS ((tree, rtx,
140 enum machine_mode));
141 static rtx expand_builtin_bzero PARAMS ((tree));
142 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
143 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
144 enum machine_mode));
145 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
146 enum machine_mode));
147 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
148 enum machine_mode));
149 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
150 enum machine_mode));
151 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
152 static rtx expand_builtin_unop PARAMS ((tree, rtx, rtx, optab));
153 static rtx expand_builtin_frame_address PARAMS ((tree));
154 static rtx expand_builtin_fputs PARAMS ((tree, int, int));
155 static tree stabilize_va_list PARAMS ((tree, int));
156 static rtx expand_builtin_expect PARAMS ((tree, rtx));
157 static tree fold_builtin_constant_p PARAMS ((tree));
158 static tree fold_builtin_classify_type PARAMS ((tree));
159 static tree fold_builtin_inf PARAMS ((tree, int));
160 static tree fold_builtin_nan PARAMS ((tree, tree, int));
161 static int validate_arglist PARAMS ((tree, ...));
162 static tree fold_trunc_transparent_mathfn PARAMS ((tree));
164 /* Return the alignment in bits of EXP, a pointer valued expression.
165 But don't return more than MAX_ALIGN no matter what.
166 The alignment returned is, by default, the alignment of the thing that
167 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
169 Otherwise, look at the expression to see if we can do better, i.e., if the
170 expression is actually pointing at an object whose alignment is tighter. */
172 static int
173 get_pointer_alignment (exp, max_align)
174 tree exp;
175 unsigned int max_align;
177 unsigned int align, inner;
179 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
180 return 0;
182 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
183 align = MIN (align, max_align);
185 while (1)
187 switch (TREE_CODE (exp))
189 case NOP_EXPR:
190 case CONVERT_EXPR:
191 case NON_LVALUE_EXPR:
192 exp = TREE_OPERAND (exp, 0);
193 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
194 return align;
196 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
197 align = MIN (inner, max_align);
198 break;
200 case PLUS_EXPR:
201 /* If sum of pointer + int, restrict our maximum alignment to that
202 imposed by the integer. If not, we can't do any better than
203 ALIGN. */
204 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
205 return align;
207 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
208 & (max_align / BITS_PER_UNIT - 1))
209 != 0)
210 max_align >>= 1;
212 exp = TREE_OPERAND (exp, 0);
213 break;
215 case ADDR_EXPR:
216 /* See what we are pointing at and look at its alignment. */
217 exp = TREE_OPERAND (exp, 0);
218 if (TREE_CODE (exp) == FUNCTION_DECL)
219 align = FUNCTION_BOUNDARY;
220 else if (DECL_P (exp))
221 align = DECL_ALIGN (exp);
222 #ifdef CONSTANT_ALIGNMENT
223 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
224 align = CONSTANT_ALIGNMENT (exp, align);
225 #endif
226 return MIN (align, max_align);
228 default:
229 return align;
234 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
235 way, because it could contain a zero byte in the middle.
236 TREE_STRING_LENGTH is the size of the character array, not the string.
238 The value returned is of type `ssizetype'.
240 Unfortunately, string_constant can't access the values of const char
241 arrays with initializers, so neither can we do so here. */
243 static tree
244 c_strlen (src)
245 tree src;
247 tree offset_node;
248 HOST_WIDE_INT offset;
249 int max;
250 const char *ptr;
252 src = string_constant (src, &offset_node);
253 if (src == 0)
254 return 0;
256 max = TREE_STRING_LENGTH (src) - 1;
257 ptr = TREE_STRING_POINTER (src);
259 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
261 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
262 compute the offset to the following null if we don't know where to
263 start searching for it. */
264 int i;
266 for (i = 0; i < max; i++)
267 if (ptr[i] == 0)
268 return 0;
270 /* We don't know the starting offset, but we do know that the string
271 has no internal zero bytes. We can assume that the offset falls
272 within the bounds of the string; otherwise, the programmer deserves
273 what he gets. Subtract the offset from the length of the string,
274 and return that. This would perhaps not be valid if we were dealing
275 with named arrays in addition to literal string constants. */
277 return size_diffop (size_int (max), offset_node);
280 /* We have a known offset into the string. Start searching there for
281 a null character if we can represent it as a single HOST_WIDE_INT. */
282 if (offset_node == 0)
283 offset = 0;
284 else if (! host_integerp (offset_node, 0))
285 offset = -1;
286 else
287 offset = tree_low_cst (offset_node, 0);
289 /* If the offset is known to be out of bounds, warn, and call strlen at
290 runtime. */
291 if (offset < 0 || offset > max)
293 warning ("offset outside bounds of constant string");
294 return 0;
297 /* Use strlen to search for the first zero byte. Since any strings
298 constructed with build_string will have nulls appended, we win even
299 if we get handed something like (char[4])"abcd".
301 Since OFFSET is our starting index into the string, no further
302 calculation is needed. */
303 return ssize_int (strlen (ptr + offset));
306 /* Return a char pointer for a C string if it is a string constant
307 or sum of string constant and integer constant. */
309 static const char *
310 c_getstr (src)
311 tree src;
313 tree offset_node;
315 src = string_constant (src, &offset_node);
316 if (src == 0)
317 return 0;
319 if (offset_node == 0)
320 return TREE_STRING_POINTER (src);
321 else if (!host_integerp (offset_node, 1)
322 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
323 return 0;
325 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
328 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
329 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
331 static rtx
332 c_readstr (str, mode)
333 const char *str;
334 enum machine_mode mode;
336 HOST_WIDE_INT c[2];
337 HOST_WIDE_INT ch;
338 unsigned int i, j;
340 if (GET_MODE_CLASS (mode) != MODE_INT)
341 abort ();
342 c[0] = 0;
343 c[1] = 0;
344 ch = 1;
345 for (i = 0; i < GET_MODE_SIZE (mode); i++)
347 j = i;
348 if (WORDS_BIG_ENDIAN)
349 j = GET_MODE_SIZE (mode) - i - 1;
350 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
351 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
352 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
353 j *= BITS_PER_UNIT;
354 if (j > 2 * HOST_BITS_PER_WIDE_INT)
355 abort ();
356 if (ch)
357 ch = (unsigned char) str[i];
358 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
360 return immed_double_const (c[0], c[1], mode);
363 /* Cast a target constant CST to target CHAR and if that value fits into
364 host char type, return zero and put that value into variable pointed by
365 P. */
367 static int
368 target_char_cast (cst, p)
369 tree cst;
370 char *p;
372 unsigned HOST_WIDE_INT val, hostval;
374 if (!host_integerp (cst, 1)
375 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
376 return 1;
378 val = tree_low_cst (cst, 1);
379 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
380 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
382 hostval = val;
383 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
384 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
386 if (val != hostval)
387 return 1;
389 *p = hostval;
390 return 0;
393 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
394 times to get the address of either a higher stack frame, or a return
395 address located within it (depending on FNDECL_CODE). */
398 expand_builtin_return_addr (fndecl_code, count, tem)
399 enum built_in_function fndecl_code;
400 int count;
401 rtx tem;
403 int i;
405 /* Some machines need special handling before we can access
406 arbitrary frames. For example, on the sparc, we must first flush
407 all register windows to the stack. */
408 #ifdef SETUP_FRAME_ADDRESSES
409 if (count > 0)
410 SETUP_FRAME_ADDRESSES ();
411 #endif
413 /* On the sparc, the return address is not in the frame, it is in a
414 register. There is no way to access it off of the current frame
415 pointer, but it can be accessed off the previous frame pointer by
416 reading the value from the register window save area. */
417 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
418 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
419 count--;
420 #endif
422 /* Scan back COUNT frames to the specified frame. */
423 for (i = 0; i < count; i++)
425 /* Assume the dynamic chain pointer is in the word that the
426 frame address points to, unless otherwise specified. */
427 #ifdef DYNAMIC_CHAIN_ADDRESS
428 tem = DYNAMIC_CHAIN_ADDRESS (tem);
429 #endif
430 tem = memory_address (Pmode, tem);
431 tem = gen_rtx_MEM (Pmode, tem);
432 set_mem_alias_set (tem, get_frame_alias_set ());
433 tem = copy_to_reg (tem);
436 /* For __builtin_frame_address, return what we've got. */
437 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
438 return tem;
440 /* For __builtin_return_address, Get the return address from that
441 frame. */
442 #ifdef RETURN_ADDR_RTX
443 tem = RETURN_ADDR_RTX (count, tem);
444 #else
445 tem = memory_address (Pmode,
446 plus_constant (tem, GET_MODE_SIZE (Pmode)));
447 tem = gen_rtx_MEM (Pmode, tem);
448 set_mem_alias_set (tem, get_frame_alias_set ());
449 #endif
450 return tem;
453 /* Alias set used for setjmp buffer. */
454 static HOST_WIDE_INT setjmp_alias_set = -1;
456 /* Construct the leading half of a __builtin_setjmp call. Control will
457 return to RECEIVER_LABEL. This is used directly by sjlj exception
458 handling code. */
460 void
461 expand_builtin_setjmp_setup (buf_addr, receiver_label)
462 rtx buf_addr;
463 rtx receiver_label;
465 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
466 rtx stack_save;
467 rtx mem;
469 if (setjmp_alias_set == -1)
470 setjmp_alias_set = new_alias_set ();
472 #ifdef POINTERS_EXTEND_UNSIGNED
473 if (GET_MODE (buf_addr) != Pmode)
474 buf_addr = convert_memory_address (Pmode, buf_addr);
475 #endif
477 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
479 emit_queue ();
481 /* We store the frame pointer and the address of receiver_label in
482 the buffer and use the rest of it for the stack save area, which
483 is machine-dependent. */
485 #ifndef BUILTIN_SETJMP_FRAME_VALUE
486 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
487 #endif
489 mem = gen_rtx_MEM (Pmode, buf_addr);
490 set_mem_alias_set (mem, setjmp_alias_set);
491 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
493 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
494 set_mem_alias_set (mem, setjmp_alias_set);
496 emit_move_insn (validize_mem (mem),
497 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
499 stack_save = gen_rtx_MEM (sa_mode,
500 plus_constant (buf_addr,
501 2 * GET_MODE_SIZE (Pmode)));
502 set_mem_alias_set (stack_save, setjmp_alias_set);
503 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
505 /* If there is further processing to do, do it. */
506 #ifdef HAVE_builtin_setjmp_setup
507 if (HAVE_builtin_setjmp_setup)
508 emit_insn (gen_builtin_setjmp_setup (buf_addr));
509 #endif
511 /* Tell optimize_save_area_alloca that extra work is going to
512 need to go on during alloca. */
513 current_function_calls_setjmp = 1;
515 /* Set this so all the registers get saved in our frame; we need to be
516 able to copy the saved values for any registers from frames we unwind. */
517 current_function_has_nonlocal_label = 1;
520 /* Construct the trailing part of a __builtin_setjmp call.
521 This is used directly by sjlj exception handling code. */
523 void
524 expand_builtin_setjmp_receiver (receiver_label)
525 rtx receiver_label ATTRIBUTE_UNUSED;
527 /* Clobber the FP when we get here, so we have to make sure it's
528 marked as used by this function. */
529 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
531 /* Mark the static chain as clobbered here so life information
532 doesn't get messed up for it. */
533 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
535 /* Now put in the code to restore the frame pointer, and argument
536 pointer, if needed. The code below is from expand_end_bindings
537 in stmt.c; see detailed documentation there. */
538 #ifdef HAVE_nonlocal_goto
539 if (! HAVE_nonlocal_goto)
540 #endif
541 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
543 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
544 if (fixed_regs[ARG_POINTER_REGNUM])
546 #ifdef ELIMINABLE_REGS
547 size_t i;
548 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
550 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
551 if (elim_regs[i].from == ARG_POINTER_REGNUM
552 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
553 break;
555 if (i == ARRAY_SIZE (elim_regs))
556 #endif
558 /* Now restore our arg pointer from the address at which it
559 was saved in our stack frame. */
560 emit_move_insn (virtual_incoming_args_rtx,
561 copy_to_reg (get_arg_pointer_save_area (cfun)));
564 #endif
566 #ifdef HAVE_builtin_setjmp_receiver
567 if (HAVE_builtin_setjmp_receiver)
568 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
569 else
570 #endif
571 #ifdef HAVE_nonlocal_goto_receiver
572 if (HAVE_nonlocal_goto_receiver)
573 emit_insn (gen_nonlocal_goto_receiver ());
574 else
575 #endif
576 { /* Nothing */ }
578 /* @@@ This is a kludge. Not all machine descriptions define a blockage
579 insn, but we must not allow the code we just generated to be reordered
580 by scheduling. Specifically, the update of the frame pointer must
581 happen immediately, not later. So emit an ASM_INPUT to act as blockage
582 insn. */
583 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
586 /* __builtin_setjmp is passed a pointer to an array of five words (not
587 all will be used on all machines). It operates similarly to the C
588 library function of the same name, but is more efficient. Much of
589 the code below (and for longjmp) is copied from the handling of
590 non-local gotos.
592 NOTE: This is intended for use by GNAT and the exception handling
593 scheme in the compiler and will only work in the method used by
594 them. */
596 static rtx
597 expand_builtin_setjmp (arglist, target)
598 tree arglist;
599 rtx target;
601 rtx buf_addr, next_lab, cont_lab;
603 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
604 return NULL_RTX;
606 if (target == 0 || GET_CODE (target) != REG
607 || REGNO (target) < FIRST_PSEUDO_REGISTER)
608 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
610 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
612 next_lab = gen_label_rtx ();
613 cont_lab = gen_label_rtx ();
615 expand_builtin_setjmp_setup (buf_addr, next_lab);
617 /* Set TARGET to zero and branch to the continue label. */
618 emit_move_insn (target, const0_rtx);
619 emit_jump_insn (gen_jump (cont_lab));
620 emit_barrier ();
621 emit_label (next_lab);
623 expand_builtin_setjmp_receiver (next_lab);
625 /* Set TARGET to one. */
626 emit_move_insn (target, const1_rtx);
627 emit_label (cont_lab);
629 /* Tell flow about the strange goings on. Putting `next_lab' on
630 `nonlocal_goto_handler_labels' to indicates that function
631 calls may traverse the arc back to this label. */
633 current_function_has_nonlocal_label = 1;
634 nonlocal_goto_handler_labels
635 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
637 return target;
640 /* __builtin_longjmp is passed a pointer to an array of five words (not
641 all will be used on all machines). It operates similarly to the C
642 library function of the same name, but is more efficient. Much of
643 the code below is copied from the handling of non-local gotos.
645 NOTE: This is intended for use by GNAT and the exception handling
646 scheme in the compiler and will only work in the method used by
647 them. */
649 void
650 expand_builtin_longjmp (buf_addr, value)
651 rtx buf_addr, value;
653 rtx fp, lab, stack, insn, last;
654 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
656 if (setjmp_alias_set == -1)
657 setjmp_alias_set = new_alias_set ();
659 #ifdef POINTERS_EXTEND_UNSIGNED
660 if (GET_MODE (buf_addr) != Pmode)
661 buf_addr = convert_memory_address (Pmode, buf_addr);
662 #endif
664 buf_addr = force_reg (Pmode, buf_addr);
666 /* We used to store value in static_chain_rtx, but that fails if pointers
667 are smaller than integers. We instead require that the user must pass
668 a second argument of 1, because that is what builtin_setjmp will
669 return. This also makes EH slightly more efficient, since we are no
670 longer copying around a value that we don't care about. */
671 if (value != const1_rtx)
672 abort ();
674 current_function_calls_longjmp = 1;
676 last = get_last_insn ();
677 #ifdef HAVE_builtin_longjmp
678 if (HAVE_builtin_longjmp)
679 emit_insn (gen_builtin_longjmp (buf_addr));
680 else
681 #endif
683 fp = gen_rtx_MEM (Pmode, buf_addr);
684 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
685 GET_MODE_SIZE (Pmode)));
687 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
688 2 * GET_MODE_SIZE (Pmode)));
689 set_mem_alias_set (fp, setjmp_alias_set);
690 set_mem_alias_set (lab, setjmp_alias_set);
691 set_mem_alias_set (stack, setjmp_alias_set);
693 /* Pick up FP, label, and SP from the block and jump. This code is
694 from expand_goto in stmt.c; see there for detailed comments. */
695 #if HAVE_nonlocal_goto
696 if (HAVE_nonlocal_goto)
697 /* We have to pass a value to the nonlocal_goto pattern that will
698 get copied into the static_chain pointer, but it does not matter
699 what that value is, because builtin_setjmp does not use it. */
700 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
701 else
702 #endif
704 lab = copy_to_reg (lab);
706 emit_move_insn (hard_frame_pointer_rtx, fp);
707 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
709 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
710 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
711 emit_indirect_jump (lab);
715 /* Search backwards and mark the jump insn as a non-local goto.
716 Note that this precludes the use of __builtin_longjmp to a
717 __builtin_setjmp target in the same function. However, we've
718 already cautioned the user that these functions are for
719 internal exception handling use only. */
720 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
722 if (insn == last)
723 abort ();
724 if (GET_CODE (insn) == JUMP_INSN)
726 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
727 REG_NOTES (insn));
728 break;
730 else if (GET_CODE (insn) == CALL_INSN)
731 break;
735 /* Expand a call to __builtin_prefetch. For a target that does not support
736 data prefetch, evaluate the memory address argument in case it has side
737 effects. */
739 static void
740 expand_builtin_prefetch (arglist)
741 tree arglist;
743 tree arg0, arg1, arg2;
744 rtx op0, op1, op2;
746 if (!validate_arglist (arglist, POINTER_TYPE, 0))
747 return;
749 arg0 = TREE_VALUE (arglist);
750 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
751 zero (read) and argument 2 (locality) defaults to 3 (high degree of
752 locality). */
753 if (TREE_CHAIN (arglist))
755 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
756 if (TREE_CHAIN (TREE_CHAIN (arglist)))
757 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
758 else
759 arg2 = build_int_2 (3, 0);
761 else
763 arg1 = integer_zero_node;
764 arg2 = build_int_2 (3, 0);
767 /* Argument 0 is an address. */
768 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
770 /* Argument 1 (read/write flag) must be a compile-time constant int. */
771 if (TREE_CODE (arg1) != INTEGER_CST)
773 error ("second arg to `__builtin_prefetch' must be a constant");
774 arg1 = integer_zero_node;
776 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
777 /* Argument 1 must be either zero or one. */
778 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
780 warning ("invalid second arg to __builtin_prefetch; using zero");
781 op1 = const0_rtx;
784 /* Argument 2 (locality) must be a compile-time constant int. */
785 if (TREE_CODE (arg2) != INTEGER_CST)
787 error ("third arg to `__builtin_prefetch' must be a constant");
788 arg2 = integer_zero_node;
790 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
791 /* Argument 2 must be 0, 1, 2, or 3. */
792 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
794 warning ("invalid third arg to __builtin_prefetch; using zero");
795 op2 = const0_rtx;
798 #ifdef HAVE_prefetch
799 if (HAVE_prefetch)
801 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
802 (op0,
803 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
804 || (GET_MODE(op0) != Pmode))
806 #ifdef POINTERS_EXTEND_UNSIGNED
807 if (GET_MODE(op0) != Pmode)
808 op0 = convert_memory_address (Pmode, op0);
809 #endif
810 op0 = force_reg (Pmode, op0);
812 emit_insn (gen_prefetch (op0, op1, op2));
814 else
815 #endif
816 op0 = protect_from_queue (op0, 0);
817 /* Don't do anything with direct references to volatile memory, but
818 generate code to handle other side effects. */
819 if (GET_CODE (op0) != MEM && side_effects_p (op0))
820 emit_insn (op0);
823 /* Get a MEM rtx for expression EXP which is the address of an operand
824 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
826 static rtx
827 get_memory_rtx (exp)
828 tree exp;
830 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
831 rtx mem;
833 #ifdef POINTERS_EXTEND_UNSIGNED
834 if (GET_MODE (addr) != Pmode)
835 addr = convert_memory_address (Pmode, addr);
836 #endif
838 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
840 /* Get an expression we can use to find the attributes to assign to MEM.
841 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
842 we can. First remove any nops. */
843 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
844 || TREE_CODE (exp) == NON_LVALUE_EXPR)
845 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
846 exp = TREE_OPERAND (exp, 0);
848 if (TREE_CODE (exp) == ADDR_EXPR)
850 exp = TREE_OPERAND (exp, 0);
851 set_mem_attributes (mem, exp, 0);
853 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
855 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
856 /* memcpy, memset and other builtin stringops can alias with anything. */
857 set_mem_alias_set (mem, 0);
860 return mem;
863 /* Built-in functions to perform an untyped call and return. */
865 /* For each register that may be used for calling a function, this
866 gives a mode used to copy the register's value. VOIDmode indicates
867 the register is not used for calling a function. If the machine
868 has register windows, this gives only the outbound registers.
869 INCOMING_REGNO gives the corresponding inbound register. */
870 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
872 /* For each register that may be used for returning values, this gives
873 a mode used to copy the register's value. VOIDmode indicates the
874 register is not used for returning values. If the machine has
875 register windows, this gives only the outbound registers.
876 INCOMING_REGNO gives the corresponding inbound register. */
877 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
879 /* For each register that may be used for calling a function, this
880 gives the offset of that register into the block returned by
881 __builtin_apply_args. 0 indicates that the register is not
882 used for calling a function. */
883 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
885 /* Return the offset of register REGNO into the block returned by
886 __builtin_apply_args. This is not declared static, since it is
887 needed in objc-act.c. */
890 apply_args_register_offset (regno)
891 int regno;
893 apply_args_size ();
895 /* Arguments are always put in outgoing registers (in the argument
896 block) if such make sense. */
897 #ifdef OUTGOING_REGNO
898 regno = OUTGOING_REGNO (regno);
899 #endif
900 return apply_args_reg_offset[regno];
903 /* Return the size required for the block returned by __builtin_apply_args,
904 and initialize apply_args_mode. */
906 static int
907 apply_args_size ()
909 static int size = -1;
910 int align;
911 unsigned int regno;
912 enum machine_mode mode;
914 /* The values computed by this function never change. */
915 if (size < 0)
917 /* The first value is the incoming arg-pointer. */
918 size = GET_MODE_SIZE (Pmode);
920 /* The second value is the structure value address unless this is
921 passed as an "invisible" first argument. */
922 if (struct_value_rtx)
923 size += GET_MODE_SIZE (Pmode);
925 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
926 if (FUNCTION_ARG_REGNO_P (regno))
928 /* Search for the proper mode for copying this register's
929 value. I'm not sure this is right, but it works so far. */
930 enum machine_mode best_mode = VOIDmode;
932 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
933 mode != VOIDmode;
934 mode = GET_MODE_WIDER_MODE (mode))
935 if (HARD_REGNO_MODE_OK (regno, mode)
936 && HARD_REGNO_NREGS (regno, mode) == 1)
937 best_mode = mode;
939 if (best_mode == VOIDmode)
940 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
941 mode != VOIDmode;
942 mode = GET_MODE_WIDER_MODE (mode))
943 if (HARD_REGNO_MODE_OK (regno, mode)
944 && have_insn_for (SET, mode))
945 best_mode = mode;
947 if (best_mode == VOIDmode)
948 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
949 mode != VOIDmode;
950 mode = GET_MODE_WIDER_MODE (mode))
951 if (HARD_REGNO_MODE_OK (regno, mode)
952 && have_insn_for (SET, mode))
953 best_mode = mode;
955 if (best_mode == VOIDmode)
956 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
957 mode != VOIDmode;
958 mode = GET_MODE_WIDER_MODE (mode))
959 if (HARD_REGNO_MODE_OK (regno, mode)
960 && have_insn_for (SET, mode))
961 best_mode = mode;
963 mode = best_mode;
964 if (mode == VOIDmode)
965 abort ();
967 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
968 if (size % align != 0)
969 size = CEIL (size, align) * align;
970 apply_args_reg_offset[regno] = size;
971 size += GET_MODE_SIZE (mode);
972 apply_args_mode[regno] = mode;
974 else
976 apply_args_mode[regno] = VOIDmode;
977 apply_args_reg_offset[regno] = 0;
980 return size;
983 /* Return the size required for the block returned by __builtin_apply,
984 and initialize apply_result_mode. */
986 static int
987 apply_result_size ()
989 static int size = -1;
990 int align, regno;
991 enum machine_mode mode;
993 /* The values computed by this function never change. */
994 if (size < 0)
996 size = 0;
998 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
999 if (FUNCTION_VALUE_REGNO_P (regno))
1001 /* Search for the proper mode for copying this register's
1002 value. I'm not sure this is right, but it works so far. */
1003 enum machine_mode best_mode = VOIDmode;
1005 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1006 mode != TImode;
1007 mode = GET_MODE_WIDER_MODE (mode))
1008 if (HARD_REGNO_MODE_OK (regno, mode))
1009 best_mode = mode;
1011 if (best_mode == VOIDmode)
1012 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1013 mode != VOIDmode;
1014 mode = GET_MODE_WIDER_MODE (mode))
1015 if (HARD_REGNO_MODE_OK (regno, mode)
1016 && have_insn_for (SET, mode))
1017 best_mode = mode;
1019 if (best_mode == VOIDmode)
1020 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1021 mode != VOIDmode;
1022 mode = GET_MODE_WIDER_MODE (mode))
1023 if (HARD_REGNO_MODE_OK (regno, mode)
1024 && have_insn_for (SET, mode))
1025 best_mode = mode;
1027 if (best_mode == VOIDmode)
1028 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1029 mode != VOIDmode;
1030 mode = GET_MODE_WIDER_MODE (mode))
1031 if (HARD_REGNO_MODE_OK (regno, mode)
1032 && have_insn_for (SET, mode))
1033 best_mode = mode;
1035 mode = best_mode;
1036 if (mode == VOIDmode)
1037 abort ();
1039 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1040 if (size % align != 0)
1041 size = CEIL (size, align) * align;
1042 size += GET_MODE_SIZE (mode);
1043 apply_result_mode[regno] = mode;
1045 else
1046 apply_result_mode[regno] = VOIDmode;
1048 /* Allow targets that use untyped_call and untyped_return to override
1049 the size so that machine-specific information can be stored here. */
1050 #ifdef APPLY_RESULT_SIZE
1051 size = APPLY_RESULT_SIZE;
1052 #endif
1054 return size;
1057 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1058 /* Create a vector describing the result block RESULT. If SAVEP is true,
1059 the result block is used to save the values; otherwise it is used to
1060 restore the values. */
1062 static rtx
1063 result_vector (savep, result)
1064 int savep;
1065 rtx result;
1067 int regno, size, align, nelts;
1068 enum machine_mode mode;
1069 rtx reg, mem;
1070 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1072 size = nelts = 0;
1073 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1074 if ((mode = apply_result_mode[regno]) != VOIDmode)
1076 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1077 if (size % align != 0)
1078 size = CEIL (size, align) * align;
1079 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1080 mem = adjust_address (result, mode, size);
1081 savevec[nelts++] = (savep
1082 ? gen_rtx_SET (VOIDmode, mem, reg)
1083 : gen_rtx_SET (VOIDmode, reg, mem));
1084 size += GET_MODE_SIZE (mode);
1086 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1088 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1090 /* Save the state required to perform an untyped call with the same
1091 arguments as were passed to the current function. */
1093 static rtx
1094 expand_builtin_apply_args_1 ()
1096 rtx registers;
1097 int size, align, regno;
1098 enum machine_mode mode;
1100 /* Create a block where the arg-pointer, structure value address,
1101 and argument registers can be saved. */
1102 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1104 /* Walk past the arg-pointer and structure value address. */
1105 size = GET_MODE_SIZE (Pmode);
1106 if (struct_value_rtx)
1107 size += GET_MODE_SIZE (Pmode);
1109 /* Save each register used in calling a function to the block. */
1110 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1111 if ((mode = apply_args_mode[regno]) != VOIDmode)
1113 rtx tem;
1115 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1116 if (size % align != 0)
1117 size = CEIL (size, align) * align;
1119 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1121 emit_move_insn (adjust_address (registers, mode, size), tem);
1122 size += GET_MODE_SIZE (mode);
1125 /* Save the arg pointer to the block. */
1126 emit_move_insn (adjust_address (registers, Pmode, 0),
1127 copy_to_reg (virtual_incoming_args_rtx));
1128 size = GET_MODE_SIZE (Pmode);
1130 /* Save the structure value address unless this is passed as an
1131 "invisible" first argument. */
1132 if (struct_value_incoming_rtx)
1134 emit_move_insn (adjust_address (registers, Pmode, size),
1135 copy_to_reg (struct_value_incoming_rtx));
1136 size += GET_MODE_SIZE (Pmode);
1139 /* Return the address of the block. */
1140 return copy_addr_to_reg (XEXP (registers, 0));
1143 /* __builtin_apply_args returns block of memory allocated on
1144 the stack into which is stored the arg pointer, structure
1145 value address, static chain, and all the registers that might
1146 possibly be used in performing a function call. The code is
1147 moved to the start of the function so the incoming values are
1148 saved. */
1150 static rtx
1151 expand_builtin_apply_args ()
1153 /* Don't do __builtin_apply_args more than once in a function.
1154 Save the result of the first call and reuse it. */
1155 if (apply_args_value != 0)
1156 return apply_args_value;
1158 /* When this function is called, it means that registers must be
1159 saved on entry to this function. So we migrate the
1160 call to the first insn of this function. */
1161 rtx temp;
1162 rtx seq;
1164 start_sequence ();
1165 temp = expand_builtin_apply_args_1 ();
1166 seq = get_insns ();
1167 end_sequence ();
1169 apply_args_value = temp;
1171 /* Put the insns after the NOTE that starts the function.
1172 If this is inside a start_sequence, make the outer-level insn
1173 chain current, so the code is placed at the start of the
1174 function. */
1175 push_topmost_sequence ();
1176 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1177 pop_topmost_sequence ();
1178 return temp;
1182 /* Perform an untyped call and save the state required to perform an
1183 untyped return of whatever value was returned by the given function. */
1185 static rtx
1186 expand_builtin_apply (function, arguments, argsize)
1187 rtx function, arguments, argsize;
1189 int size, align, regno;
1190 enum machine_mode mode;
1191 rtx incoming_args, result, reg, dest, src, call_insn;
1192 rtx old_stack_level = 0;
1193 rtx call_fusage = 0;
1195 #ifdef POINTERS_EXTEND_UNSIGNED
1196 if (GET_MODE (arguments) != Pmode)
1197 arguments = convert_memory_address (Pmode, arguments);
1198 #endif
1200 /* Create a block where the return registers can be saved. */
1201 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1203 /* Fetch the arg pointer from the ARGUMENTS block. */
1204 incoming_args = gen_reg_rtx (Pmode);
1205 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1206 #ifndef STACK_GROWS_DOWNWARD
1207 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1208 incoming_args, 0, OPTAB_LIB_WIDEN);
1209 #endif
1211 /* Perform postincrements before actually calling the function. */
1212 emit_queue ();
1214 /* Push a new argument block and copy the arguments. Do not allow
1215 the (potential) memcpy call below to interfere with our stack
1216 manipulations. */
1217 do_pending_stack_adjust ();
1218 NO_DEFER_POP;
1220 /* Save the stack with nonlocal if available */
1221 #ifdef HAVE_save_stack_nonlocal
1222 if (HAVE_save_stack_nonlocal)
1223 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1224 else
1225 #endif
1226 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1228 /* Push a block of memory onto the stack to store the memory arguments.
1229 Save the address in a register, and copy the memory arguments. ??? I
1230 haven't figured out how the calling convention macros effect this,
1231 but it's likely that the source and/or destination addresses in
1232 the block copy will need updating in machine specific ways. */
1233 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1234 dest = gen_rtx_MEM (BLKmode, dest);
1235 set_mem_align (dest, PARM_BOUNDARY);
1236 src = gen_rtx_MEM (BLKmode, incoming_args);
1237 set_mem_align (src, PARM_BOUNDARY);
1238 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1240 /* Refer to the argument block. */
1241 apply_args_size ();
1242 arguments = gen_rtx_MEM (BLKmode, arguments);
1243 set_mem_align (arguments, PARM_BOUNDARY);
1245 /* Walk past the arg-pointer and structure value address. */
1246 size = GET_MODE_SIZE (Pmode);
1247 if (struct_value_rtx)
1248 size += GET_MODE_SIZE (Pmode);
1250 /* Restore each of the registers previously saved. Make USE insns
1251 for each of these registers for use in making the call. */
1252 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1253 if ((mode = apply_args_mode[regno]) != VOIDmode)
1255 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1256 if (size % align != 0)
1257 size = CEIL (size, align) * align;
1258 reg = gen_rtx_REG (mode, regno);
1259 emit_move_insn (reg, adjust_address (arguments, mode, size));
1260 use_reg (&call_fusage, reg);
1261 size += GET_MODE_SIZE (mode);
1264 /* Restore the structure value address unless this is passed as an
1265 "invisible" first argument. */
1266 size = GET_MODE_SIZE (Pmode);
1267 if (struct_value_rtx)
1269 rtx value = gen_reg_rtx (Pmode);
1270 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1271 emit_move_insn (struct_value_rtx, value);
1272 if (GET_CODE (struct_value_rtx) == REG)
1273 use_reg (&call_fusage, struct_value_rtx);
1274 size += GET_MODE_SIZE (Pmode);
1277 /* All arguments and registers used for the call are set up by now! */
1278 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1280 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1281 and we don't want to load it into a register as an optimization,
1282 because prepare_call_address already did it if it should be done. */
1283 if (GET_CODE (function) != SYMBOL_REF)
1284 function = memory_address (FUNCTION_MODE, function);
1286 /* Generate the actual call instruction and save the return value. */
1287 #ifdef HAVE_untyped_call
1288 if (HAVE_untyped_call)
1289 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1290 result, result_vector (1, result)));
1291 else
1292 #endif
1293 #ifdef HAVE_call_value
1294 if (HAVE_call_value)
1296 rtx valreg = 0;
1298 /* Locate the unique return register. It is not possible to
1299 express a call that sets more than one return register using
1300 call_value; use untyped_call for that. In fact, untyped_call
1301 only needs to save the return registers in the given block. */
1302 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1303 if ((mode = apply_result_mode[regno]) != VOIDmode)
1305 if (valreg)
1306 abort (); /* HAVE_untyped_call required. */
1307 valreg = gen_rtx_REG (mode, regno);
1310 emit_call_insn (GEN_CALL_VALUE (valreg,
1311 gen_rtx_MEM (FUNCTION_MODE, function),
1312 const0_rtx, NULL_RTX, const0_rtx));
1314 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1316 else
1317 #endif
1318 abort ();
1320 /* Find the CALL insn we just emitted. */
1321 for (call_insn = get_last_insn ();
1322 call_insn && GET_CODE (call_insn) != CALL_INSN;
1323 call_insn = PREV_INSN (call_insn))
1326 if (! call_insn)
1327 abort ();
1329 /* Put the register usage information on the CALL. If there is already
1330 some usage information, put ours at the end. */
1331 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1333 rtx link;
1335 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1336 link = XEXP (link, 1))
1339 XEXP (link, 1) = call_fusage;
1341 else
1342 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1344 /* Restore the stack. */
1345 #ifdef HAVE_save_stack_nonlocal
1346 if (HAVE_save_stack_nonlocal)
1347 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1348 else
1349 #endif
1350 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1352 OK_DEFER_POP;
1354 /* Return the address of the result block. */
1355 return copy_addr_to_reg (XEXP (result, 0));
1358 /* Perform an untyped return. */
1360 static void
1361 expand_builtin_return (result)
1362 rtx result;
1364 int size, align, regno;
1365 enum machine_mode mode;
1366 rtx reg;
1367 rtx call_fusage = 0;
1369 #ifdef POINTERS_EXTEND_UNSIGNED
1370 if (GET_MODE (result) != Pmode)
1371 result = convert_memory_address (Pmode, result);
1372 #endif
1374 apply_result_size ();
1375 result = gen_rtx_MEM (BLKmode, result);
1377 #ifdef HAVE_untyped_return
1378 if (HAVE_untyped_return)
1380 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1381 emit_barrier ();
1382 return;
1384 #endif
1386 /* Restore the return value and note that each value is used. */
1387 size = 0;
1388 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1389 if ((mode = apply_result_mode[regno]) != VOIDmode)
1391 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1392 if (size % align != 0)
1393 size = CEIL (size, align) * align;
1394 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1395 emit_move_insn (reg, adjust_address (result, mode, size));
1397 push_to_sequence (call_fusage);
1398 emit_insn (gen_rtx_USE (VOIDmode, reg));
1399 call_fusage = get_insns ();
1400 end_sequence ();
1401 size += GET_MODE_SIZE (mode);
1404 /* Put the USE insns before the return. */
1405 emit_insn (call_fusage);
1407 /* Return whatever values was restored by jumping directly to the end
1408 of the function. */
1409 expand_null_return ();
1412 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1414 static enum type_class
1415 type_to_class (type)
1416 tree type;
1418 switch (TREE_CODE (type))
1420 case VOID_TYPE: return void_type_class;
1421 case INTEGER_TYPE: return integer_type_class;
1422 case CHAR_TYPE: return char_type_class;
1423 case ENUMERAL_TYPE: return enumeral_type_class;
1424 case BOOLEAN_TYPE: return boolean_type_class;
1425 case POINTER_TYPE: return pointer_type_class;
1426 case REFERENCE_TYPE: return reference_type_class;
1427 case OFFSET_TYPE: return offset_type_class;
1428 case REAL_TYPE: return real_type_class;
1429 case COMPLEX_TYPE: return complex_type_class;
1430 case FUNCTION_TYPE: return function_type_class;
1431 case METHOD_TYPE: return method_type_class;
1432 case RECORD_TYPE: return record_type_class;
1433 case UNION_TYPE:
1434 case QUAL_UNION_TYPE: return union_type_class;
1435 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1436 ? string_type_class : array_type_class);
1437 case SET_TYPE: return set_type_class;
1438 case FILE_TYPE: return file_type_class;
1439 case LANG_TYPE: return lang_type_class;
1440 default: return no_type_class;
1444 /* Expand a call to __builtin_classify_type with arguments found in
1445 ARGLIST. */
1447 static rtx
1448 expand_builtin_classify_type (arglist)
1449 tree arglist;
1451 if (arglist != 0)
1452 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1453 return GEN_INT (no_type_class);
1456 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1458 static rtx
1459 expand_builtin_constant_p (exp)
1460 tree exp;
1462 tree arglist = TREE_OPERAND (exp, 1);
1463 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1464 rtx tmp;
1466 if (arglist == 0)
1467 return const0_rtx;
1468 arglist = TREE_VALUE (arglist);
1470 /* We have taken care of the easy cases during constant folding. This
1471 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1472 get a chance to see if it can deduce whether ARGLIST is constant. */
1474 current_function_calls_constant_p = 1;
1476 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1477 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1478 return tmp;
1481 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1482 if available. */
1483 tree
1484 mathfn_built_in (type, fn)
1485 tree type;
1486 enum built_in_function fn;
1488 enum built_in_function fcode = NOT_BUILT_IN;
1489 if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
1490 switch (fn)
1492 case BUILT_IN_SQRT:
1493 case BUILT_IN_SQRTF:
1494 case BUILT_IN_SQRTL:
1495 fcode = BUILT_IN_SQRT;
1496 break;
1497 case BUILT_IN_SIN:
1498 case BUILT_IN_SINF:
1499 case BUILT_IN_SINL:
1500 fcode = BUILT_IN_SIN;
1501 break;
1502 case BUILT_IN_COS:
1503 case BUILT_IN_COSF:
1504 case BUILT_IN_COSL:
1505 fcode = BUILT_IN_COS;
1506 break;
1507 case BUILT_IN_EXP:
1508 case BUILT_IN_EXPF:
1509 case BUILT_IN_EXPL:
1510 fcode = BUILT_IN_EXP;
1511 break;
1512 case BUILT_IN_LOG:
1513 case BUILT_IN_LOGF:
1514 case BUILT_IN_LOGL:
1515 fcode = BUILT_IN_LOG;
1516 break;
1517 case BUILT_IN_FLOOR:
1518 case BUILT_IN_FLOORF:
1519 case BUILT_IN_FLOORL:
1520 fcode = BUILT_IN_FLOOR;
1521 break;
1522 case BUILT_IN_CEIL:
1523 case BUILT_IN_CEILF:
1524 case BUILT_IN_CEILL:
1525 fcode = BUILT_IN_CEIL;
1526 break;
1527 case BUILT_IN_TRUNC:
1528 case BUILT_IN_TRUNCF:
1529 case BUILT_IN_TRUNCL:
1530 fcode = BUILT_IN_TRUNC;
1531 break;
1532 case BUILT_IN_ROUND:
1533 case BUILT_IN_ROUNDF:
1534 case BUILT_IN_ROUNDL:
1535 fcode = BUILT_IN_ROUND;
1536 break;
1537 case BUILT_IN_NEARBYINT:
1538 case BUILT_IN_NEARBYINTF:
1539 case BUILT_IN_NEARBYINTL:
1540 fcode = BUILT_IN_NEARBYINT;
1541 break;
1542 default:
1543 abort ();
1545 else if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
1546 switch (fn)
1548 case BUILT_IN_SQRT:
1549 case BUILT_IN_SQRTF:
1550 case BUILT_IN_SQRTL:
1551 fcode = BUILT_IN_SQRTF;
1552 break;
1553 case BUILT_IN_SIN:
1554 case BUILT_IN_SINF:
1555 case BUILT_IN_SINL:
1556 fcode = BUILT_IN_SINF;
1557 break;
1558 case BUILT_IN_COS:
1559 case BUILT_IN_COSF:
1560 case BUILT_IN_COSL:
1561 fcode = BUILT_IN_COSF;
1562 break;
1563 case BUILT_IN_EXP:
1564 case BUILT_IN_EXPF:
1565 case BUILT_IN_EXPL:
1566 fcode = BUILT_IN_EXPF;
1567 break;
1568 case BUILT_IN_LOG:
1569 case BUILT_IN_LOGF:
1570 case BUILT_IN_LOGL:
1571 fcode = BUILT_IN_LOGF;
1572 break;
1573 case BUILT_IN_FLOOR:
1574 case BUILT_IN_FLOORF:
1575 case BUILT_IN_FLOORL:
1576 fcode = BUILT_IN_FLOORF;
1577 break;
1578 case BUILT_IN_CEIL:
1579 case BUILT_IN_CEILF:
1580 case BUILT_IN_CEILL:
1581 fcode = BUILT_IN_CEILF;
1582 break;
1583 case BUILT_IN_TRUNC:
1584 case BUILT_IN_TRUNCF:
1585 case BUILT_IN_TRUNCL:
1586 fcode = BUILT_IN_TRUNCF;
1587 break;
1588 case BUILT_IN_ROUND:
1589 case BUILT_IN_ROUNDF:
1590 case BUILT_IN_ROUNDL:
1591 fcode = BUILT_IN_ROUNDF;
1592 break;
1593 case BUILT_IN_NEARBYINT:
1594 case BUILT_IN_NEARBYINTF:
1595 case BUILT_IN_NEARBYINTL:
1596 fcode = BUILT_IN_NEARBYINTF;
1597 break;
1598 default:
1599 abort ();
1601 else if (TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
1602 switch (fn)
1604 case BUILT_IN_SQRT:
1605 case BUILT_IN_SQRTF:
1606 case BUILT_IN_SQRTL:
1607 fcode = BUILT_IN_SQRTL;
1608 break;
1609 case BUILT_IN_SIN:
1610 case BUILT_IN_SINF:
1611 case BUILT_IN_SINL:
1612 fcode = BUILT_IN_SINL;
1613 break;
1614 case BUILT_IN_COS:
1615 case BUILT_IN_COSF:
1616 case BUILT_IN_COSL:
1617 fcode = BUILT_IN_COSL;
1618 break;
1619 case BUILT_IN_EXP:
1620 case BUILT_IN_EXPF:
1621 case BUILT_IN_EXPL:
1622 fcode = BUILT_IN_EXPL;
1623 break;
1624 case BUILT_IN_LOG:
1625 case BUILT_IN_LOGF:
1626 case BUILT_IN_LOGL:
1627 fcode = BUILT_IN_LOGL;
1628 break;
1629 case BUILT_IN_FLOOR:
1630 case BUILT_IN_FLOORF:
1631 case BUILT_IN_FLOORL:
1632 fcode = BUILT_IN_FLOORL;
1633 break;
1634 case BUILT_IN_CEIL:
1635 case BUILT_IN_CEILF:
1636 case BUILT_IN_CEILL:
1637 fcode = BUILT_IN_CEILL;
1638 break;
1639 case BUILT_IN_TRUNC:
1640 case BUILT_IN_TRUNCF:
1641 case BUILT_IN_TRUNCL:
1642 fcode = BUILT_IN_TRUNCL;
1643 break;
1644 case BUILT_IN_ROUND:
1645 case BUILT_IN_ROUNDF:
1646 case BUILT_IN_ROUNDL:
1647 fcode = BUILT_IN_ROUNDL;
1648 break;
1649 case BUILT_IN_NEARBYINT:
1650 case BUILT_IN_NEARBYINTF:
1651 case BUILT_IN_NEARBYINTL:
1652 fcode = BUILT_IN_NEARBYINTL;
1653 break;
1654 default:
1655 abort ();
1657 return implicit_built_in_decls[fcode];
1660 /* If errno must be maintained, expand the RTL to check if the result,
1661 TARGET, of a built-in function call, EXP, is NaN, and if so set
1662 errno to EDOM. */
1664 static void
1665 expand_errno_check (exp, target)
1666 tree exp;
1667 rtx target;
1669 rtx lab;
1671 if (flag_errno_math && HONOR_NANS (GET_MODE (target)))
1673 lab = gen_label_rtx ();
1675 /* Test the result; if it is NaN, set errno=EDOM because
1676 the argument was not in the domain. */
1677 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1678 0, lab);
1680 #ifdef TARGET_EDOM
1682 #ifdef GEN_ERRNO_RTX
1683 rtx errno_rtx = GEN_ERRNO_RTX;
1684 #else
1685 rtx errno_rtx
1686 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1687 #endif
1689 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1691 #else
1692 /* We can't set errno=EDOM directly; let the library call do it.
1693 Pop the arguments right away in case the call gets deleted. */
1694 NO_DEFER_POP;
1695 expand_call (exp, target, 0);
1696 OK_DEFER_POP;
1697 #endif
1699 emit_label (lab);
1704 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1705 Return 0 if a normal call should be emitted rather than expanding the
1706 function in-line. EXP is the expression that is a call to the builtin
1707 function; if convenient, the result should be placed in TARGET.
1708 SUBTARGET may be used as the target for computing one of EXP's operands. */
1710 static rtx
1711 expand_builtin_mathfn (exp, target, subtarget)
1712 tree exp;
1713 rtx target, subtarget;
1715 optab builtin_optab;
1716 rtx op0, insns;
1717 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1718 tree arglist = TREE_OPERAND (exp, 1);
1719 enum machine_mode argmode;
1720 bool errno_set = true;
1722 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1723 return 0;
1725 /* Stabilize and compute the argument. */
1726 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1727 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1729 exp = copy_node (exp);
1730 TREE_OPERAND (exp, 1) = arglist;
1731 /* Wrap the computation of the argument in a SAVE_EXPR. That
1732 way, if we need to expand the argument again (as in the
1733 flag_errno_math case below where we cannot directly set
1734 errno), we will not perform side-effects more than once.
1735 Note that here we're mutating the original EXP as well as the
1736 copy; that's the right thing to do in case the original EXP
1737 is expanded later. */
1738 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1739 arglist = copy_node (arglist);
1741 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1743 /* Make a suitable register to place result in. */
1744 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1746 emit_queue ();
1747 start_sequence ();
1749 switch (DECL_FUNCTION_CODE (fndecl))
1751 case BUILT_IN_SIN:
1752 case BUILT_IN_SINF:
1753 case BUILT_IN_SINL:
1754 builtin_optab = sin_optab; break;
1755 case BUILT_IN_COS:
1756 case BUILT_IN_COSF:
1757 case BUILT_IN_COSL:
1758 builtin_optab = cos_optab; break;
1759 case BUILT_IN_SQRT:
1760 case BUILT_IN_SQRTF:
1761 case BUILT_IN_SQRTL:
1762 builtin_optab = sqrt_optab; break;
1763 case BUILT_IN_EXP:
1764 case BUILT_IN_EXPF:
1765 case BUILT_IN_EXPL:
1766 builtin_optab = exp_optab; break;
1767 case BUILT_IN_LOG:
1768 case BUILT_IN_LOGF:
1769 case BUILT_IN_LOGL:
1770 builtin_optab = log_optab; break;
1771 case BUILT_IN_FLOOR:
1772 case BUILT_IN_FLOORF:
1773 case BUILT_IN_FLOORL:
1774 errno_set = false ; builtin_optab = floor_optab; break;
1775 case BUILT_IN_CEIL:
1776 case BUILT_IN_CEILF:
1777 case BUILT_IN_CEILL:
1778 errno_set = false ; builtin_optab = ceil_optab; break;
1779 case BUILT_IN_TRUNC:
1780 case BUILT_IN_TRUNCF:
1781 case BUILT_IN_TRUNCL:
1782 errno_set = false ; builtin_optab = trunc_optab; break;
1783 case BUILT_IN_ROUND:
1784 case BUILT_IN_ROUNDF:
1785 case BUILT_IN_ROUNDL:
1786 errno_set = false ; builtin_optab = round_optab; break;
1787 case BUILT_IN_NEARBYINT:
1788 case BUILT_IN_NEARBYINTF:
1789 case BUILT_IN_NEARBYINTL:
1790 errno_set = false ; builtin_optab = nearbyint_optab; break;
1791 default:
1792 abort ();
1795 /* Compute into TARGET.
1796 Set TARGET to wherever the result comes back. */
1797 argmode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
1798 target = expand_unop (argmode, builtin_optab, op0, target, 0);
1800 /* If we were unable to expand via the builtin, stop the
1801 sequence (without outputting the insns) and return 0, causing
1802 a call to the library function. */
1803 if (target == 0)
1805 end_sequence ();
1806 return 0;
1809 if (errno_set)
1810 expand_errno_check (exp, target);
1812 /* Output the entire sequence. */
1813 insns = get_insns ();
1814 end_sequence ();
1815 emit_insn (insns);
1817 return target;
1820 /* Expand a call to the builtin binary math functions (pow and atan2).
1821 Return 0 if a normal call should be emitted rather than expanding the
1822 function in-line. EXP is the expression that is a call to the builtin
1823 function; if convenient, the result should be placed in TARGET.
1824 SUBTARGET may be used as the target for computing one of EXP's
1825 operands. */
1827 static rtx
1828 expand_builtin_mathfn_2 (exp, target, subtarget)
1829 tree exp;
1830 rtx target, subtarget;
1832 optab builtin_optab;
1833 rtx op0, op1, insns;
1834 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1835 tree arglist = TREE_OPERAND (exp, 1);
1836 tree arg0, arg1;
1837 enum machine_mode argmode;
1838 bool errno_set = true;
1839 bool stable = true;
1841 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1842 return 0;
1844 arg0 = TREE_VALUE (arglist);
1845 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1847 /* Stabilize the arguments. */
1848 if (TREE_CODE (arg0) != VAR_DECL && TREE_CODE (arg0) != PARM_DECL)
1850 arg0 = save_expr (arg0);
1851 TREE_VALUE (arglist) = arg0;
1852 stable = false;
1854 if (TREE_CODE (arg1) != VAR_DECL && TREE_CODE (arg1) != PARM_DECL)
1856 arg1 = save_expr (arg1);
1857 TREE_VALUE (TREE_CHAIN (arglist)) = arg1;
1858 stable = false;
1861 if (! stable)
1863 exp = copy_node (exp);
1864 arglist = tree_cons (NULL_TREE, arg0,
1865 build_tree_list (NULL_TREE, arg1));
1866 TREE_OPERAND (exp, 1) = arglist;
1869 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1870 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1872 /* Make a suitable register to place result in. */
1873 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1875 emit_queue ();
1876 start_sequence ();
1878 switch (DECL_FUNCTION_CODE (fndecl))
1880 case BUILT_IN_POW:
1881 case BUILT_IN_POWF:
1882 case BUILT_IN_POWL:
1883 builtin_optab = pow_optab; break;
1884 case BUILT_IN_ATAN2:
1885 case BUILT_IN_ATAN2F:
1886 case BUILT_IN_ATAN2L:
1887 builtin_optab = atan2_optab; break;
1888 default:
1889 abort ();
1892 /* Compute into TARGET.
1893 Set TARGET to wherever the result comes back. */
1894 argmode = TYPE_MODE (TREE_TYPE (arg0));
1895 target = expand_binop (argmode, builtin_optab, op0, op1,
1896 target, 0, OPTAB_DIRECT);
1898 /* If we were unable to expand via the builtin, stop the
1899 sequence (without outputting the insns) and return 0, causing
1900 a call to the library function. */
1901 if (target == 0)
1903 end_sequence ();
1904 return 0;
1907 if (errno_set)
1908 expand_errno_check (exp, target);
1910 /* Output the entire sequence. */
1911 insns = get_insns ();
1912 end_sequence ();
1913 emit_insn (insns);
1915 return target;
1918 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1919 if we failed the caller should emit a normal call, otherwise
1920 try to get the result in TARGET, if convenient. */
1922 static rtx
1923 expand_builtin_strlen (exp, target)
1924 tree exp;
1925 rtx target;
1927 tree arglist = TREE_OPERAND (exp, 1);
1928 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1930 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1931 return 0;
1932 else
1934 rtx pat;
1935 tree src = TREE_VALUE (arglist);
1937 int align
1938 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1940 rtx result, src_reg, char_rtx, before_strlen;
1941 enum machine_mode insn_mode = value_mode, char_mode;
1942 enum insn_code icode = CODE_FOR_nothing;
1944 /* If SRC is not a pointer type, don't do this operation inline. */
1945 if (align == 0)
1946 return 0;
1948 /* Bail out if we can't compute strlen in the right mode. */
1949 while (insn_mode != VOIDmode)
1951 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1952 if (icode != CODE_FOR_nothing)
1953 break;
1955 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1957 if (insn_mode == VOIDmode)
1958 return 0;
1960 /* Make a place to write the result of the instruction. */
1961 result = target;
1962 if (! (result != 0
1963 && GET_CODE (result) == REG
1964 && GET_MODE (result) == insn_mode
1965 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1966 result = gen_reg_rtx (insn_mode);
1968 /* Make a place to hold the source address. We will not expand
1969 the actual source until we are sure that the expansion will
1970 not fail -- there are trees that cannot be expanded twice. */
1971 src_reg = gen_reg_rtx (Pmode);
1973 /* Mark the beginning of the strlen sequence so we can emit the
1974 source operand later. */
1975 before_strlen = get_last_insn ();
1977 char_rtx = const0_rtx;
1978 char_mode = insn_data[(int) icode].operand[2].mode;
1979 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1980 char_mode))
1981 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1983 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1984 char_rtx, GEN_INT (align));
1985 if (! pat)
1986 return 0;
1987 emit_insn (pat);
1989 /* Now that we are assured of success, expand the source. */
1990 start_sequence ();
1991 pat = memory_address (BLKmode,
1992 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1993 if (pat != src_reg)
1994 emit_move_insn (src_reg, pat);
1995 pat = get_insns ();
1996 end_sequence ();
1998 if (before_strlen)
1999 emit_insn_after (pat, before_strlen);
2000 else
2001 emit_insn_before (pat, get_insns ());
2003 /* Return the value in the proper mode for this function. */
2004 if (GET_MODE (result) == value_mode)
2005 target = result;
2006 else if (target != 0)
2007 convert_move (target, result, 0);
2008 else
2009 target = convert_to_mode (value_mode, result, 0);
2011 return target;
2015 /* Expand a call to the strstr builtin. Return 0 if we failed the
2016 caller should emit a normal call, otherwise try to get the result
2017 in TARGET, if convenient (and in mode MODE if that's convenient). */
2019 static rtx
2020 expand_builtin_strstr (arglist, target, mode)
2021 tree arglist;
2022 rtx target;
2023 enum machine_mode mode;
2025 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2026 return 0;
2027 else
2029 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2030 tree fn;
2031 const char *p1, *p2;
2033 p2 = c_getstr (s2);
2034 if (p2 == NULL)
2035 return 0;
2037 p1 = c_getstr (s1);
2038 if (p1 != NULL)
2040 const char *r = strstr (p1, p2);
2042 if (r == NULL)
2043 return const0_rtx;
2045 /* Return an offset into the constant string argument. */
2046 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2047 s1, ssize_int (r - p1))),
2048 target, mode, EXPAND_NORMAL);
2051 if (p2[0] == '\0')
2052 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2054 if (p2[1] != '\0')
2055 return 0;
2057 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2058 if (!fn)
2059 return 0;
2061 /* New argument list transforming strstr(s1, s2) to
2062 strchr(s1, s2[0]). */
2063 arglist =
2064 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2065 arglist = tree_cons (NULL_TREE, s1, arglist);
2066 return expand_expr (build_function_call_expr (fn, arglist),
2067 target, mode, EXPAND_NORMAL);
2071 /* Expand a call to the strchr builtin. Return 0 if we failed the
2072 caller should emit a normal call, otherwise try to get the result
2073 in TARGET, if convenient (and in mode MODE if that's convenient). */
2075 static rtx
2076 expand_builtin_strchr (arglist, target, mode)
2077 tree arglist;
2078 rtx target;
2079 enum machine_mode mode;
2081 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2082 return 0;
2083 else
2085 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2086 const char *p1;
2088 if (TREE_CODE (s2) != INTEGER_CST)
2089 return 0;
2091 p1 = c_getstr (s1);
2092 if (p1 != NULL)
2094 char c;
2095 const char *r;
2097 if (target_char_cast (s2, &c))
2098 return 0;
2100 r = strchr (p1, c);
2102 if (r == NULL)
2103 return const0_rtx;
2105 /* Return an offset into the constant string argument. */
2106 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2107 s1, ssize_int (r - p1))),
2108 target, mode, EXPAND_NORMAL);
2111 /* FIXME: Should use here strchrM optab so that ports can optimize
2112 this. */
2113 return 0;
2117 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2118 caller should emit a normal call, otherwise try to get the result
2119 in TARGET, if convenient (and in mode MODE if that's convenient). */
2121 static rtx
2122 expand_builtin_strrchr (arglist, target, mode)
2123 tree arglist;
2124 rtx target;
2125 enum machine_mode mode;
2127 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2128 return 0;
2129 else
2131 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2132 tree fn;
2133 const char *p1;
2135 if (TREE_CODE (s2) != INTEGER_CST)
2136 return 0;
2138 p1 = c_getstr (s1);
2139 if (p1 != NULL)
2141 char c;
2142 const char *r;
2144 if (target_char_cast (s2, &c))
2145 return 0;
2147 r = strrchr (p1, c);
2149 if (r == NULL)
2150 return const0_rtx;
2152 /* Return an offset into the constant string argument. */
2153 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2154 s1, ssize_int (r - p1))),
2155 target, mode, EXPAND_NORMAL);
2158 if (! integer_zerop (s2))
2159 return 0;
2161 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2162 if (!fn)
2163 return 0;
2165 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2166 return expand_expr (build_function_call_expr (fn, arglist),
2167 target, mode, EXPAND_NORMAL);
2171 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2172 caller should emit a normal call, otherwise try to get the result
2173 in TARGET, if convenient (and in mode MODE if that's convenient). */
2175 static rtx
2176 expand_builtin_strpbrk (arglist, target, mode)
2177 tree arglist;
2178 rtx target;
2179 enum machine_mode mode;
2181 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2182 return 0;
2183 else
2185 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2186 tree fn;
2187 const char *p1, *p2;
2189 p2 = c_getstr (s2);
2190 if (p2 == NULL)
2191 return 0;
2193 p1 = c_getstr (s1);
2194 if (p1 != NULL)
2196 const char *r = strpbrk (p1, p2);
2198 if (r == NULL)
2199 return const0_rtx;
2201 /* Return an offset into the constant string argument. */
2202 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2203 s1, ssize_int (r - p1))),
2204 target, mode, EXPAND_NORMAL);
2207 if (p2[0] == '\0')
2209 /* strpbrk(x, "") == NULL.
2210 Evaluate and ignore the arguments in case they had
2211 side-effects. */
2212 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2213 return const0_rtx;
2216 if (p2[1] != '\0')
2217 return 0; /* Really call strpbrk. */
2219 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2220 if (!fn)
2221 return 0;
2223 /* New argument list transforming strpbrk(s1, s2) to
2224 strchr(s1, s2[0]). */
2225 arglist =
2226 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2227 arglist = tree_cons (NULL_TREE, s1, arglist);
2228 return expand_expr (build_function_call_expr (fn, arglist),
2229 target, mode, EXPAND_NORMAL);
2233 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2234 bytes from constant string DATA + OFFSET and return it as target
2235 constant. */
2237 static rtx
2238 builtin_memcpy_read_str (data, offset, mode)
2239 PTR data;
2240 HOST_WIDE_INT offset;
2241 enum machine_mode mode;
2243 const char *str = (const char *) data;
2245 if (offset < 0
2246 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2247 > strlen (str) + 1))
2248 abort (); /* Attempt to read past the end of constant string. */
2250 return c_readstr (str + offset, mode);
2253 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2254 Return 0 if we failed, the caller should emit a normal call, otherwise
2255 try to get the result in TARGET, if convenient (and in mode MODE if
2256 that's convenient). */
2258 static rtx
2259 expand_builtin_memcpy (arglist, target, mode)
2260 tree arglist;
2261 rtx target;
2262 enum machine_mode mode;
2264 if (!validate_arglist (arglist,
2265 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2266 return 0;
2267 else
2269 tree dest = TREE_VALUE (arglist);
2270 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2271 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2272 const char *src_str;
2274 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2275 unsigned int dest_align
2276 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2277 rtx dest_mem, src_mem, dest_addr, len_rtx;
2279 /* If DEST is not a pointer type, call the normal function. */
2280 if (dest_align == 0)
2281 return 0;
2283 /* If the LEN parameter is zero, return DEST. */
2284 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2286 /* Evaluate and ignore SRC in case it has side-effects. */
2287 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2288 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2291 /* If either SRC is not a pointer type, don't do this
2292 operation in-line. */
2293 if (src_align == 0)
2294 return 0;
2296 dest_mem = get_memory_rtx (dest);
2297 set_mem_align (dest_mem, dest_align);
2298 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2299 src_str = c_getstr (src);
2301 /* If SRC is a string constant and block move would be done
2302 by pieces, we can avoid loading the string from memory
2303 and only stored the computed constants. */
2304 if (src_str
2305 && GET_CODE (len_rtx) == CONST_INT
2306 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2307 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2308 (PTR) src_str, dest_align))
2310 store_by_pieces (dest_mem, INTVAL (len_rtx),
2311 builtin_memcpy_read_str,
2312 (PTR) src_str, dest_align);
2313 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2314 #ifdef POINTERS_EXTEND_UNSIGNED
2315 if (GET_MODE (dest_mem) != ptr_mode)
2316 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2317 #endif
2318 return dest_mem;
2321 src_mem = get_memory_rtx (src);
2322 set_mem_align (src_mem, src_align);
2324 /* Copy word part most expediently. */
2325 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2326 BLOCK_OP_NORMAL);
2328 if (dest_addr == 0)
2330 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2331 #ifdef POINTERS_EXTEND_UNSIGNED
2332 if (GET_MODE (dest_addr) != ptr_mode)
2333 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2334 #endif
2337 return dest_addr;
2341 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2342 if we failed the caller should emit a normal call, otherwise try to get
2343 the result in TARGET, if convenient (and in mode MODE if that's
2344 convenient). */
2346 static rtx
2347 expand_builtin_strcpy (exp, target, mode)
2348 tree exp;
2349 rtx target;
2350 enum machine_mode mode;
2352 tree arglist = TREE_OPERAND (exp, 1);
2353 tree fn, len;
2355 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2356 return 0;
2358 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2359 if (!fn)
2360 return 0;
2362 len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2363 if (len == 0)
2364 return 0;
2366 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2367 chainon (arglist, build_tree_list (NULL_TREE, len));
2368 return expand_expr (build_function_call_expr (fn, arglist),
2369 target, mode, EXPAND_NORMAL);
2372 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2373 bytes from constant string DATA + OFFSET and return it as target
2374 constant. */
2376 static rtx
2377 builtin_strncpy_read_str (data, offset, mode)
2378 PTR data;
2379 HOST_WIDE_INT offset;
2380 enum machine_mode mode;
2382 const char *str = (const char *) data;
2384 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2385 return const0_rtx;
2387 return c_readstr (str + offset, mode);
2390 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2391 if we failed the caller should emit a normal call. */
2393 static rtx
2394 expand_builtin_strncpy (arglist, target, mode)
2395 tree arglist;
2396 rtx target;
2397 enum machine_mode mode;
2399 if (!validate_arglist (arglist,
2400 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2401 return 0;
2402 else
2404 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2405 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2406 tree fn;
2408 /* We must be passed a constant len parameter. */
2409 if (TREE_CODE (len) != INTEGER_CST)
2410 return 0;
2412 /* If the len parameter is zero, return the dst parameter. */
2413 if (integer_zerop (len))
2415 /* Evaluate and ignore the src argument in case it has
2416 side-effects. */
2417 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2418 VOIDmode, EXPAND_NORMAL);
2419 /* Return the dst parameter. */
2420 return expand_expr (TREE_VALUE (arglist), target, mode,
2421 EXPAND_NORMAL);
2424 /* Now, we must be passed a constant src ptr parameter. */
2425 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2426 return 0;
2428 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2430 /* We're required to pad with trailing zeros if the requested
2431 len is greater than strlen(s2)+1. In that case try to
2432 use store_by_pieces, if it fails, punt. */
2433 if (tree_int_cst_lt (slen, len))
2435 tree dest = TREE_VALUE (arglist);
2436 unsigned int dest_align
2437 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2438 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2439 rtx dest_mem;
2441 if (!p || dest_align == 0 || !host_integerp (len, 1)
2442 || !can_store_by_pieces (tree_low_cst (len, 1),
2443 builtin_strncpy_read_str,
2444 (PTR) p, dest_align))
2445 return 0;
2447 dest_mem = get_memory_rtx (dest);
2448 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2449 builtin_strncpy_read_str,
2450 (PTR) p, dest_align);
2451 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2452 #ifdef POINTERS_EXTEND_UNSIGNED
2453 if (GET_MODE (dest_mem) != ptr_mode)
2454 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2455 #endif
2456 return dest_mem;
2459 /* OK transform into builtin memcpy. */
2460 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2461 if (!fn)
2462 return 0;
2463 return expand_expr (build_function_call_expr (fn, arglist),
2464 target, mode, EXPAND_NORMAL);
2468 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2469 bytes from constant string DATA + OFFSET and return it as target
2470 constant. */
2472 static rtx
2473 builtin_memset_read_str (data, offset, mode)
2474 PTR data;
2475 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2476 enum machine_mode mode;
2478 const char *c = (const char *) data;
2479 char *p = alloca (GET_MODE_SIZE (mode));
2481 memset (p, *c, GET_MODE_SIZE (mode));
2483 return c_readstr (p, mode);
2486 /* Callback routine for store_by_pieces. Return the RTL of a register
2487 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2488 char value given in the RTL register data. For example, if mode is
2489 4 bytes wide, return the RTL for 0x01010101*data. */
2491 static rtx
2492 builtin_memset_gen_str (data, offset, mode)
2493 PTR data;
2494 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2495 enum machine_mode mode;
2497 rtx target, coeff;
2498 size_t size;
2499 char *p;
2501 size = GET_MODE_SIZE (mode);
2502 if (size == 1)
2503 return (rtx) data;
2505 p = alloca (size);
2506 memset (p, 1, size);
2507 coeff = c_readstr (p, mode);
2509 target = convert_to_mode (mode, (rtx) data, 1);
2510 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2511 return force_reg (mode, target);
2514 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2515 if we failed the caller should emit a normal call, otherwise try to get
2516 the result in TARGET, if convenient (and in mode MODE if that's
2517 convenient). */
2519 static rtx
2520 expand_builtin_memset (exp, target, mode)
2521 tree exp;
2522 rtx target;
2523 enum machine_mode mode;
2525 tree arglist = TREE_OPERAND (exp, 1);
2527 if (!validate_arglist (arglist,
2528 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2529 return 0;
2530 else
2532 tree dest = TREE_VALUE (arglist);
2533 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2534 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2535 char c;
2537 unsigned int dest_align
2538 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2539 rtx dest_mem, dest_addr, len_rtx;
2541 /* If DEST is not a pointer type, don't do this
2542 operation in-line. */
2543 if (dest_align == 0)
2544 return 0;
2546 /* If the LEN parameter is zero, return DEST. */
2547 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2549 /* Evaluate and ignore VAL in case it has side-effects. */
2550 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2551 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2554 if (TREE_CODE (val) != INTEGER_CST)
2556 rtx val_rtx;
2558 if (!host_integerp (len, 1))
2559 return 0;
2561 if (optimize_size && tree_low_cst (len, 1) > 1)
2562 return 0;
2564 /* Assume that we can memset by pieces if we can store the
2565 * the coefficients by pieces (in the required modes).
2566 * We can't pass builtin_memset_gen_str as that emits RTL. */
2567 c = 1;
2568 if (!can_store_by_pieces (tree_low_cst (len, 1),
2569 builtin_memset_read_str,
2570 (PTR) &c, dest_align))
2571 return 0;
2573 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
2574 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
2575 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
2576 val_rtx);
2577 dest_mem = get_memory_rtx (dest);
2578 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2579 builtin_memset_gen_str,
2580 (PTR) val_rtx, dest_align);
2581 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2582 #ifdef POINTERS_EXTEND_UNSIGNED
2583 if (GET_MODE (dest_mem) != ptr_mode)
2584 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2585 #endif
2586 return dest_mem;
2589 if (target_char_cast (val, &c))
2590 return 0;
2592 if (c)
2594 if (!host_integerp (len, 1))
2595 return 0;
2596 if (!can_store_by_pieces (tree_low_cst (len, 1),
2597 builtin_memset_read_str, (PTR) &c,
2598 dest_align))
2599 return 0;
2601 dest_mem = get_memory_rtx (dest);
2602 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2603 builtin_memset_read_str,
2604 (PTR) &c, dest_align);
2605 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2606 #ifdef POINTERS_EXTEND_UNSIGNED
2607 if (GET_MODE (dest_mem) != ptr_mode)
2608 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2609 #endif
2610 return dest_mem;
2613 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2615 dest_mem = get_memory_rtx (dest);
2616 set_mem_align (dest_mem, dest_align);
2617 dest_addr = clear_storage (dest_mem, len_rtx);
2619 if (dest_addr == 0)
2621 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2622 #ifdef POINTERS_EXTEND_UNSIGNED
2623 if (GET_MODE (dest_addr) != ptr_mode)
2624 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2625 #endif
2628 return dest_addr;
2632 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2633 if we failed the caller should emit a normal call. */
2635 static rtx
2636 expand_builtin_bzero (exp)
2637 tree exp;
2639 tree arglist = TREE_OPERAND (exp, 1);
2640 tree dest, size, newarglist;
2641 rtx result;
2643 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2644 return NULL_RTX;
2646 dest = TREE_VALUE (arglist);
2647 size = TREE_VALUE (TREE_CHAIN (arglist));
2649 /* New argument list transforming bzero(ptr x, int y) to
2650 memset(ptr x, int 0, size_t y). This is done this way
2651 so that if it isn't expanded inline, we fallback to
2652 calling bzero instead of memset. */
2654 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2655 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2656 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2658 TREE_OPERAND (exp, 1) = newarglist;
2659 result = expand_builtin_memset (exp, const0_rtx, VOIDmode);
2661 /* Always restore the original arguments. */
2662 TREE_OPERAND (exp, 1) = arglist;
2664 return result;
2667 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2668 ARGLIST is the argument list for this call. Return 0 if we failed and the
2669 caller should emit a normal call, otherwise try to get the result in
2670 TARGET, if convenient (and in mode MODE, if that's convenient). */
2672 static rtx
2673 expand_builtin_memcmp (exp, arglist, target, mode)
2674 tree exp ATTRIBUTE_UNUSED;
2675 tree arglist;
2676 rtx target;
2677 enum machine_mode mode;
2679 tree arg1, arg2, len;
2680 const char *p1, *p2;
2682 if (!validate_arglist (arglist,
2683 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2684 return 0;
2686 arg1 = TREE_VALUE (arglist);
2687 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2688 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2690 /* If the len parameter is zero, return zero. */
2691 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2693 /* Evaluate and ignore arg1 and arg2 in case they have
2694 side-effects. */
2695 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2696 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2697 return const0_rtx;
2700 p1 = c_getstr (arg1);
2701 p2 = c_getstr (arg2);
2703 /* If all arguments are constant, and the value of len is not greater
2704 than the lengths of arg1 and arg2, evaluate at compile-time. */
2705 if (host_integerp (len, 1) && p1 && p2
2706 && compare_tree_int (len, strlen (p1) + 1) <= 0
2707 && compare_tree_int (len, strlen (p2) + 1) <= 0)
2709 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
2711 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2714 /* If len parameter is one, return an expression corresponding to
2715 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2716 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
2718 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2719 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2720 tree ind1 =
2721 fold (build1 (CONVERT_EXPR, integer_type_node,
2722 build1 (INDIRECT_REF, cst_uchar_node,
2723 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2724 tree ind2 =
2725 fold (build1 (CONVERT_EXPR, integer_type_node,
2726 build1 (INDIRECT_REF, cst_uchar_node,
2727 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2728 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2729 return expand_expr (result, target, mode, EXPAND_NORMAL);
2732 #ifdef HAVE_cmpstrsi
2734 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2735 rtx result;
2736 rtx insn;
2738 int arg1_align
2739 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2740 int arg2_align
2741 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2742 enum machine_mode insn_mode
2743 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2745 /* If we don't have POINTER_TYPE, call the function. */
2746 if (arg1_align == 0 || arg2_align == 0)
2747 return 0;
2749 /* Make a place to write the result of the instruction. */
2750 result = target;
2751 if (! (result != 0
2752 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2753 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2754 result = gen_reg_rtx (insn_mode);
2756 arg1_rtx = get_memory_rtx (arg1);
2757 arg2_rtx = get_memory_rtx (arg2);
2758 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2759 if (!HAVE_cmpstrsi)
2760 insn = NULL_RTX;
2761 else
2762 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2763 GEN_INT (MIN (arg1_align, arg2_align)));
2765 if (insn)
2766 emit_insn (insn);
2767 else
2768 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2769 TYPE_MODE (integer_type_node), 3,
2770 XEXP (arg1_rtx, 0), Pmode,
2771 XEXP (arg2_rtx, 0), Pmode,
2772 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2773 TREE_UNSIGNED (sizetype)),
2774 TYPE_MODE (sizetype));
2776 /* Return the value in the proper mode for this function. */
2777 mode = TYPE_MODE (TREE_TYPE (exp));
2778 if (GET_MODE (result) == mode)
2779 return result;
2780 else if (target != 0)
2782 convert_move (target, result, 0);
2783 return target;
2785 else
2786 return convert_to_mode (mode, result, 0);
2788 #endif
2790 return 0;
2793 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2794 if we failed the caller should emit a normal call, otherwise try to get
2795 the result in TARGET, if convenient. */
2797 static rtx
2798 expand_builtin_strcmp (exp, target, mode)
2799 tree exp;
2800 rtx target;
2801 enum machine_mode mode;
2803 tree arglist = TREE_OPERAND (exp, 1);
2804 tree arg1, arg2, len, len2, fn;
2805 const char *p1, *p2;
2807 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2808 return 0;
2810 arg1 = TREE_VALUE (arglist);
2811 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2813 p1 = c_getstr (arg1);
2814 p2 = c_getstr (arg2);
2816 if (p1 && p2)
2818 const int i = strcmp (p1, p2);
2819 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2822 /* If either arg is "", return an expression corresponding to
2823 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2824 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2826 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2827 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2828 tree ind1 =
2829 fold (build1 (CONVERT_EXPR, integer_type_node,
2830 build1 (INDIRECT_REF, cst_uchar_node,
2831 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2832 tree ind2 =
2833 fold (build1 (CONVERT_EXPR, integer_type_node,
2834 build1 (INDIRECT_REF, cst_uchar_node,
2835 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2836 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2837 return expand_expr (result, target, mode, EXPAND_NORMAL);
2840 len = c_strlen (arg1);
2841 len2 = c_strlen (arg2);
2843 if (len)
2844 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2846 if (len2)
2847 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2849 /* If we don't have a constant length for the first, use the length
2850 of the second, if we know it. We don't require a constant for
2851 this case; some cost analysis could be done if both are available
2852 but neither is constant. For now, assume they're equally cheap
2853 unless one has side effects.
2855 If both strings have constant lengths, use the smaller. This
2856 could arise if optimization results in strcpy being called with
2857 two fixed strings, or if the code was machine-generated. We should
2858 add some code to the `memcmp' handler below to deal with such
2859 situations, someday. */
2861 if (!len || TREE_CODE (len) != INTEGER_CST)
2863 if (len2 && !TREE_SIDE_EFFECTS (len2))
2864 len = len2;
2865 else if (len == 0)
2866 return 0;
2868 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2869 && tree_int_cst_lt (len2, len))
2870 len = len2;
2872 /* If both arguments have side effects, we cannot optimize. */
2873 if (TREE_SIDE_EFFECTS (len))
2874 return 0;
2876 fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2877 if (!fn)
2878 return 0;
2880 chainon (arglist, build_tree_list (NULL_TREE, len));
2881 return expand_expr (build_function_call_expr (fn, arglist),
2882 target, mode, EXPAND_NORMAL);
2885 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2886 if we failed the caller should emit a normal call, otherwise try to get
2887 the result in TARGET, if convenient. */
2889 static rtx
2890 expand_builtin_strncmp (exp, target, mode)
2891 tree exp;
2892 rtx target;
2893 enum machine_mode mode;
2895 tree arglist = TREE_OPERAND (exp, 1);
2896 tree fn, newarglist, len = 0;
2897 tree arg1, arg2, arg3;
2898 const char *p1, *p2;
2900 if (!validate_arglist (arglist,
2901 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2902 return 0;
2904 arg1 = TREE_VALUE (arglist);
2905 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2906 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2908 /* If the len parameter is zero, return zero. */
2909 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2911 /* Evaluate and ignore arg1 and arg2 in case they have
2912 side-effects. */
2913 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2914 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2915 return const0_rtx;
2918 p1 = c_getstr (arg1);
2919 p2 = c_getstr (arg2);
2921 /* If all arguments are constant, evaluate at compile-time. */
2922 if (host_integerp (arg3, 1) && p1 && p2)
2924 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2925 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2928 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2929 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2930 if (host_integerp (arg3, 1)
2931 && (tree_low_cst (arg3, 1) == 1
2932 || (tree_low_cst (arg3, 1) > 1
2933 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2935 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2936 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2937 tree ind1 =
2938 fold (build1 (CONVERT_EXPR, integer_type_node,
2939 build1 (INDIRECT_REF, cst_uchar_node,
2940 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2941 tree ind2 =
2942 fold (build1 (CONVERT_EXPR, integer_type_node,
2943 build1 (INDIRECT_REF, cst_uchar_node,
2944 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2945 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2946 return expand_expr (result, target, mode, EXPAND_NORMAL);
2949 /* If c_strlen can determine an expression for one of the string
2950 lengths, and it doesn't have side effects, then call
2951 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
2953 /* Perhaps one of the strings is really constant, if so prefer
2954 that constant length over the other string's length. */
2955 if (p1)
2956 len = c_strlen (arg1);
2957 else if (p2)
2958 len = c_strlen (arg2);
2960 /* If we still don't have a len, try either string arg as long
2961 as they don't have side effects. */
2962 if (!len && !TREE_SIDE_EFFECTS (arg1))
2963 len = c_strlen (arg1);
2964 if (!len && !TREE_SIDE_EFFECTS (arg2))
2965 len = c_strlen (arg2);
2966 /* If we still don't have a length, punt. */
2967 if (!len)
2968 return 0;
2970 fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2971 if (!fn)
2972 return 0;
2974 /* Add one to the string length. */
2975 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2977 /* The actual new length parameter is MIN(len,arg3). */
2978 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2980 newarglist = build_tree_list (NULL_TREE, len);
2981 newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2982 newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2983 return expand_expr (build_function_call_expr (fn, newarglist),
2984 target, mode, EXPAND_NORMAL);
2987 /* Expand expression EXP, which is a call to the strcat builtin.
2988 Return 0 if we failed the caller should emit a normal call,
2989 otherwise try to get the result in TARGET, if convenient. */
2991 static rtx
2992 expand_builtin_strcat (arglist, target, mode)
2993 tree arglist;
2994 rtx target;
2995 enum machine_mode mode;
2997 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2998 return 0;
2999 else
3001 tree dst = TREE_VALUE (arglist),
3002 src = TREE_VALUE (TREE_CHAIN (arglist));
3003 const char *p = c_getstr (src);
3005 /* If the string length is zero, return the dst parameter. */
3006 if (p && *p == '\0')
3007 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3009 return 0;
3013 /* Expand expression EXP, which is a call to the strncat builtin.
3014 Return 0 if we failed the caller should emit a normal call,
3015 otherwise try to get the result in TARGET, if convenient. */
3017 static rtx
3018 expand_builtin_strncat (arglist, target, mode)
3019 tree arglist;
3020 rtx target;
3021 enum machine_mode mode;
3023 if (!validate_arglist (arglist,
3024 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3025 return 0;
3026 else
3028 tree dst = TREE_VALUE (arglist),
3029 src = TREE_VALUE (TREE_CHAIN (arglist)),
3030 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3031 const char *p = c_getstr (src);
3033 /* If the requested length is zero, or the src parameter string
3034 length is zero, return the dst parameter. */
3035 if (integer_zerop (len) || (p && *p == '\0'))
3037 /* Evaluate and ignore the src and len parameters in case
3038 they have side-effects. */
3039 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3040 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3041 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3044 /* If the requested len is greater than or equal to the string
3045 length, call strcat. */
3046 if (TREE_CODE (len) == INTEGER_CST && p
3047 && compare_tree_int (len, strlen (p)) >= 0)
3049 tree newarglist
3050 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3051 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3053 /* If the replacement _DECL isn't initialized, don't do the
3054 transformation. */
3055 if (!fn)
3056 return 0;
3058 return expand_expr (build_function_call_expr (fn, newarglist),
3059 target, mode, EXPAND_NORMAL);
3061 return 0;
3065 /* Expand expression EXP, which is a call to the strspn builtin.
3066 Return 0 if we failed the caller should emit a normal call,
3067 otherwise try to get the result in TARGET, if convenient. */
3069 static rtx
3070 expand_builtin_strspn (arglist, target, mode)
3071 tree arglist;
3072 rtx target;
3073 enum machine_mode mode;
3075 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3076 return 0;
3077 else
3079 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3080 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3082 /* If both arguments are constants, evaluate at compile-time. */
3083 if (p1 && p2)
3085 const size_t r = strspn (p1, p2);
3086 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3089 /* If either argument is "", return 0. */
3090 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3092 /* Evaluate and ignore both arguments in case either one has
3093 side-effects. */
3094 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3095 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3096 return const0_rtx;
3098 return 0;
3102 /* Expand expression EXP, which is a call to the strcspn builtin.
3103 Return 0 if we failed the caller should emit a normal call,
3104 otherwise try to get the result in TARGET, if convenient. */
3106 static rtx
3107 expand_builtin_strcspn (arglist, target, mode)
3108 tree arglist;
3109 rtx target;
3110 enum machine_mode mode;
3112 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3113 return 0;
3114 else
3116 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3117 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3119 /* If both arguments are constants, evaluate at compile-time. */
3120 if (p1 && p2)
3122 const size_t r = strcspn (p1, p2);
3123 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3126 /* If the first argument is "", return 0. */
3127 if (p1 && *p1 == '\0')
3129 /* Evaluate and ignore argument s2 in case it has
3130 side-effects. */
3131 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3132 return const0_rtx;
3135 /* If the second argument is "", return __builtin_strlen(s1). */
3136 if (p2 && *p2 == '\0')
3138 tree newarglist = build_tree_list (NULL_TREE, s1),
3139 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3141 /* If the replacement _DECL isn't initialized, don't do the
3142 transformation. */
3143 if (!fn)
3144 return 0;
3146 return expand_expr (build_function_call_expr (fn, newarglist),
3147 target, mode, EXPAND_NORMAL);
3149 return 0;
3153 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3154 if that's convenient. */
3157 expand_builtin_saveregs ()
3159 rtx val, seq;
3161 /* Don't do __builtin_saveregs more than once in a function.
3162 Save the result of the first call and reuse it. */
3163 if (saveregs_value != 0)
3164 return saveregs_value;
3166 /* When this function is called, it means that registers must be
3167 saved on entry to this function. So we migrate the call to the
3168 first insn of this function. */
3170 start_sequence ();
3172 #ifdef EXPAND_BUILTIN_SAVEREGS
3173 /* Do whatever the machine needs done in this case. */
3174 val = EXPAND_BUILTIN_SAVEREGS ();
3175 #else
3176 /* ??? We used to try and build up a call to the out of line function,
3177 guessing about what registers needed saving etc. This became much
3178 harder with __builtin_va_start, since we don't have a tree for a
3179 call to __builtin_saveregs to fall back on. There was exactly one
3180 port (i860) that used this code, and I'm unconvinced it could actually
3181 handle the general case. So we no longer try to handle anything
3182 weird and make the backend absorb the evil. */
3184 error ("__builtin_saveregs not supported by this target");
3185 val = const0_rtx;
3186 #endif
3188 seq = get_insns ();
3189 end_sequence ();
3191 saveregs_value = val;
3193 /* Put the insns after the NOTE that starts the function. If this
3194 is inside a start_sequence, make the outer-level insn chain current, so
3195 the code is placed at the start of the function. */
3196 push_topmost_sequence ();
3197 emit_insn_after (seq, get_insns ());
3198 pop_topmost_sequence ();
3200 return val;
3203 /* __builtin_args_info (N) returns word N of the arg space info
3204 for the current function. The number and meanings of words
3205 is controlled by the definition of CUMULATIVE_ARGS. */
3207 static rtx
3208 expand_builtin_args_info (exp)
3209 tree exp;
3211 tree arglist = TREE_OPERAND (exp, 1);
3212 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3213 int *word_ptr = (int *) &current_function_args_info;
3214 #if 0
3215 /* These are used by the code below that is if 0'ed away */
3216 int i;
3217 tree type, elts, result;
3218 #endif
3220 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3221 abort ();
3223 if (arglist != 0)
3225 if (!host_integerp (TREE_VALUE (arglist), 0))
3226 error ("argument of `__builtin_args_info' must be constant");
3227 else
3229 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3231 if (wordnum < 0 || wordnum >= nwords)
3232 error ("argument of `__builtin_args_info' out of range");
3233 else
3234 return GEN_INT (word_ptr[wordnum]);
3237 else
3238 error ("missing argument in `__builtin_args_info'");
3240 return const0_rtx;
3242 #if 0
3243 for (i = 0; i < nwords; i++)
3244 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
3246 type = build_array_type (integer_type_node,
3247 build_index_type (build_int_2 (nwords, 0)));
3248 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
3249 TREE_CONSTANT (result) = 1;
3250 TREE_STATIC (result) = 1;
3251 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
3252 TREE_CONSTANT (result) = 1;
3253 return expand_expr (result, NULL_RTX, VOIDmode, 0);
3254 #endif
3257 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3259 static rtx
3260 expand_builtin_next_arg (arglist)
3261 tree arglist;
3263 tree fntype = TREE_TYPE (current_function_decl);
3265 if (TYPE_ARG_TYPES (fntype) == 0
3266 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3267 == void_type_node))
3269 error ("`va_start' used in function with fixed args");
3270 return const0_rtx;
3273 if (arglist)
3275 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3276 tree arg = TREE_VALUE (arglist);
3278 /* Strip off all nops for the sake of the comparison. This
3279 is not quite the same as STRIP_NOPS. It does more.
3280 We must also strip off INDIRECT_EXPR for C++ reference
3281 parameters. */
3282 while (TREE_CODE (arg) == NOP_EXPR
3283 || TREE_CODE (arg) == CONVERT_EXPR
3284 || TREE_CODE (arg) == NON_LVALUE_EXPR
3285 || TREE_CODE (arg) == INDIRECT_REF)
3286 arg = TREE_OPERAND (arg, 0);
3287 if (arg != last_parm)
3288 warning ("second parameter of `va_start' not last named argument");
3290 else
3291 /* Evidently an out of date version of <stdarg.h>; can't validate
3292 va_start's second argument, but can still work as intended. */
3293 warning ("`__builtin_next_arg' called without an argument");
3295 return expand_binop (Pmode, add_optab,
3296 current_function_internal_arg_pointer,
3297 current_function_arg_offset_rtx,
3298 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3301 /* Make it easier for the backends by protecting the valist argument
3302 from multiple evaluations. */
3304 static tree
3305 stabilize_va_list (valist, needs_lvalue)
3306 tree valist;
3307 int needs_lvalue;
3309 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3311 if (TREE_SIDE_EFFECTS (valist))
3312 valist = save_expr (valist);
3314 /* For this case, the backends will be expecting a pointer to
3315 TREE_TYPE (va_list_type_node), but it's possible we've
3316 actually been given an array (an actual va_list_type_node).
3317 So fix it. */
3318 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3320 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3321 tree p2 = build_pointer_type (va_list_type_node);
3323 valist = build1 (ADDR_EXPR, p2, valist);
3324 valist = fold (build1 (NOP_EXPR, p1, valist));
3327 else
3329 tree pt;
3331 if (! needs_lvalue)
3333 if (! TREE_SIDE_EFFECTS (valist))
3334 return valist;
3336 pt = build_pointer_type (va_list_type_node);
3337 valist = fold (build1 (ADDR_EXPR, pt, valist));
3338 TREE_SIDE_EFFECTS (valist) = 1;
3341 if (TREE_SIDE_EFFECTS (valist))
3342 valist = save_expr (valist);
3343 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3344 valist));
3347 return valist;
3350 /* The "standard" implementation of va_start: just assign `nextarg' to
3351 the variable. */
3353 void
3354 std_expand_builtin_va_start (valist, nextarg)
3355 tree valist;
3356 rtx nextarg;
3358 tree t;
3360 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3361 make_tree (ptr_type_node, nextarg));
3362 TREE_SIDE_EFFECTS (t) = 1;
3364 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3367 /* Expand ARGLIST, from a call to __builtin_va_start. */
3369 static rtx
3370 expand_builtin_va_start (arglist)
3371 tree arglist;
3373 rtx nextarg;
3374 tree chain, valist;
3376 chain = TREE_CHAIN (arglist);
3378 if (TREE_CHAIN (chain))
3379 error ("too many arguments to function `va_start'");
3381 nextarg = expand_builtin_next_arg (chain);
3382 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3384 #ifdef EXPAND_BUILTIN_VA_START
3385 EXPAND_BUILTIN_VA_START (valist, nextarg);
3386 #else
3387 std_expand_builtin_va_start (valist, nextarg);
3388 #endif
3390 return const0_rtx;
3393 /* The "standard" implementation of va_arg: read the value from the
3394 current (padded) address and increment by the (padded) size. */
3397 std_expand_builtin_va_arg (valist, type)
3398 tree valist, type;
3400 tree addr_tree, t, type_size = NULL;
3401 tree align, alignm1;
3402 tree rounded_size;
3403 rtx addr;
3405 /* Compute the rounded size of the type. */
3406 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3407 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3408 if (type == error_mark_node
3409 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3410 || TREE_OVERFLOW (type_size))
3411 rounded_size = size_zero_node;
3412 else
3413 rounded_size = fold (build (MULT_EXPR, sizetype,
3414 fold (build (TRUNC_DIV_EXPR, sizetype,
3415 fold (build (PLUS_EXPR, sizetype,
3416 type_size, alignm1)),
3417 align)),
3418 align));
3420 /* Get AP. */
3421 addr_tree = valist;
3422 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3424 /* Small args are padded downward. */
3425 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3426 fold (build (COND_EXPR, sizetype,
3427 fold (build (GT_EXPR, sizetype,
3428 rounded_size,
3429 align)),
3430 size_zero_node,
3431 fold (build (MINUS_EXPR, sizetype,
3432 rounded_size,
3433 type_size))))));
3436 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3437 addr = copy_to_reg (addr);
3439 /* Compute new value for AP. */
3440 if (! integer_zerop (rounded_size))
3442 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3443 build (PLUS_EXPR, TREE_TYPE (valist), valist,
3444 rounded_size));
3445 TREE_SIDE_EFFECTS (t) = 1;
3446 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3449 return addr;
3452 /* Expand __builtin_va_arg, which is not really a builtin function, but
3453 a very special sort of operator. */
3456 expand_builtin_va_arg (valist, type)
3457 tree valist, type;
3459 rtx addr, result;
3460 tree promoted_type, want_va_type, have_va_type;
3462 /* Verify that valist is of the proper type. */
3464 want_va_type = va_list_type_node;
3465 have_va_type = TREE_TYPE (valist);
3466 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3468 /* If va_list is an array type, the argument may have decayed
3469 to a pointer type, e.g. by being passed to another function.
3470 In that case, unwrap both types so that we can compare the
3471 underlying records. */
3472 if (TREE_CODE (have_va_type) == ARRAY_TYPE
3473 || TREE_CODE (have_va_type) == POINTER_TYPE)
3475 want_va_type = TREE_TYPE (want_va_type);
3476 have_va_type = TREE_TYPE (have_va_type);
3479 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3481 error ("first argument to `va_arg' not of type `va_list'");
3482 addr = const0_rtx;
3485 /* Generate a diagnostic for requesting data of a type that cannot
3486 be passed through `...' due to type promotion at the call site. */
3487 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3488 != type)
3490 const char *name = "<anonymous type>", *pname = 0;
3491 static bool gave_help;
3493 if (TYPE_NAME (type))
3495 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3496 name = IDENTIFIER_POINTER (TYPE_NAME (type));
3497 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3498 && DECL_NAME (TYPE_NAME (type)))
3499 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3501 if (TYPE_NAME (promoted_type))
3503 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3504 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3505 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3506 && DECL_NAME (TYPE_NAME (promoted_type)))
3507 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3510 /* Unfortunately, this is merely undefined, rather than a constraint
3511 violation, so we cannot make this an error. If this call is never
3512 executed, the program is still strictly conforming. */
3513 warning ("`%s' is promoted to `%s' when passed through `...'",
3514 name, pname);
3515 if (! gave_help)
3517 gave_help = true;
3518 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3519 pname, name);
3522 /* We can, however, treat "undefined" any way we please.
3523 Call abort to encourage the user to fix the program. */
3524 expand_builtin_trap ();
3526 /* This is dead code, but go ahead and finish so that the
3527 mode of the result comes out right. */
3528 addr = const0_rtx;
3530 else
3532 /* Make it easier for the backends by protecting the valist argument
3533 from multiple evaluations. */
3534 valist = stabilize_va_list (valist, 0);
3536 #ifdef EXPAND_BUILTIN_VA_ARG
3537 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
3538 #else
3539 addr = std_expand_builtin_va_arg (valist, type);
3540 #endif
3543 #ifdef POINTERS_EXTEND_UNSIGNED
3544 if (GET_MODE (addr) != Pmode)
3545 addr = convert_memory_address (Pmode, addr);
3546 #endif
3548 result = gen_rtx_MEM (TYPE_MODE (type), addr);
3549 set_mem_alias_set (result, get_varargs_alias_set ());
3551 return result;
3554 /* Expand ARGLIST, from a call to __builtin_va_end. */
3556 static rtx
3557 expand_builtin_va_end (arglist)
3558 tree arglist;
3560 tree valist = TREE_VALUE (arglist);
3562 #ifdef EXPAND_BUILTIN_VA_END
3563 valist = stabilize_va_list (valist, 0);
3564 EXPAND_BUILTIN_VA_END (arglist);
3565 #else
3566 /* Evaluate for side effects, if needed. I hate macros that don't
3567 do that. */
3568 if (TREE_SIDE_EFFECTS (valist))
3569 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
3570 #endif
3572 return const0_rtx;
3575 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3576 builtin rather than just as an assignment in stdarg.h because of the
3577 nastiness of array-type va_list types. */
3579 static rtx
3580 expand_builtin_va_copy (arglist)
3581 tree arglist;
3583 tree dst, src, t;
3585 dst = TREE_VALUE (arglist);
3586 src = TREE_VALUE (TREE_CHAIN (arglist));
3588 dst = stabilize_va_list (dst, 1);
3589 src = stabilize_va_list (src, 0);
3591 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3593 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3594 TREE_SIDE_EFFECTS (t) = 1;
3595 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3597 else
3599 rtx dstb, srcb, size;
3601 /* Evaluate to pointers. */
3602 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3603 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3604 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3605 VOIDmode, EXPAND_NORMAL);
3607 #ifdef POINTERS_EXTEND_UNSIGNED
3608 if (GET_MODE (dstb) != Pmode)
3609 dstb = convert_memory_address (Pmode, dstb);
3611 if (GET_MODE (srcb) != Pmode)
3612 srcb = convert_memory_address (Pmode, srcb);
3613 #endif
3615 /* "Dereference" to BLKmode memories. */
3616 dstb = gen_rtx_MEM (BLKmode, dstb);
3617 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3618 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
3619 srcb = gen_rtx_MEM (BLKmode, srcb);
3620 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3621 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
3623 /* Copy. */
3624 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
3627 return const0_rtx;
3630 /* Expand a call to one of the builtin functions __builtin_frame_address or
3631 __builtin_return_address. */
3633 static rtx
3634 expand_builtin_frame_address (exp)
3635 tree exp;
3637 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3638 tree arglist = TREE_OPERAND (exp, 1);
3640 /* The argument must be a nonnegative integer constant.
3641 It counts the number of frames to scan up the stack.
3642 The value is the return address saved in that frame. */
3643 if (arglist == 0)
3644 /* Warning about missing arg was already issued. */
3645 return const0_rtx;
3646 else if (! host_integerp (TREE_VALUE (arglist), 1))
3648 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3649 error ("invalid arg to `__builtin_frame_address'");
3650 else
3651 error ("invalid arg to `__builtin_return_address'");
3652 return const0_rtx;
3654 else
3656 rtx tem
3657 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3658 tree_low_cst (TREE_VALUE (arglist), 1),
3659 hard_frame_pointer_rtx);
3661 /* Some ports cannot access arbitrary stack frames. */
3662 if (tem == NULL)
3664 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3665 warning ("unsupported arg to `__builtin_frame_address'");
3666 else
3667 warning ("unsupported arg to `__builtin_return_address'");
3668 return const0_rtx;
3671 /* For __builtin_frame_address, return what we've got. */
3672 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3673 return tem;
3675 if (GET_CODE (tem) != REG
3676 && ! CONSTANT_P (tem))
3677 tem = copy_to_mode_reg (Pmode, tem);
3678 return tem;
3682 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3683 we failed and the caller should emit a normal call, otherwise try to get
3684 the result in TARGET, if convenient. */
3686 static rtx
3687 expand_builtin_alloca (arglist, target)
3688 tree arglist;
3689 rtx target;
3691 rtx op0;
3692 rtx result;
3694 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3695 return 0;
3697 /* Compute the argument. */
3698 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3700 /* Allocate the desired space. */
3701 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3703 #ifdef POINTERS_EXTEND_UNSIGNED
3704 if (GET_MODE (result) != ptr_mode)
3705 result = convert_memory_address (ptr_mode, result);
3706 #endif
3708 return result;
3711 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
3712 Return 0 if a normal call should be emitted rather than expanding the
3713 function in-line. If convenient, the result should be placed in TARGET.
3714 SUBTARGET may be used as the target for computing one of EXP's operands. */
3716 static rtx
3717 expand_builtin_unop (arglist, target, subtarget, op_optab)
3718 tree arglist;
3719 rtx target, subtarget;
3720 optab op_optab;
3722 rtx op0;
3723 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3724 return 0;
3726 /* Compute the argument. */
3727 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3728 /* Compute op, into TARGET if possible.
3729 Set TARGET to wherever the result comes back. */
3730 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3731 op_optab, op0, target, 1);
3732 if (target == 0)
3733 abort ();
3734 return target;
3737 /* If the string passed to fputs is a constant and is one character
3738 long, we attempt to transform this call into __builtin_fputc(). */
3740 static rtx
3741 expand_builtin_fputs (arglist, ignore, unlocked)
3742 tree arglist;
3743 int ignore;
3744 int unlocked;
3746 tree len, fn;
3747 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
3748 : implicit_built_in_decls[BUILT_IN_FPUTC];
3749 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
3750 : implicit_built_in_decls[BUILT_IN_FWRITE];
3752 /* If the return value is used, or the replacement _DECL isn't
3753 initialized, don't do the transformation. */
3754 if (!ignore || !fn_fputc || !fn_fwrite)
3755 return 0;
3757 /* Verify the arguments in the original call. */
3758 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3759 return 0;
3761 /* Get the length of the string passed to fputs. If the length
3762 can't be determined, punt. */
3763 if (!(len = c_strlen (TREE_VALUE (arglist)))
3764 || TREE_CODE (len) != INTEGER_CST)
3765 return 0;
3767 switch (compare_tree_int (len, 1))
3769 case -1: /* length is 0, delete the call entirely . */
3771 /* Evaluate and ignore the argument in case it has
3772 side-effects. */
3773 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3774 VOIDmode, EXPAND_NORMAL);
3775 return const0_rtx;
3777 case 0: /* length is 1, call fputc. */
3779 const char *p = c_getstr (TREE_VALUE (arglist));
3781 if (p != NULL)
3783 /* New argument list transforming fputs(string, stream) to
3784 fputc(string[0], stream). */
3785 arglist =
3786 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3787 arglist =
3788 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3789 fn = fn_fputc;
3790 break;
3793 /* FALLTHROUGH */
3794 case 1: /* length is greater than 1, call fwrite. */
3796 tree string_arg = TREE_VALUE (arglist);
3798 /* New argument list transforming fputs(string, stream) to
3799 fwrite(string, 1, len, stream). */
3800 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3801 arglist = tree_cons (NULL_TREE, len, arglist);
3802 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3803 arglist = tree_cons (NULL_TREE, string_arg, arglist);
3804 fn = fn_fwrite;
3805 break;
3807 default:
3808 abort ();
3811 return expand_expr (build_function_call_expr (fn, arglist),
3812 (ignore ? const0_rtx : NULL_RTX),
3813 VOIDmode, EXPAND_NORMAL);
3816 /* Expand a call to __builtin_expect. We return our argument and emit a
3817 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3818 a non-jump context. */
3820 static rtx
3821 expand_builtin_expect (arglist, target)
3822 tree arglist;
3823 rtx target;
3825 tree exp, c;
3826 rtx note, rtx_c;
3828 if (arglist == NULL_TREE
3829 || TREE_CHAIN (arglist) == NULL_TREE)
3830 return const0_rtx;
3831 exp = TREE_VALUE (arglist);
3832 c = TREE_VALUE (TREE_CHAIN (arglist));
3834 if (TREE_CODE (c) != INTEGER_CST)
3836 error ("second arg to `__builtin_expect' must be a constant");
3837 c = integer_zero_node;
3840 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3842 /* Don't bother with expected value notes for integral constants. */
3843 if (GET_CODE (target) != CONST_INT)
3845 /* We do need to force this into a register so that we can be
3846 moderately sure to be able to correctly interpret the branch
3847 condition later. */
3848 target = force_reg (GET_MODE (target), target);
3850 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3852 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3853 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3856 return target;
3859 /* Like expand_builtin_expect, except do this in a jump context. This is
3860 called from do_jump if the conditional is a __builtin_expect. Return either
3861 a list of insns to emit the jump or NULL if we cannot optimize
3862 __builtin_expect. We need to optimize this at jump time so that machines
3863 like the PowerPC don't turn the test into a SCC operation, and then jump
3864 based on the test being 0/1. */
3867 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3868 tree exp;
3869 rtx if_false_label;
3870 rtx if_true_label;
3872 tree arglist = TREE_OPERAND (exp, 1);
3873 tree arg0 = TREE_VALUE (arglist);
3874 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3875 rtx ret = NULL_RTX;
3877 /* Only handle __builtin_expect (test, 0) and
3878 __builtin_expect (test, 1). */
3879 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3880 && (integer_zerop (arg1) || integer_onep (arg1)))
3882 int num_jumps = 0;
3883 rtx insn;
3885 /* If we fail to locate an appropriate conditional jump, we'll
3886 fall back to normal evaluation. Ensure that the expression
3887 can be re-evaluated. */
3888 switch (unsafe_for_reeval (arg0))
3890 case 0: /* Safe. */
3891 break;
3893 case 1: /* Mildly unsafe. */
3894 arg0 = unsave_expr (arg0);
3895 break;
3897 case 2: /* Wildly unsafe. */
3898 return NULL_RTX;
3901 /* Expand the jump insns. */
3902 start_sequence ();
3903 do_jump (arg0, if_false_label, if_true_label);
3904 ret = get_insns ();
3905 end_sequence ();
3907 /* Now that the __builtin_expect has been validated, go through and add
3908 the expect's to each of the conditional jumps. If we run into an
3909 error, just give up and generate the 'safe' code of doing a SCC
3910 operation and then doing a branch on that. */
3911 insn = ret;
3912 while (insn != NULL_RTX)
3914 rtx next = NEXT_INSN (insn);
3915 rtx pattern;
3917 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3918 && (pattern = pc_set (insn)) != NULL_RTX)
3920 rtx ifelse = SET_SRC (pattern);
3921 rtx label;
3922 int taken;
3924 if (GET_CODE (ifelse) != IF_THEN_ELSE)
3925 goto do_next_insn;
3927 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3929 taken = 1;
3930 label = XEXP (XEXP (ifelse, 1), 0);
3932 /* An inverted jump reverses the probabilities. */
3933 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3935 taken = 0;
3936 label = XEXP (XEXP (ifelse, 2), 0);
3938 /* We shouldn't have to worry about conditional returns during
3939 the expansion stage, but handle it gracefully anyway. */
3940 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3942 taken = 1;
3943 label = NULL_RTX;
3945 /* An inverted return reverses the probabilities. */
3946 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3948 taken = 0;
3949 label = NULL_RTX;
3951 else
3952 goto do_next_insn;
3954 /* If the test is expected to fail, reverse the
3955 probabilities. */
3956 if (integer_zerop (arg1))
3957 taken = 1 - taken;
3959 /* If we are jumping to the false label, reverse the
3960 probabilities. */
3961 if (label == NULL_RTX)
3962 ; /* conditional return */
3963 else if (label == if_false_label)
3964 taken = 1 - taken;
3965 else if (label != if_true_label)
3966 goto do_next_insn;
3968 num_jumps++;
3969 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3972 do_next_insn:
3973 insn = next;
3976 /* If no jumps were modified, fail and do __builtin_expect the normal
3977 way. */
3978 if (num_jumps == 0)
3979 ret = NULL_RTX;
3982 return ret;
3985 void
3986 expand_builtin_trap ()
3988 #ifdef HAVE_trap
3989 if (HAVE_trap)
3990 emit_insn (gen_trap ());
3991 else
3992 #endif
3993 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
3994 emit_barrier ();
3997 /* Expand an expression EXP that calls a built-in function,
3998 with result going to TARGET if that's convenient
3999 (and in mode MODE if that's convenient).
4000 SUBTARGET may be used as the target for computing one of EXP's operands.
4001 IGNORE is nonzero if the value is to be ignored. */
4004 expand_builtin (exp, target, subtarget, mode, ignore)
4005 tree exp;
4006 rtx target;
4007 rtx subtarget;
4008 enum machine_mode mode;
4009 int ignore;
4011 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4012 tree arglist = TREE_OPERAND (exp, 1);
4013 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4015 /* Perform postincrements before expanding builtin functions.  */
4016 emit_queue ();
4018 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4019 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4021 /* When not optimizing, generate calls to library functions for a certain
4022 set of builtins. */
4023 if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
4024 switch (fcode)
4026 case BUILT_IN_SQRT:
4027 case BUILT_IN_SQRTF:
4028 case BUILT_IN_SQRTL:
4029 case BUILT_IN_SIN:
4030 case BUILT_IN_SINF:
4031 case BUILT_IN_SINL:
4032 case BUILT_IN_COS:
4033 case BUILT_IN_COSF:
4034 case BUILT_IN_COSL:
4035 case BUILT_IN_EXP:
4036 case BUILT_IN_EXPF:
4037 case BUILT_IN_EXPL:
4038 case BUILT_IN_LOG:
4039 case BUILT_IN_LOGF:
4040 case BUILT_IN_LOGL:
4041 case BUILT_IN_POW:
4042 case BUILT_IN_POWF:
4043 case BUILT_IN_POWL:
4044 case BUILT_IN_ATAN2:
4045 case BUILT_IN_ATAN2F:
4046 case BUILT_IN_ATAN2L:
4047 case BUILT_IN_MEMSET:
4048 case BUILT_IN_MEMCPY:
4049 case BUILT_IN_MEMCMP:
4050 case BUILT_IN_BCMP:
4051 case BUILT_IN_BZERO:
4052 case BUILT_IN_INDEX:
4053 case BUILT_IN_RINDEX:
4054 case BUILT_IN_STRCHR:
4055 case BUILT_IN_STRRCHR:
4056 case BUILT_IN_STRLEN:
4057 case BUILT_IN_STRCPY:
4058 case BUILT_IN_STRNCPY:
4059 case BUILT_IN_STRNCMP:
4060 case BUILT_IN_STRSTR:
4061 case BUILT_IN_STRPBRK:
4062 case BUILT_IN_STRCAT:
4063 case BUILT_IN_STRNCAT:
4064 case BUILT_IN_STRSPN:
4065 case BUILT_IN_STRCSPN:
4066 case BUILT_IN_STRCMP:
4067 case BUILT_IN_FFS:
4068 case BUILT_IN_PUTCHAR:
4069 case BUILT_IN_PUTS:
4070 case BUILT_IN_PRINTF:
4071 case BUILT_IN_FPUTC:
4072 case BUILT_IN_FPUTS:
4073 case BUILT_IN_FWRITE:
4074 case BUILT_IN_PUTCHAR_UNLOCKED:
4075 case BUILT_IN_PUTS_UNLOCKED:
4076 case BUILT_IN_PRINTF_UNLOCKED:
4077 case BUILT_IN_FPUTC_UNLOCKED:
4078 case BUILT_IN_FPUTS_UNLOCKED:
4079 case BUILT_IN_FWRITE_UNLOCKED:
4080 case BUILT_IN_FLOOR:
4081 case BUILT_IN_FLOORF:
4082 case BUILT_IN_FLOORL:
4083 case BUILT_IN_CEIL:
4084 case BUILT_IN_CEILF:
4085 case BUILT_IN_CEILL:
4086 case BUILT_IN_TRUNC:
4087 case BUILT_IN_TRUNCF:
4088 case BUILT_IN_TRUNCL:
4089 case BUILT_IN_ROUND:
4090 case BUILT_IN_ROUNDF:
4091 case BUILT_IN_ROUNDL:
4092 case BUILT_IN_NEARBYINT:
4093 case BUILT_IN_NEARBYINTF:
4094 case BUILT_IN_NEARBYINTL:
4095 return expand_call (exp, target, ignore);
4097 default:
4098 break;
4101 switch (fcode)
4103 case BUILT_IN_ABS:
4104 case BUILT_IN_LABS:
4105 case BUILT_IN_LLABS:
4106 case BUILT_IN_IMAXABS:
4107 case BUILT_IN_FABS:
4108 case BUILT_IN_FABSF:
4109 case BUILT_IN_FABSL:
4110 /* build_function_call changes these into ABS_EXPR. */
4111 abort ();
4113 case BUILT_IN_CONJ:
4114 case BUILT_IN_CONJF:
4115 case BUILT_IN_CONJL:
4116 case BUILT_IN_CREAL:
4117 case BUILT_IN_CREALF:
4118 case BUILT_IN_CREALL:
4119 case BUILT_IN_CIMAG:
4120 case BUILT_IN_CIMAGF:
4121 case BUILT_IN_CIMAGL:
4122 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4123 and IMAGPART_EXPR. */
4124 abort ();
4126 case BUILT_IN_SIN:
4127 case BUILT_IN_SINF:
4128 case BUILT_IN_SINL:
4129 case BUILT_IN_COS:
4130 case BUILT_IN_COSF:
4131 case BUILT_IN_COSL:
4132 case BUILT_IN_EXP:
4133 case BUILT_IN_EXPF:
4134 case BUILT_IN_EXPL:
4135 case BUILT_IN_LOG:
4136 case BUILT_IN_LOGF:
4137 case BUILT_IN_LOGL:
4138 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4139 because of possible accuracy problems. */
4140 if (! flag_unsafe_math_optimizations)
4141 break;
4142 case BUILT_IN_SQRT:
4143 case BUILT_IN_SQRTF:
4144 case BUILT_IN_SQRTL:
4145 case BUILT_IN_FLOOR:
4146 case BUILT_IN_FLOORF:
4147 case BUILT_IN_FLOORL:
4148 case BUILT_IN_CEIL:
4149 case BUILT_IN_CEILF:
4150 case BUILT_IN_CEILL:
4151 case BUILT_IN_TRUNC:
4152 case BUILT_IN_TRUNCF:
4153 case BUILT_IN_TRUNCL:
4154 case BUILT_IN_ROUND:
4155 case BUILT_IN_ROUNDF:
4156 case BUILT_IN_ROUNDL:
4157 case BUILT_IN_NEARBYINT:
4158 case BUILT_IN_NEARBYINTF:
4159 case BUILT_IN_NEARBYINTL:
4160 target = expand_builtin_mathfn (exp, target, subtarget);
4161 if (target)
4162 return target;
4163 break;
4165 case BUILT_IN_POW:
4166 case BUILT_IN_POWF:
4167 case BUILT_IN_POWL:
4168 case BUILT_IN_ATAN2:
4169 case BUILT_IN_ATAN2F:
4170 case BUILT_IN_ATAN2L:
4171 if (! flag_unsafe_math_optimizations)
4172 break;
4173 target = expand_builtin_mathfn_2 (exp, target, subtarget);
4174 if (target)
4175 return target;
4176 break;
4178 case BUILT_IN_APPLY_ARGS:
4179 return expand_builtin_apply_args ();
4181 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4182 FUNCTION with a copy of the parameters described by
4183 ARGUMENTS, and ARGSIZE. It returns a block of memory
4184 allocated on the stack into which is stored all the registers
4185 that might possibly be used for returning the result of a
4186 function. ARGUMENTS is the value returned by
4187 __builtin_apply_args. ARGSIZE is the number of bytes of
4188 arguments that must be copied. ??? How should this value be
4189 computed? We'll also need a safe worst case value for varargs
4190 functions. */
4191 case BUILT_IN_APPLY:
4192 if (!validate_arglist (arglist, POINTER_TYPE,
4193 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4194 && !validate_arglist (arglist, REFERENCE_TYPE,
4195 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4196 return const0_rtx;
4197 else
4199 int i;
4200 tree t;
4201 rtx ops[3];
4203 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4204 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4206 return expand_builtin_apply (ops[0], ops[1], ops[2]);
4209 /* __builtin_return (RESULT) causes the function to return the
4210 value described by RESULT. RESULT is address of the block of
4211 memory returned by __builtin_apply. */
4212 case BUILT_IN_RETURN:
4213 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4214 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4215 NULL_RTX, VOIDmode, 0));
4216 return const0_rtx;
4218 case BUILT_IN_SAVEREGS:
4219 return expand_builtin_saveregs ();
4221 case BUILT_IN_ARGS_INFO:
4222 return expand_builtin_args_info (exp);
4224 /* Return the address of the first anonymous stack arg. */
4225 case BUILT_IN_NEXT_ARG:
4226 return expand_builtin_next_arg (arglist);
4228 case BUILT_IN_CLASSIFY_TYPE:
4229 return expand_builtin_classify_type (arglist);
4231 case BUILT_IN_CONSTANT_P:
4232 return expand_builtin_constant_p (exp);
4234 case BUILT_IN_FRAME_ADDRESS:
4235 case BUILT_IN_RETURN_ADDRESS:
4236 return expand_builtin_frame_address (exp);
4238 /* Returns the address of the area where the structure is returned.
4239 0 otherwise. */
4240 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
4241 if (arglist != 0
4242 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
4243 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
4244 return const0_rtx;
4245 else
4246 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
4248 case BUILT_IN_ALLOCA:
4249 target = expand_builtin_alloca (arglist, target);
4250 if (target)
4251 return target;
4252 break;
4254 case BUILT_IN_FFS:
4255 case BUILT_IN_FFSL:
4256 case BUILT_IN_FFSLL:
4257 target = expand_builtin_unop (arglist, target, subtarget, ffs_optab);
4258 if (target)
4259 return target;
4260 break;
4262 case BUILT_IN_CLZ:
4263 case BUILT_IN_CLZL:
4264 case BUILT_IN_CLZLL:
4265 target = expand_builtin_unop (arglist, target, subtarget, clz_optab);
4266 if (target)
4267 return target;
4268 break;
4270 case BUILT_IN_CTZ:
4271 case BUILT_IN_CTZL:
4272 case BUILT_IN_CTZLL:
4273 target = expand_builtin_unop (arglist, target, subtarget, ctz_optab);
4274 if (target)
4275 return target;
4276 break;
4278 case BUILT_IN_POPCOUNT:
4279 case BUILT_IN_POPCOUNTL:
4280 case BUILT_IN_POPCOUNTLL:
4281 target = expand_builtin_unop (arglist, target, subtarget,
4282 popcount_optab);
4283 if (target)
4284 return target;
4285 break;
4287 case BUILT_IN_PARITY:
4288 case BUILT_IN_PARITYL:
4289 case BUILT_IN_PARITYLL:
4290 target = expand_builtin_unop (arglist, target, subtarget, parity_optab);
4291 if (target)
4292 return target;
4293 break;
4295 case BUILT_IN_STRLEN:
4296 target = expand_builtin_strlen (exp, target);
4297 if (target)
4298 return target;
4299 break;
4301 case BUILT_IN_STRCPY:
4302 target = expand_builtin_strcpy (exp, target, mode);
4303 if (target)
4304 return target;
4305 break;
4307 case BUILT_IN_STRNCPY:
4308 target = expand_builtin_strncpy (arglist, target, mode);
4309 if (target)
4310 return target;
4311 break;
4313 case BUILT_IN_STRCAT:
4314 target = expand_builtin_strcat (arglist, target, mode);
4315 if (target)
4316 return target;
4317 break;
4319 case BUILT_IN_STRNCAT:
4320 target = expand_builtin_strncat (arglist, target, mode);
4321 if (target)
4322 return target;
4323 break;
4325 case BUILT_IN_STRSPN:
4326 target = expand_builtin_strspn (arglist, target, mode);
4327 if (target)
4328 return target;
4329 break;
4331 case BUILT_IN_STRCSPN:
4332 target = expand_builtin_strcspn (arglist, target, mode);
4333 if (target)
4334 return target;
4335 break;
4337 case BUILT_IN_STRSTR:
4338 target = expand_builtin_strstr (arglist, target, mode);
4339 if (target)
4340 return target;
4341 break;
4343 case BUILT_IN_STRPBRK:
4344 target = expand_builtin_strpbrk (arglist, target, mode);
4345 if (target)
4346 return target;
4347 break;
4349 case BUILT_IN_INDEX:
4350 case BUILT_IN_STRCHR:
4351 target = expand_builtin_strchr (arglist, target, mode);
4352 if (target)
4353 return target;
4354 break;
4356 case BUILT_IN_RINDEX:
4357 case BUILT_IN_STRRCHR:
4358 target = expand_builtin_strrchr (arglist, target, mode);
4359 if (target)
4360 return target;
4361 break;
4363 case BUILT_IN_MEMCPY:
4364 target = expand_builtin_memcpy (arglist, target, mode);
4365 if (target)
4366 return target;
4367 break;
4369 case BUILT_IN_MEMSET:
4370 target = expand_builtin_memset (exp, target, mode);
4371 if (target)
4372 return target;
4373 break;
4375 case BUILT_IN_BZERO:
4376 target = expand_builtin_bzero (exp);
4377 if (target)
4378 return target;
4379 break;
4381 case BUILT_IN_STRCMP:
4382 target = expand_builtin_strcmp (exp, target, mode);
4383 if (target)
4384 return target;
4385 break;
4387 case BUILT_IN_STRNCMP:
4388 target = expand_builtin_strncmp (exp, target, mode);
4389 if (target)
4390 return target;
4391 break;
4393 case BUILT_IN_BCMP:
4394 case BUILT_IN_MEMCMP:
4395 target = expand_builtin_memcmp (exp, arglist, target, mode);
4396 if (target)
4397 return target;
4398 break;
4400 case BUILT_IN_SETJMP:
4401 target = expand_builtin_setjmp (arglist, target);
4402 if (target)
4403 return target;
4404 break;
4406 /* __builtin_longjmp is passed a pointer to an array of five words.
4407 It's similar to the C library longjmp function but works with
4408 __builtin_setjmp above. */
4409 case BUILT_IN_LONGJMP:
4410 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4411 break;
4412 else
4414 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
4415 VOIDmode, 0);
4416 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
4417 NULL_RTX, VOIDmode, 0);
4419 if (value != const1_rtx)
4421 error ("__builtin_longjmp second argument must be 1");
4422 return const0_rtx;
4425 expand_builtin_longjmp (buf_addr, value);
4426 return const0_rtx;
4429 case BUILT_IN_TRAP:
4430 expand_builtin_trap ();
4431 return const0_rtx;
4433 case BUILT_IN_FPUTS:
4434 target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
4435 if (target)
4436 return target;
4437 break;
4438 case BUILT_IN_FPUTS_UNLOCKED:
4439 target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
4440 if (target)
4441 return target;
4442 break;
4444 /* Various hooks for the DWARF 2 __throw routine. */
4445 case BUILT_IN_UNWIND_INIT:
4446 expand_builtin_unwind_init ();
4447 return const0_rtx;
4448 case BUILT_IN_DWARF_CFA:
4449 return virtual_cfa_rtx;
4450 #ifdef DWARF2_UNWIND_INFO
4451 case BUILT_IN_DWARF_FP_REGNUM:
4452 return expand_builtin_dwarf_fp_regnum ();
4453 case BUILT_IN_INIT_DWARF_REG_SIZES:
4454 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
4455 return const0_rtx;
4456 #endif
4457 case BUILT_IN_FROB_RETURN_ADDR:
4458 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
4459 case BUILT_IN_EXTRACT_RETURN_ADDR:
4460 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
4461 case BUILT_IN_EH_RETURN:
4462 expand_builtin_eh_return (TREE_VALUE (arglist),
4463 TREE_VALUE (TREE_CHAIN (arglist)));
4464 return const0_rtx;
4465 #ifdef EH_RETURN_DATA_REGNO
4466 case BUILT_IN_EH_RETURN_DATA_REGNO:
4467 return expand_builtin_eh_return_data_regno (arglist);
4468 #endif
4469 case BUILT_IN_VA_START:
4470 case BUILT_IN_STDARG_START:
4471 return expand_builtin_va_start (arglist);
4472 case BUILT_IN_VA_END:
4473 return expand_builtin_va_end (arglist);
4474 case BUILT_IN_VA_COPY:
4475 return expand_builtin_va_copy (arglist);
4476 case BUILT_IN_EXPECT:
4477 return expand_builtin_expect (arglist, target);
4478 case BUILT_IN_PREFETCH:
4479 expand_builtin_prefetch (arglist);
4480 return const0_rtx;
4483 default: /* just do library call, if unknown builtin */
4484 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
4485 error ("built-in function `%s' not currently supported",
4486 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
4489 /* The switch statement above can drop through to cause the function
4490 to be called normally. */
4491 return expand_call (exp, target, ignore);
4494 /* Determine whether a tree node represents a call to a built-in
4495 math function. If the tree T is a call to a built-in function
4496 taking a single real argument, then the return value is the
4497 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
4498 the return value is END_BUILTINS. */
4500 enum built_in_function
4501 builtin_mathfn_code (t)
4502 tree t;
4504 tree fndecl, arglist;
4506 if (TREE_CODE (t) != CALL_EXPR
4507 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
4508 return END_BUILTINS;
4510 fndecl = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
4511 if (TREE_CODE (fndecl) != FUNCTION_DECL
4512 || ! DECL_BUILT_IN (fndecl)
4513 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4514 return END_BUILTINS;
4516 arglist = TREE_OPERAND (t, 1);
4517 if (! arglist
4518 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
4519 || TREE_CHAIN (arglist))
4520 return END_BUILTINS;
4522 return DECL_FUNCTION_CODE (fndecl);
4525 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4526 constant. ARGLIST is the argument list of the call. */
4528 static tree
4529 fold_builtin_constant_p (arglist)
4530 tree arglist;
4532 if (arglist == 0)
4533 return 0;
4535 arglist = TREE_VALUE (arglist);
4537 /* We return 1 for a numeric type that's known to be a constant
4538 value at compile-time or for an aggregate type that's a
4539 literal constant. */
4540 STRIP_NOPS (arglist);
4542 /* If we know this is a constant, emit the constant of one. */
4543 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
4544 || (TREE_CODE (arglist) == CONSTRUCTOR
4545 && TREE_CONSTANT (arglist))
4546 || (TREE_CODE (arglist) == ADDR_EXPR
4547 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
4548 return integer_one_node;
4550 /* If we aren't going to be running CSE or this expression
4551 has side effects, show we don't know it to be a constant.
4552 Likewise if it's a pointer or aggregate type since in those
4553 case we only want literals, since those are only optimized
4554 when generating RTL, not later.
4555 And finally, if we are compiling an initializer, not code, we
4556 need to return a definite result now; there's not going to be any
4557 more optimization done. */
4558 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
4559 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
4560 || POINTER_TYPE_P (TREE_TYPE (arglist))
4561 || cfun == 0)
4562 return integer_zero_node;
4564 return 0;
4567 /* Fold a call to __builtin_classify_type. */
4569 static tree
4570 fold_builtin_classify_type (arglist)
4571 tree arglist;
4573 if (arglist == 0)
4574 return build_int_2 (no_type_class, 0);
4576 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
4579 /* Fold a call to __builtin_inf or __builtin_huge_val. */
4581 static tree
4582 fold_builtin_inf (type, warn)
4583 tree type;
4584 int warn;
4586 REAL_VALUE_TYPE real;
4588 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
4589 warning ("target format does not support infinity");
4591 real_inf (&real);
4592 return build_real (type, real);
4595 /* Fold a call to __builtin_nan or __builtin_nans. */
4597 static tree
4598 fold_builtin_nan (arglist, type, quiet)
4599 tree arglist, type;
4600 int quiet;
4602 REAL_VALUE_TYPE real;
4603 const char *str;
4605 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4606 return 0;
4607 str = c_getstr (TREE_VALUE (arglist));
4608 if (!str)
4609 return 0;
4611 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
4612 return 0;
4614 return build_real (type, real);
4617 /* EXP is assumed to me builtin call where truncation can be propagated
4618 across (for instance floor((double)f) == (double)floorf (f).
4619 Do the transformation. */
4620 static tree
4621 fold_trunc_transparent_mathfn (exp)
4622 tree exp;
4624 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4625 tree arglist = TREE_OPERAND (exp, 1);
4626 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4628 if (optimize && validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4630 tree arg0 = strip_float_extensions (TREE_VALUE (arglist));
4631 tree ftype = TREE_TYPE (exp);
4632 tree newtype = TREE_TYPE (arg0);
4633 tree decl;
4635 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
4636 && (decl = mathfn_built_in (newtype, fcode)))
4638 arglist =
4639 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
4640 return convert (ftype,
4641 build_function_call_expr (decl, arglist));
4644 return 0;
4647 /* Used by constant folding to eliminate some builtin calls early. EXP is
4648 the CALL_EXPR of a call to a builtin function. */
4650 tree
4651 fold_builtin (exp)
4652 tree exp;
4654 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4655 tree arglist = TREE_OPERAND (exp, 1);
4656 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4658 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4659 return 0;
4661 switch (fcode)
4663 case BUILT_IN_CONSTANT_P:
4664 return fold_builtin_constant_p (arglist);
4666 case BUILT_IN_CLASSIFY_TYPE:
4667 return fold_builtin_classify_type (arglist);
4669 case BUILT_IN_STRLEN:
4670 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4672 tree len = c_strlen (TREE_VALUE (arglist));
4673 if (len)
4675 /* Convert from the internal "sizetype" type to "size_t". */
4676 if (size_type_node)
4677 len = convert (size_type_node, len);
4678 return len;
4681 break;
4683 case BUILT_IN_SQRT:
4684 case BUILT_IN_SQRTF:
4685 case BUILT_IN_SQRTL:
4686 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4688 enum built_in_function fcode;
4689 tree arg = TREE_VALUE (arglist);
4691 /* Optimize sqrt of constant value. */
4692 if (TREE_CODE (arg) == REAL_CST
4693 && ! TREE_CONSTANT_OVERFLOW (arg))
4695 enum machine_mode mode;
4696 REAL_VALUE_TYPE r, x;
4698 x = TREE_REAL_CST (arg);
4699 mode = TYPE_MODE (TREE_TYPE (arg));
4700 if (real_sqrt (&r, mode, &x)
4701 || (!flag_trapping_math && !flag_errno_math))
4702 return build_real (TREE_TYPE (arg), r);
4705 /* Optimize sqrt(exp(x)) = exp(x/2.0). */
4706 fcode = builtin_mathfn_code (arg);
4707 if (flag_unsafe_math_optimizations
4708 && (fcode == BUILT_IN_EXP
4709 || fcode == BUILT_IN_EXPF
4710 || fcode == BUILT_IN_EXPL))
4712 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
4713 arg = build (RDIV_EXPR, TREE_TYPE (arg),
4714 TREE_VALUE (TREE_OPERAND (arg, 1)),
4715 build_real (TREE_TYPE (arg), dconst2));
4716 arglist = build_tree_list (NULL_TREE, arg);
4717 return build_function_call_expr (expfn, arglist);
4720 break;
4722 case BUILT_IN_EXP:
4723 case BUILT_IN_EXPF:
4724 case BUILT_IN_EXPL:
4725 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4727 enum built_in_function fcode;
4728 tree arg = TREE_VALUE (arglist);
4730 /* Optimize exp(0.0) = 1.0. */
4731 if (real_zerop (arg))
4732 return build_real (TREE_TYPE (arg), dconst1);
4734 /* Optimize exp(log(x)) = x. */
4735 fcode = builtin_mathfn_code (arg);
4736 if (flag_unsafe_math_optimizations
4737 && (fcode == BUILT_IN_LOG
4738 || fcode == BUILT_IN_LOGF
4739 || fcode == BUILT_IN_LOGL))
4740 return TREE_VALUE (TREE_OPERAND (arg, 1));
4742 break;
4744 case BUILT_IN_LOG:
4745 case BUILT_IN_LOGF:
4746 case BUILT_IN_LOGL:
4747 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4749 enum built_in_function fcode;
4750 tree arg = TREE_VALUE (arglist);
4752 /* Optimize log(1.0) = 0.0. */
4753 if (real_onep (arg))
4754 return build_real (TREE_TYPE (arg), dconst0);
4756 /* Optimize log(exp(x)) = x. */
4757 fcode = builtin_mathfn_code (arg);
4758 if (flag_unsafe_math_optimizations
4759 && (fcode == BUILT_IN_EXP
4760 || fcode == BUILT_IN_EXPF
4761 || fcode == BUILT_IN_EXPL))
4762 return TREE_VALUE (TREE_OPERAND (arg, 1));
4764 /* Optimize log(sqrt(x)) = log(x)/2.0. */
4765 if (flag_unsafe_math_optimizations
4766 && (fcode == BUILT_IN_SQRT
4767 || fcode == BUILT_IN_SQRTF
4768 || fcode == BUILT_IN_SQRTL))
4770 tree logfn = build_function_call_expr (fndecl,
4771 TREE_OPERAND (arg, 1));
4772 return fold (build (RDIV_EXPR, TREE_TYPE (arg), logfn,
4773 build_real (TREE_TYPE (arg), dconst2)));
4776 break;
4778 case BUILT_IN_INF:
4779 case BUILT_IN_INFF:
4780 case BUILT_IN_INFL:
4781 return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), true);
4783 case BUILT_IN_HUGE_VAL:
4784 case BUILT_IN_HUGE_VALF:
4785 case BUILT_IN_HUGE_VALL:
4786 return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), false);
4788 case BUILT_IN_NAN:
4789 case BUILT_IN_NANF:
4790 case BUILT_IN_NANL:
4791 return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), true);
4793 case BUILT_IN_NANS:
4794 case BUILT_IN_NANSF:
4795 case BUILT_IN_NANSL:
4796 return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false);
4798 case BUILT_IN_FLOOR:
4799 case BUILT_IN_FLOORF:
4800 case BUILT_IN_FLOORL:
4801 case BUILT_IN_CEIL:
4802 case BUILT_IN_CEILF:
4803 case BUILT_IN_CEILL:
4804 case BUILT_IN_TRUNC:
4805 case BUILT_IN_TRUNCF:
4806 case BUILT_IN_TRUNCL:
4807 case BUILT_IN_ROUND:
4808 case BUILT_IN_ROUNDF:
4809 case BUILT_IN_ROUNDL:
4810 case BUILT_IN_NEARBYINT:
4811 case BUILT_IN_NEARBYINTF:
4812 case BUILT_IN_NEARBYINTL:
4813 return fold_trunc_transparent_mathfn (exp);
4815 default:
4816 break;
4819 return 0;
4822 /* Conveniently construct a function call expression. */
4824 tree
4825 build_function_call_expr (fn, arglist)
4826 tree fn, arglist;
4828 tree call_expr;
4830 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
4831 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
4832 call_expr, arglist);
4833 TREE_SIDE_EFFECTS (call_expr) = 1;
4834 return fold (call_expr);
4837 /* This function validates the types of a function call argument list
4838 represented as a tree chain of parameters against a specified list
4839 of tree_codes. If the last specifier is a 0, that represents an
4840 ellipses, otherwise the last specifier must be a VOID_TYPE. */
4842 static int
4843 validate_arglist VPARAMS ((tree arglist, ...))
4845 enum tree_code code;
4846 int res = 0;
4848 VA_OPEN (ap, arglist);
4849 VA_FIXEDARG (ap, tree, arglist);
4853 code = va_arg (ap, enum tree_code);
4854 switch (code)
4856 case 0:
4857 /* This signifies an ellipses, any further arguments are all ok. */
4858 res = 1;
4859 goto end;
4860 case VOID_TYPE:
4861 /* This signifies an endlink, if no arguments remain, return
4862 true, otherwise return false. */
4863 res = arglist == 0;
4864 goto end;
4865 default:
4866 /* If no parameters remain or the parameter's code does not
4867 match the specified code, return false. Otherwise continue
4868 checking any remaining arguments. */
4869 if (arglist == 0
4870 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
4871 goto end;
4872 break;
4874 arglist = TREE_CHAIN (arglist);
4876 while (1);
4878 /* We need gotos here since we can only have one VA_CLOSE in a
4879 function. */
4880 end: ;
4881 VA_CLOSE (ap);
4883 return res;
4886 /* Default version of target-specific builtin setup that does nothing. */
4888 void
4889 default_init_builtins ()
4893 /* Default target-specific builtin expander that does nothing. */
4896 default_expand_builtin (exp, target, subtarget, mode, ignore)
4897 tree exp ATTRIBUTE_UNUSED;
4898 rtx target ATTRIBUTE_UNUSED;
4899 rtx subtarget ATTRIBUTE_UNUSED;
4900 enum machine_mode mode ATTRIBUTE_UNUSED;
4901 int ignore ATTRIBUTE_UNUSED;
4903 return NULL_RTX;
4906 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
4908 void
4909 purge_builtin_constant_p ()
4911 rtx insn, set, arg, new, note;
4913 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4914 if (INSN_P (insn)
4915 && (set = single_set (insn)) != NULL_RTX
4916 && GET_CODE (SET_SRC (set)) == CONSTANT_P_RTX)
4918 arg = XEXP (SET_SRC (set), 0);
4919 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
4920 validate_change (insn, &SET_SRC (set), new, 0);
4922 /* Remove the REG_EQUAL note from the insn. */
4923 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
4924 remove_note (insn, note);