* Makefile.in (rtlanal.o): Depend on $(TM_P_H).
[official-gcc.git] / gcc / builtins.c
blob0576886490d6f53ef6ad5fad3c7a57cb220ee5cb
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001 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 "machmode.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "obstack.h"
28 #include "flags.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "except.h"
32 #include "function.h"
33 #include "insn-config.h"
34 #include "expr.h"
35 #include "optabs.h"
36 #include "libfuncs.h"
37 #include "recog.h"
38 #include "output.h"
39 #include "typeclass.h"
40 #include "toplev.h"
41 #include "predict.h"
42 #include "tm_p.h"
43 #include "target.h"
45 #define CALLED_AS_BUILT_IN(NODE) \
46 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
48 /* Register mappings for target machines without register windows. */
49 #ifndef INCOMING_REGNO
50 #define INCOMING_REGNO(OUT) (OUT)
51 #endif
52 #ifndef OUTGOING_REGNO
53 #define OUTGOING_REGNO(IN) (IN)
54 #endif
56 #ifndef PAD_VARARGS_DOWN
57 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
58 #endif
60 /* Define the names of the builtin function types and codes. */
61 const char *const built_in_class_names[4]
62 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
64 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA) STRINGX(X),
65 const char *const built_in_names[(int) END_BUILTINS] =
67 #include "builtins.def"
69 #undef DEF_BUILTIN
71 /* Setup an array of _DECL trees, make sure each element is
72 initialized to NULL_TREE. */
73 tree built_in_decls[(int) END_BUILTINS];
75 tree (*lang_type_promotes_to) PARAMS ((tree));
77 static int get_pointer_alignment PARAMS ((tree, unsigned int));
78 static tree c_strlen PARAMS ((tree));
79 static const char *c_getstr PARAMS ((tree));
80 static rtx c_readstr PARAMS ((const char *,
81 enum machine_mode));
82 static int target_char_cast PARAMS ((tree, char *));
83 static rtx get_memory_rtx PARAMS ((tree));
84 static int apply_args_size PARAMS ((void));
85 static int apply_result_size PARAMS ((void));
86 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
87 static rtx result_vector PARAMS ((int, rtx));
88 #endif
89 static rtx expand_builtin_setjmp PARAMS ((tree, rtx));
90 static rtx expand_builtin_apply_args PARAMS ((void));
91 static rtx expand_builtin_apply_args_1 PARAMS ((void));
92 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
93 static void expand_builtin_return PARAMS ((rtx));
94 static enum type_class type_to_class PARAMS ((tree));
95 static rtx expand_builtin_classify_type PARAMS ((tree));
96 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
97 static rtx expand_builtin_constant_p PARAMS ((tree));
98 static rtx expand_builtin_args_info PARAMS ((tree));
99 static rtx expand_builtin_next_arg PARAMS ((tree));
100 static rtx expand_builtin_va_start PARAMS ((int, tree));
101 static rtx expand_builtin_va_end PARAMS ((tree));
102 static rtx expand_builtin_va_copy PARAMS ((tree));
103 #ifdef HAVE_cmpstrsi
104 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
105 #endif
106 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
107 enum machine_mode));
108 static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
109 enum machine_mode));
110 static rtx builtin_memcpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
111 enum machine_mode));
112 static rtx expand_builtin_strcat PARAMS ((tree, rtx,
113 enum machine_mode));
114 static rtx expand_builtin_strncat PARAMS ((tree, rtx,
115 enum machine_mode));
116 static rtx expand_builtin_strspn PARAMS ((tree, rtx,
117 enum machine_mode));
118 static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
119 enum machine_mode));
120 static rtx expand_builtin_memcpy PARAMS ((tree));
121 static rtx expand_builtin_strcpy PARAMS ((tree));
122 static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
123 enum machine_mode));
124 static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
125 enum machine_mode));
126 static rtx builtin_memset_read_str PARAMS ((PTR, HOST_WIDE_INT,
127 enum machine_mode));
128 static rtx expand_builtin_memset PARAMS ((tree));
129 static rtx expand_builtin_bzero PARAMS ((tree));
130 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
131 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
132 enum machine_mode));
133 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
134 enum machine_mode));
135 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
136 enum machine_mode));
137 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
138 enum machine_mode));
139 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
140 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
141 static rtx expand_builtin_frame_address PARAMS ((tree));
142 static rtx expand_builtin_fputs PARAMS ((tree, int));
143 static tree stabilize_va_list PARAMS ((tree, int));
144 static rtx expand_builtin_expect PARAMS ((tree, rtx));
145 static tree fold_builtin_constant_p PARAMS ((tree));
146 static tree fold_builtin_classify_type PARAMS ((tree));
147 static tree build_function_call_expr PARAMS ((tree, tree));
148 static int validate_arglist PARAMS ((tree, ...));
150 /* Return the alignment in bits of EXP, a pointer valued expression.
151 But don't return more than MAX_ALIGN no matter what.
152 The alignment returned is, by default, the alignment of the thing that
153 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
155 Otherwise, look at the expression to see if we can do better, i.e., if the
156 expression is actually pointing at an object whose alignment is tighter. */
158 static int
159 get_pointer_alignment (exp, max_align)
160 tree exp;
161 unsigned int max_align;
163 unsigned int align, inner;
165 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
166 return 0;
168 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
169 align = MIN (align, max_align);
171 while (1)
173 switch (TREE_CODE (exp))
175 case NOP_EXPR:
176 case CONVERT_EXPR:
177 case NON_LVALUE_EXPR:
178 exp = TREE_OPERAND (exp, 0);
179 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
180 return align;
182 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
183 align = MIN (inner, max_align);
184 break;
186 case PLUS_EXPR:
187 /* If sum of pointer + int, restrict our maximum alignment to that
188 imposed by the integer. If not, we can't do any better than
189 ALIGN. */
190 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
191 return align;
193 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
194 & (max_align / BITS_PER_UNIT - 1))
195 != 0)
196 max_align >>= 1;
198 exp = TREE_OPERAND (exp, 0);
199 break;
201 case ADDR_EXPR:
202 /* See what we are pointing at and look at its alignment. */
203 exp = TREE_OPERAND (exp, 0);
204 if (TREE_CODE (exp) == FUNCTION_DECL)
205 align = FUNCTION_BOUNDARY;
206 else if (DECL_P (exp))
207 align = DECL_ALIGN (exp);
208 #ifdef CONSTANT_ALIGNMENT
209 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
210 align = CONSTANT_ALIGNMENT (exp, align);
211 #endif
212 return MIN (align, max_align);
214 default:
215 return align;
220 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
221 way, because it could contain a zero byte in the middle.
222 TREE_STRING_LENGTH is the size of the character array, not the string.
224 The value returned is of type `ssizetype'.
226 Unfortunately, string_constant can't access the values of const char
227 arrays with initializers, so neither can we do so here. */
229 static tree
230 c_strlen (src)
231 tree src;
233 tree offset_node;
234 HOST_WIDE_INT offset;
235 int max;
236 const char *ptr;
238 src = string_constant (src, &offset_node);
239 if (src == 0)
240 return 0;
242 max = TREE_STRING_LENGTH (src) - 1;
243 ptr = TREE_STRING_POINTER (src);
245 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
247 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
248 compute the offset to the following null if we don't know where to
249 start searching for it. */
250 int i;
252 for (i = 0; i < max; i++)
253 if (ptr[i] == 0)
254 return 0;
256 /* We don't know the starting offset, but we do know that the string
257 has no internal zero bytes. We can assume that the offset falls
258 within the bounds of the string; otherwise, the programmer deserves
259 what he gets. Subtract the offset from the length of the string,
260 and return that. This would perhaps not be valid if we were dealing
261 with named arrays in addition to literal string constants. */
263 return size_diffop (size_int (max), offset_node);
266 /* We have a known offset into the string. Start searching there for
267 a null character if we can represent it as a single HOST_WIDE_INT. */
268 if (offset_node == 0)
269 offset = 0;
270 else if (! host_integerp (offset_node, 0))
271 offset = -1;
272 else
273 offset = tree_low_cst (offset_node, 0);
275 /* If the offset is known to be out of bounds, warn, and call strlen at
276 runtime. */
277 if (offset < 0 || offset > max)
279 warning ("offset outside bounds of constant string");
280 return 0;
283 /* Use strlen to search for the first zero byte. Since any strings
284 constructed with build_string will have nulls appended, we win even
285 if we get handed something like (char[4])"abcd".
287 Since OFFSET is our starting index into the string, no further
288 calculation is needed. */
289 return ssize_int (strlen (ptr + offset));
292 /* Return a char pointer for a C string if it is a string constant
293 or sum of string constant and integer constant. */
295 static const char *
296 c_getstr (src)
297 tree src;
299 tree offset_node;
301 src = string_constant (src, &offset_node);
302 if (src == 0)
303 return 0;
305 if (offset_node == 0)
306 return TREE_STRING_POINTER (src);
307 else if (!host_integerp (offset_node, 1)
308 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
309 return 0;
311 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
314 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
315 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
317 static rtx
318 c_readstr (str, mode)
319 const char *str;
320 enum machine_mode mode;
322 HOST_WIDE_INT c[2];
323 HOST_WIDE_INT ch;
324 unsigned int i, j;
326 if (GET_MODE_CLASS (mode) != MODE_INT)
327 abort ();
328 c[0] = 0;
329 c[1] = 0;
330 ch = 1;
331 for (i = 0; i < GET_MODE_SIZE (mode); i++)
333 j = i;
334 if (WORDS_BIG_ENDIAN)
335 j = GET_MODE_SIZE (mode) - i - 1;
336 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
337 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
338 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
339 j *= BITS_PER_UNIT;
340 if (j > 2 * HOST_BITS_PER_WIDE_INT)
341 abort ();
342 if (ch)
343 ch = (unsigned char) str[i];
344 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
346 return immed_double_const (c[0], c[1], mode);
349 /* Cast a target constant CST to target CHAR and if that value fits into
350 host char type, return zero and put that value into variable pointed by
351 P. */
353 static int
354 target_char_cast (cst, p)
355 tree cst;
356 char *p;
358 unsigned HOST_WIDE_INT val, hostval;
360 if (!host_integerp (cst, 1)
361 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
362 return 1;
364 val = tree_low_cst (cst, 1);
365 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
366 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
368 hostval = val;
369 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
370 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
372 if (val != hostval)
373 return 1;
375 *p = hostval;
376 return 0;
379 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
380 times to get the address of either a higher stack frame, or a return
381 address located within it (depending on FNDECL_CODE). */
384 expand_builtin_return_addr (fndecl_code, count, tem)
385 enum built_in_function fndecl_code;
386 int count;
387 rtx tem;
389 int i;
391 /* Some machines need special handling before we can access
392 arbitrary frames. For example, on the sparc, we must first flush
393 all register windows to the stack. */
394 #ifdef SETUP_FRAME_ADDRESSES
395 if (count > 0)
396 SETUP_FRAME_ADDRESSES ();
397 #endif
399 /* On the sparc, the return address is not in the frame, it is in a
400 register. There is no way to access it off of the current frame
401 pointer, but it can be accessed off the previous frame pointer by
402 reading the value from the register window save area. */
403 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
404 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
405 count--;
406 #endif
408 /* Scan back COUNT frames to the specified frame. */
409 for (i = 0; i < count; i++)
411 /* Assume the dynamic chain pointer is in the word that the
412 frame address points to, unless otherwise specified. */
413 #ifdef DYNAMIC_CHAIN_ADDRESS
414 tem = DYNAMIC_CHAIN_ADDRESS (tem);
415 #endif
416 tem = memory_address (Pmode, tem);
417 tem = gen_rtx_MEM (Pmode, tem);
418 set_mem_alias_set (tem, get_frame_alias_set ());
419 tem = copy_to_reg (tem);
422 /* For __builtin_frame_address, return what we've got. */
423 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
424 return tem;
426 /* For __builtin_return_address, Get the return address from that
427 frame. */
428 #ifdef RETURN_ADDR_RTX
429 tem = RETURN_ADDR_RTX (count, tem);
430 #else
431 tem = memory_address (Pmode,
432 plus_constant (tem, GET_MODE_SIZE (Pmode)));
433 tem = gen_rtx_MEM (Pmode, tem);
434 set_mem_alias_set (tem, get_frame_alias_set ());
435 #endif
436 return tem;
439 /* Alias set used for setjmp buffer. */
440 static HOST_WIDE_INT setjmp_alias_set = -1;
442 /* Construct the leading half of a __builtin_setjmp call. Control will
443 return to RECEIVER_LABEL. This is used directly by sjlj exception
444 handling code. */
446 void
447 expand_builtin_setjmp_setup (buf_addr, receiver_label)
448 rtx buf_addr;
449 rtx receiver_label;
451 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
452 rtx stack_save;
453 rtx mem;
455 if (setjmp_alias_set == -1)
456 setjmp_alias_set = new_alias_set ();
458 #ifdef POINTERS_EXTEND_UNSIGNED
459 buf_addr = convert_memory_address (Pmode, buf_addr);
460 #endif
462 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
464 emit_queue ();
466 /* We store the frame pointer and the address of receiver_label in
467 the buffer and use the rest of it for the stack save area, which
468 is machine-dependent. */
470 #ifndef BUILTIN_SETJMP_FRAME_VALUE
471 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
472 #endif
474 mem = gen_rtx_MEM (Pmode, buf_addr);
475 set_mem_alias_set (mem, setjmp_alias_set);
476 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
478 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
479 set_mem_alias_set (mem, setjmp_alias_set);
481 emit_move_insn (validize_mem (mem),
482 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
484 stack_save = gen_rtx_MEM (sa_mode,
485 plus_constant (buf_addr,
486 2 * GET_MODE_SIZE (Pmode)));
487 set_mem_alias_set (stack_save, setjmp_alias_set);
488 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
490 /* If there is further processing to do, do it. */
491 #ifdef HAVE_builtin_setjmp_setup
492 if (HAVE_builtin_setjmp_setup)
493 emit_insn (gen_builtin_setjmp_setup (buf_addr));
494 #endif
496 /* Tell optimize_save_area_alloca that extra work is going to
497 need to go on during alloca. */
498 current_function_calls_setjmp = 1;
500 /* Set this so all the registers get saved in our frame; we need to be
501 able to copy the saved values for any registers from frames we unwind. */
502 current_function_has_nonlocal_label = 1;
505 /* Construct the trailing part of a __builtin_setjmp call.
506 This is used directly by sjlj exception handling code. */
508 void
509 expand_builtin_setjmp_receiver (receiver_label)
510 rtx receiver_label ATTRIBUTE_UNUSED;
512 /* Clobber the FP when we get here, so we have to make sure it's
513 marked as used by this function. */
514 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
516 /* Mark the static chain as clobbered here so life information
517 doesn't get messed up for it. */
518 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
520 /* Now put in the code to restore the frame pointer, and argument
521 pointer, if needed. The code below is from expand_end_bindings
522 in stmt.c; see detailed documentation there. */
523 #ifdef HAVE_nonlocal_goto
524 if (! HAVE_nonlocal_goto)
525 #endif
526 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
528 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
529 if (fixed_regs[ARG_POINTER_REGNUM])
531 #ifdef ELIMINABLE_REGS
532 size_t i;
533 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
535 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
536 if (elim_regs[i].from == ARG_POINTER_REGNUM
537 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
538 break;
540 if (i == ARRAY_SIZE (elim_regs))
541 #endif
543 /* Now restore our arg pointer from the address at which it
544 was saved in our stack frame. */
545 emit_move_insn (virtual_incoming_args_rtx,
546 copy_to_reg (get_arg_pointer_save_area (cfun)));
549 #endif
551 #ifdef HAVE_builtin_setjmp_receiver
552 if (HAVE_builtin_setjmp_receiver)
553 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
554 else
555 #endif
556 #ifdef HAVE_nonlocal_goto_receiver
557 if (HAVE_nonlocal_goto_receiver)
558 emit_insn (gen_nonlocal_goto_receiver ());
559 else
560 #endif
561 { /* Nothing */ }
563 /* @@@ This is a kludge. Not all machine descriptions define a blockage
564 insn, but we must not allow the code we just generated to be reordered
565 by scheduling. Specifically, the update of the frame pointer must
566 happen immediately, not later. So emit an ASM_INPUT to act as blockage
567 insn. */
568 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
571 /* __builtin_setjmp is passed a pointer to an array of five words (not
572 all will be used on all machines). It operates similarly to the C
573 library function of the same name, but is more efficient. Much of
574 the code below (and for longjmp) is copied from the handling of
575 non-local gotos.
577 NOTE: This is intended for use by GNAT and the exception handling
578 scheme in the compiler and will only work in the method used by
579 them. */
581 static rtx
582 expand_builtin_setjmp (arglist, target)
583 tree arglist;
584 rtx target;
586 rtx buf_addr, next_lab, cont_lab;
588 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
589 return NULL_RTX;
591 if (target == 0 || GET_CODE (target) != REG
592 || REGNO (target) < FIRST_PSEUDO_REGISTER)
593 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
595 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
597 next_lab = gen_label_rtx ();
598 cont_lab = gen_label_rtx ();
600 expand_builtin_setjmp_setup (buf_addr, next_lab);
602 /* Set TARGET to zero and branch to the continue label. */
603 emit_move_insn (target, const0_rtx);
604 emit_jump_insn (gen_jump (cont_lab));
605 emit_barrier ();
606 emit_label (next_lab);
608 expand_builtin_setjmp_receiver (next_lab);
610 /* Set TARGET to one. */
611 emit_move_insn (target, const1_rtx);
612 emit_label (cont_lab);
614 /* Tell flow about the strange goings on. Putting `next_lab' on
615 `nonlocal_goto_handler_labels' to indicates that function
616 calls may traverse the arc back to this label. */
618 current_function_has_nonlocal_label = 1;
619 nonlocal_goto_handler_labels
620 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
622 return target;
625 /* __builtin_longjmp is passed a pointer to an array of five words (not
626 all will be used on all machines). It operates similarly to the C
627 library function of the same name, but is more efficient. Much of
628 the code below is copied from the handling of non-local gotos.
630 NOTE: This is intended for use by GNAT and the exception handling
631 scheme in the compiler and will only work in the method used by
632 them. */
634 void
635 expand_builtin_longjmp (buf_addr, value)
636 rtx buf_addr, value;
638 rtx fp, lab, stack, insn;
639 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
641 if (setjmp_alias_set == -1)
642 setjmp_alias_set = new_alias_set ();
644 #ifdef POINTERS_EXTEND_UNSIGNED
645 buf_addr = convert_memory_address (Pmode, buf_addr);
646 #endif
647 buf_addr = force_reg (Pmode, buf_addr);
649 /* We used to store value in static_chain_rtx, but that fails if pointers
650 are smaller than integers. We instead require that the user must pass
651 a second argument of 1, because that is what builtin_setjmp will
652 return. This also makes EH slightly more efficient, since we are no
653 longer copying around a value that we don't care about. */
654 if (value != const1_rtx)
655 abort ();
657 current_function_calls_longjmp = 1;
659 #ifdef HAVE_builtin_longjmp
660 if (HAVE_builtin_longjmp)
661 emit_insn (gen_builtin_longjmp (buf_addr));
662 else
663 #endif
665 fp = gen_rtx_MEM (Pmode, buf_addr);
666 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
667 GET_MODE_SIZE (Pmode)));
669 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
670 2 * GET_MODE_SIZE (Pmode)));
671 set_mem_alias_set (fp, setjmp_alias_set);
672 set_mem_alias_set (lab, setjmp_alias_set);
673 set_mem_alias_set (stack, setjmp_alias_set);
675 /* Pick up FP, label, and SP from the block and jump. This code is
676 from expand_goto in stmt.c; see there for detailed comments. */
677 #if HAVE_nonlocal_goto
678 if (HAVE_nonlocal_goto)
679 /* We have to pass a value to the nonlocal_goto pattern that will
680 get copied into the static_chain pointer, but it does not matter
681 what that value is, because builtin_setjmp does not use it. */
682 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
683 else
684 #endif
686 lab = copy_to_reg (lab);
688 emit_move_insn (hard_frame_pointer_rtx, fp);
689 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
691 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
692 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
693 emit_indirect_jump (lab);
697 /* Search backwards and mark the jump insn as a non-local goto.
698 Note that this precludes the use of __builtin_longjmp to a
699 __builtin_setjmp target in the same function. However, we've
700 already cautioned the user that these functions are for
701 internal exception handling use only. */
702 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
704 if (GET_CODE (insn) == JUMP_INSN)
706 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
707 REG_NOTES (insn));
708 break;
710 else if (GET_CODE (insn) == CALL_INSN)
711 break;
715 /* Get a MEM rtx for expression EXP which is the address of an operand
716 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
718 static rtx
719 get_memory_rtx (exp)
720 tree exp;
722 rtx mem = gen_rtx_MEM (BLKmode,
723 memory_address (BLKmode,
724 expand_expr (exp, NULL_RTX,
725 ptr_mode, EXPAND_SUM)));
727 /* Get an expression we can use to find the attributes to assign to MEM.
728 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
729 we can. First remove any nops. */
730 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
731 || TREE_CODE (exp) == NON_LVALUE_EXPR)
732 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
733 exp = TREE_OPERAND (exp, 0);
735 if (TREE_CODE (exp) == ADDR_EXPR)
736 exp = TREE_OPERAND (exp, 0);
737 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
738 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
739 else
740 return mem;
742 set_mem_attributes (mem, exp, 0);
743 /* memcpy, memset and other builtin stringops can alias with anything. */
744 set_mem_alias_set (mem, 0);
745 return mem;
748 /* Built-in functions to perform an untyped call and return. */
750 /* For each register that may be used for calling a function, this
751 gives a mode used to copy the register's value. VOIDmode indicates
752 the register is not used for calling a function. If the machine
753 has register windows, this gives only the outbound registers.
754 INCOMING_REGNO gives the corresponding inbound register. */
755 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
757 /* For each register that may be used for returning values, this gives
758 a mode used to copy the register's value. VOIDmode indicates the
759 register is not used for returning values. If the machine has
760 register windows, this gives only the outbound registers.
761 INCOMING_REGNO gives the corresponding inbound register. */
762 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
764 /* For each register that may be used for calling a function, this
765 gives the offset of that register into the block returned by
766 __builtin_apply_args. 0 indicates that the register is not
767 used for calling a function. */
768 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
770 /* Return the offset of register REGNO into the block returned by
771 __builtin_apply_args. This is not declared static, since it is
772 needed in objc-act.c. */
774 int
775 apply_args_register_offset (regno)
776 int regno;
778 apply_args_size ();
780 /* Arguments are always put in outgoing registers (in the argument
781 block) if such make sense. */
782 #ifdef OUTGOING_REGNO
783 regno = OUTGOING_REGNO(regno);
784 #endif
785 return apply_args_reg_offset[regno];
788 /* Return the size required for the block returned by __builtin_apply_args,
789 and initialize apply_args_mode. */
791 static int
792 apply_args_size ()
794 static int size = -1;
795 int align, regno;
796 enum machine_mode mode;
798 /* The values computed by this function never change. */
799 if (size < 0)
801 /* The first value is the incoming arg-pointer. */
802 size = GET_MODE_SIZE (Pmode);
804 /* The second value is the structure value address unless this is
805 passed as an "invisible" first argument. */
806 if (struct_value_rtx)
807 size += GET_MODE_SIZE (Pmode);
809 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
810 if (FUNCTION_ARG_REGNO_P (regno))
812 /* Search for the proper mode for copying this register's
813 value. I'm not sure this is right, but it works so far. */
814 enum machine_mode best_mode = VOIDmode;
816 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
817 mode != VOIDmode;
818 mode = GET_MODE_WIDER_MODE (mode))
819 if (HARD_REGNO_MODE_OK (regno, mode)
820 && HARD_REGNO_NREGS (regno, mode) == 1)
821 best_mode = mode;
823 if (best_mode == VOIDmode)
824 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
825 mode != VOIDmode;
826 mode = GET_MODE_WIDER_MODE (mode))
827 if (HARD_REGNO_MODE_OK (regno, mode)
828 && have_insn_for (SET, mode))
829 best_mode = mode;
831 mode = best_mode;
832 if (mode == VOIDmode)
833 abort ();
835 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
836 if (size % align != 0)
837 size = CEIL (size, align) * align;
838 apply_args_reg_offset[regno] = size;
839 size += GET_MODE_SIZE (mode);
840 apply_args_mode[regno] = mode;
842 else
844 apply_args_mode[regno] = VOIDmode;
845 apply_args_reg_offset[regno] = 0;
848 return size;
851 /* Return the size required for the block returned by __builtin_apply,
852 and initialize apply_result_mode. */
854 static int
855 apply_result_size ()
857 static int size = -1;
858 int align, regno;
859 enum machine_mode mode;
861 /* The values computed by this function never change. */
862 if (size < 0)
864 size = 0;
866 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
867 if (FUNCTION_VALUE_REGNO_P (regno))
869 /* Search for the proper mode for copying this register's
870 value. I'm not sure this is right, but it works so far. */
871 enum machine_mode best_mode = VOIDmode;
873 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
874 mode != TImode;
875 mode = GET_MODE_WIDER_MODE (mode))
876 if (HARD_REGNO_MODE_OK (regno, mode))
877 best_mode = mode;
879 if (best_mode == VOIDmode)
880 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
881 mode != VOIDmode;
882 mode = GET_MODE_WIDER_MODE (mode))
883 if (HARD_REGNO_MODE_OK (regno, mode)
884 && have_insn_for (SET, mode))
885 best_mode = mode;
887 mode = best_mode;
888 if (mode == VOIDmode)
889 abort ();
891 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
892 if (size % align != 0)
893 size = CEIL (size, align) * align;
894 size += GET_MODE_SIZE (mode);
895 apply_result_mode[regno] = mode;
897 else
898 apply_result_mode[regno] = VOIDmode;
900 /* Allow targets that use untyped_call and untyped_return to override
901 the size so that machine-specific information can be stored here. */
902 #ifdef APPLY_RESULT_SIZE
903 size = APPLY_RESULT_SIZE;
904 #endif
906 return size;
909 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
910 /* Create a vector describing the result block RESULT. If SAVEP is true,
911 the result block is used to save the values; otherwise it is used to
912 restore the values. */
914 static rtx
915 result_vector (savep, result)
916 int savep;
917 rtx result;
919 int regno, size, align, nelts;
920 enum machine_mode mode;
921 rtx reg, mem;
922 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
924 size = nelts = 0;
925 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
926 if ((mode = apply_result_mode[regno]) != VOIDmode)
928 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
929 if (size % align != 0)
930 size = CEIL (size, align) * align;
931 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
932 mem = adjust_address (result, mode, size);
933 savevec[nelts++] = (savep
934 ? gen_rtx_SET (VOIDmode, mem, reg)
935 : gen_rtx_SET (VOIDmode, reg, mem));
936 size += GET_MODE_SIZE (mode);
938 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
940 #endif /* HAVE_untyped_call or HAVE_untyped_return */
942 /* Save the state required to perform an untyped call with the same
943 arguments as were passed to the current function. */
945 static rtx
946 expand_builtin_apply_args_1 ()
948 rtx registers;
949 int size, align, regno;
950 enum machine_mode mode;
952 /* Create a block where the arg-pointer, structure value address,
953 and argument registers can be saved. */
954 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
956 /* Walk past the arg-pointer and structure value address. */
957 size = GET_MODE_SIZE (Pmode);
958 if (struct_value_rtx)
959 size += GET_MODE_SIZE (Pmode);
961 /* Save each register used in calling a function to the block. */
962 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
963 if ((mode = apply_args_mode[regno]) != VOIDmode)
965 rtx tem;
967 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
968 if (size % align != 0)
969 size = CEIL (size, align) * align;
971 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
973 emit_move_insn (adjust_address (registers, mode, size), tem);
974 size += GET_MODE_SIZE (mode);
977 /* Save the arg pointer to the block. */
978 emit_move_insn (adjust_address (registers, Pmode, 0),
979 copy_to_reg (virtual_incoming_args_rtx));
980 size = GET_MODE_SIZE (Pmode);
982 /* Save the structure value address unless this is passed as an
983 "invisible" first argument. */
984 if (struct_value_incoming_rtx)
986 emit_move_insn (adjust_address (registers, Pmode, size),
987 copy_to_reg (struct_value_incoming_rtx));
988 size += GET_MODE_SIZE (Pmode);
991 /* Return the address of the block. */
992 return copy_addr_to_reg (XEXP (registers, 0));
995 /* __builtin_apply_args returns block of memory allocated on
996 the stack into which is stored the arg pointer, structure
997 value address, static chain, and all the registers that might
998 possibly be used in performing a function call. The code is
999 moved to the start of the function so the incoming values are
1000 saved. */
1002 static rtx
1003 expand_builtin_apply_args ()
1005 /* Don't do __builtin_apply_args more than once in a function.
1006 Save the result of the first call and reuse it. */
1007 if (apply_args_value != 0)
1008 return apply_args_value;
1010 /* When this function is called, it means that registers must be
1011 saved on entry to this function. So we migrate the
1012 call to the first insn of this function. */
1013 rtx temp;
1014 rtx seq;
1016 start_sequence ();
1017 temp = expand_builtin_apply_args_1 ();
1018 seq = get_insns ();
1019 end_sequence ();
1021 apply_args_value = temp;
1023 /* Put the sequence after the NOTE that starts the function.
1024 If this is inside a SEQUENCE, make the outer-level insn
1025 chain current, so the code is placed at the start of the
1026 function. */
1027 push_topmost_sequence ();
1028 emit_insns_before (seq, NEXT_INSN (get_insns ()));
1029 pop_topmost_sequence ();
1030 return temp;
1034 /* Perform an untyped call and save the state required to perform an
1035 untyped return of whatever value was returned by the given function. */
1037 static rtx
1038 expand_builtin_apply (function, arguments, argsize)
1039 rtx function, arguments, argsize;
1041 int size, align, regno;
1042 enum machine_mode mode;
1043 rtx incoming_args, result, reg, dest, call_insn;
1044 rtx old_stack_level = 0;
1045 rtx call_fusage = 0;
1047 /* Create a block where the return registers can be saved. */
1048 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1050 /* Fetch the arg pointer from the ARGUMENTS block. */
1051 incoming_args = gen_reg_rtx (Pmode);
1052 emit_move_insn (incoming_args,
1053 gen_rtx_MEM (Pmode, arguments));
1054 #ifndef STACK_GROWS_DOWNWARD
1055 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1056 incoming_args, 0, OPTAB_LIB_WIDEN);
1057 #endif
1059 /* Perform postincrements before actually calling the function. */
1060 emit_queue ();
1062 /* Push a new argument block and copy the arguments. Do not allow
1063 the (potential) memcpy call below to interfere with our stack
1064 manipulations. */
1065 do_pending_stack_adjust ();
1066 NO_DEFER_POP;
1068 /* Save the stack with nonlocal if available */
1069 #ifdef HAVE_save_stack_nonlocal
1070 if (HAVE_save_stack_nonlocal)
1071 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1072 else
1073 #endif
1074 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1076 /* Push a block of memory onto the stack to store the memory arguments.
1077 Save the address in a register, and copy the memory arguments. ??? I
1078 haven't figured out how the calling convention macros effect this,
1079 but it's likely that the source and/or destination addresses in
1080 the block copy will need updating in machine specific ways. */
1081 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1082 emit_block_move (gen_rtx_MEM (BLKmode, dest),
1083 gen_rtx_MEM (BLKmode, incoming_args),
1084 argsize, PARM_BOUNDARY);
1086 /* Refer to the argument block. */
1087 apply_args_size ();
1088 arguments = gen_rtx_MEM (BLKmode, arguments);
1090 /* Walk past the arg-pointer and structure value address. */
1091 size = GET_MODE_SIZE (Pmode);
1092 if (struct_value_rtx)
1093 size += GET_MODE_SIZE (Pmode);
1095 /* Restore each of the registers previously saved. Make USE insns
1096 for each of these registers for use in making the call. */
1097 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1098 if ((mode = apply_args_mode[regno]) != VOIDmode)
1100 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1101 if (size % align != 0)
1102 size = CEIL (size, align) * align;
1103 reg = gen_rtx_REG (mode, regno);
1104 emit_move_insn (reg, adjust_address (arguments, mode, size));
1105 use_reg (&call_fusage, reg);
1106 size += GET_MODE_SIZE (mode);
1109 /* Restore the structure value address unless this is passed as an
1110 "invisible" first argument. */
1111 size = GET_MODE_SIZE (Pmode);
1112 if (struct_value_rtx)
1114 rtx value = gen_reg_rtx (Pmode);
1115 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1116 emit_move_insn (struct_value_rtx, value);
1117 if (GET_CODE (struct_value_rtx) == REG)
1118 use_reg (&call_fusage, struct_value_rtx);
1119 size += GET_MODE_SIZE (Pmode);
1122 /* All arguments and registers used for the call are set up by now! */
1123 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1125 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1126 and we don't want to load it into a register as an optimization,
1127 because prepare_call_address already did it if it should be done. */
1128 if (GET_CODE (function) != SYMBOL_REF)
1129 function = memory_address (FUNCTION_MODE, function);
1131 /* Generate the actual call instruction and save the return value. */
1132 #ifdef HAVE_untyped_call
1133 if (HAVE_untyped_call)
1134 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1135 result, result_vector (1, result)));
1136 else
1137 #endif
1138 #ifdef HAVE_call_value
1139 if (HAVE_call_value)
1141 rtx valreg = 0;
1143 /* Locate the unique return register. It is not possible to
1144 express a call that sets more than one return register using
1145 call_value; use untyped_call for that. In fact, untyped_call
1146 only needs to save the return registers in the given block. */
1147 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1148 if ((mode = apply_result_mode[regno]) != VOIDmode)
1150 if (valreg)
1151 abort (); /* HAVE_untyped_call required. */
1152 valreg = gen_rtx_REG (mode, regno);
1155 emit_call_insn (GEN_CALL_VALUE (valreg,
1156 gen_rtx_MEM (FUNCTION_MODE, function),
1157 const0_rtx, NULL_RTX, const0_rtx));
1159 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1161 else
1162 #endif
1163 abort ();
1165 /* Find the CALL insn we just emitted. */
1166 for (call_insn = get_last_insn ();
1167 call_insn && GET_CODE (call_insn) != CALL_INSN;
1168 call_insn = PREV_INSN (call_insn))
1171 if (! call_insn)
1172 abort ();
1174 /* Put the register usage information on the CALL. If there is already
1175 some usage information, put ours at the end. */
1176 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1178 rtx link;
1180 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1181 link = XEXP (link, 1))
1184 XEXP (link, 1) = call_fusage;
1186 else
1187 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1189 /* Restore the stack. */
1190 #ifdef HAVE_save_stack_nonlocal
1191 if (HAVE_save_stack_nonlocal)
1192 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1193 else
1194 #endif
1195 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1197 OK_DEFER_POP;
1199 /* Return the address of the result block. */
1200 return copy_addr_to_reg (XEXP (result, 0));
1203 /* Perform an untyped return. */
1205 static void
1206 expand_builtin_return (result)
1207 rtx result;
1209 int size, align, regno;
1210 enum machine_mode mode;
1211 rtx reg;
1212 rtx call_fusage = 0;
1214 apply_result_size ();
1215 result = gen_rtx_MEM (BLKmode, result);
1217 #ifdef HAVE_untyped_return
1218 if (HAVE_untyped_return)
1220 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1221 emit_barrier ();
1222 return;
1224 #endif
1226 /* Restore the return value and note that each value is used. */
1227 size = 0;
1228 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1229 if ((mode = apply_result_mode[regno]) != VOIDmode)
1231 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1232 if (size % align != 0)
1233 size = CEIL (size, align) * align;
1234 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1235 emit_move_insn (reg, adjust_address (result, mode, size));
1237 push_to_sequence (call_fusage);
1238 emit_insn (gen_rtx_USE (VOIDmode, reg));
1239 call_fusage = get_insns ();
1240 end_sequence ();
1241 size += GET_MODE_SIZE (mode);
1244 /* Put the USE insns before the return. */
1245 emit_insns (call_fusage);
1247 /* Return whatever values was restored by jumping directly to the end
1248 of the function. */
1249 expand_null_return ();
1252 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1254 static enum type_class
1255 type_to_class (type)
1256 tree type;
1258 switch (TREE_CODE (type))
1260 case VOID_TYPE: return void_type_class;
1261 case INTEGER_TYPE: return integer_type_class;
1262 case CHAR_TYPE: return char_type_class;
1263 case ENUMERAL_TYPE: return enumeral_type_class;
1264 case BOOLEAN_TYPE: return boolean_type_class;
1265 case POINTER_TYPE: return pointer_type_class;
1266 case REFERENCE_TYPE: return reference_type_class;
1267 case OFFSET_TYPE: return offset_type_class;
1268 case REAL_TYPE: return real_type_class;
1269 case COMPLEX_TYPE: return complex_type_class;
1270 case FUNCTION_TYPE: return function_type_class;
1271 case METHOD_TYPE: return method_type_class;
1272 case RECORD_TYPE: return record_type_class;
1273 case UNION_TYPE:
1274 case QUAL_UNION_TYPE: return union_type_class;
1275 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1276 ? string_type_class : array_type_class);
1277 case SET_TYPE: return set_type_class;
1278 case FILE_TYPE: return file_type_class;
1279 case LANG_TYPE: return lang_type_class;
1280 default: return no_type_class;
1284 /* Expand a call to __builtin_classify_type with arguments found in
1285 ARGLIST. */
1287 static rtx
1288 expand_builtin_classify_type (arglist)
1289 tree arglist;
1291 if (arglist != 0)
1292 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1293 return GEN_INT (no_type_class);
1296 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1298 static rtx
1299 expand_builtin_constant_p (exp)
1300 tree exp;
1302 tree arglist = TREE_OPERAND (exp, 1);
1303 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1304 rtx tmp;
1306 if (arglist == 0)
1307 return const0_rtx;
1308 arglist = TREE_VALUE (arglist);
1310 /* We have taken care of the easy cases during constant folding. This
1311 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1312 chance to see if it can deduce whether ARGLIST is constant. */
1314 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1315 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1316 return tmp;
1319 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1320 Return 0 if a normal call should be emitted rather than expanding the
1321 function in-line. EXP is the expression that is a call to the builtin
1322 function; if convenient, the result should be placed in TARGET.
1323 SUBTARGET may be used as the target for computing one of EXP's operands. */
1325 static rtx
1326 expand_builtin_mathfn (exp, target, subtarget)
1327 tree exp;
1328 rtx target, subtarget;
1330 optab builtin_optab;
1331 rtx op0, insns;
1332 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1333 tree arglist = TREE_OPERAND (exp, 1);
1335 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1336 return 0;
1338 /* Stabilize and compute the argument. */
1339 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1340 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1342 exp = copy_node (exp);
1343 TREE_OPERAND (exp, 1) = arglist;
1344 /* Wrap the computation of the argument in a SAVE_EXPR. That
1345 way, if we need to expand the argument again (as in the
1346 flag_errno_math case below where we cannot directly set
1347 errno), we will not perform side-effects more than once.
1348 Note that here we're mutating the original EXP as well as the
1349 copy; that's the right thing to do in case the original EXP
1350 is expanded later. */
1351 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1352 arglist = copy_node (arglist);
1354 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1356 /* Make a suitable register to place result in. */
1357 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1359 emit_queue ();
1360 start_sequence ();
1362 switch (DECL_FUNCTION_CODE (fndecl))
1364 case BUILT_IN_SIN:
1365 case BUILT_IN_SINF:
1366 case BUILT_IN_SINL:
1367 builtin_optab = sin_optab; break;
1368 case BUILT_IN_COS:
1369 case BUILT_IN_COSF:
1370 case BUILT_IN_COSL:
1371 builtin_optab = cos_optab; break;
1372 case BUILT_IN_FSQRT:
1373 case BUILT_IN_SQRTF:
1374 case BUILT_IN_SQRTL:
1375 builtin_optab = sqrt_optab; break;
1376 default:
1377 abort ();
1380 /* Compute into TARGET.
1381 Set TARGET to wherever the result comes back. */
1382 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1383 builtin_optab, op0, target, 0);
1385 /* If we were unable to expand via the builtin, stop the
1386 sequence (without outputting the insns) and return 0, causing
1387 a call to the library function. */
1388 if (target == 0)
1390 end_sequence ();
1391 return 0;
1394 /* If errno must be maintained and if we are not allowing unsafe
1395 math optimizations, check the result. */
1397 if (flag_errno_math && ! flag_unsafe_math_optimizations)
1399 rtx lab1;
1401 /* Don't define the builtin FP instructions
1402 if your machine is not IEEE. */
1403 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1404 abort ();
1406 lab1 = gen_label_rtx ();
1408 /* Test the result; if it is NaN, set errno=EDOM because
1409 the argument was not in the domain. */
1410 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1411 0, 0, lab1);
1413 #ifdef TARGET_EDOM
1415 #ifdef GEN_ERRNO_RTX
1416 rtx errno_rtx = GEN_ERRNO_RTX;
1417 #else
1418 rtx errno_rtx
1419 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1420 #endif
1422 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1424 #else
1425 /* We can't set errno=EDOM directly; let the library call do it.
1426 Pop the arguments right away in case the call gets deleted. */
1427 NO_DEFER_POP;
1428 expand_call (exp, target, 0);
1429 OK_DEFER_POP;
1430 #endif
1432 emit_label (lab1);
1435 /* Output the entire sequence. */
1436 insns = get_insns ();
1437 end_sequence ();
1438 emit_insns (insns);
1440 return target;
1443 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1444 if we failed the caller should emit a normal call, otherwise
1445 try to get the result in TARGET, if convenient. */
1447 static rtx
1448 expand_builtin_strlen (exp, target)
1449 tree exp;
1450 rtx target;
1452 tree arglist = TREE_OPERAND (exp, 1);
1453 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1455 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1456 return 0;
1457 else
1459 rtx pat;
1460 tree src = TREE_VALUE (arglist);
1462 int align
1463 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1465 rtx result, src_reg, char_rtx, before_strlen;
1466 enum machine_mode insn_mode = value_mode, char_mode;
1467 enum insn_code icode = CODE_FOR_nothing;
1469 /* If SRC is not a pointer type, don't do this operation inline. */
1470 if (align == 0)
1471 return 0;
1473 /* Bail out if we can't compute strlen in the right mode. */
1474 while (insn_mode != VOIDmode)
1476 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1477 if (icode != CODE_FOR_nothing)
1478 break;
1480 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1482 if (insn_mode == VOIDmode)
1483 return 0;
1485 /* Make a place to write the result of the instruction. */
1486 result = target;
1487 if (! (result != 0
1488 && GET_CODE (result) == REG
1489 && GET_MODE (result) == insn_mode
1490 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1491 result = gen_reg_rtx (insn_mode);
1493 /* Make a place to hold the source address. We will not expand
1494 the actual source until we are sure that the expansion will
1495 not fail -- there are trees that cannot be expanded twice. */
1496 src_reg = gen_reg_rtx (Pmode);
1498 /* Mark the beginning of the strlen sequence so we can emit the
1499 source operand later. */
1500 before_strlen = get_last_insn();
1502 /* Check the string is readable and has an end. */
1503 if (current_function_check_memory_usage)
1504 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1505 VOIDmode, 2, src_reg, Pmode,
1506 GEN_INT (MEMORY_USE_RO),
1507 TYPE_MODE (integer_type_node));
1509 char_rtx = const0_rtx;
1510 char_mode = insn_data[(int) icode].operand[2].mode;
1511 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1512 char_mode))
1513 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1515 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1516 char_rtx, GEN_INT (align));
1517 if (! pat)
1518 return 0;
1519 emit_insn (pat);
1521 /* Now that we are assured of success, expand the source. */
1522 start_sequence ();
1523 pat = memory_address (BLKmode,
1524 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1525 if (pat != src_reg)
1526 emit_move_insn (src_reg, pat);
1527 pat = gen_sequence ();
1528 end_sequence ();
1530 if (before_strlen)
1531 emit_insn_after (pat, before_strlen);
1532 else
1533 emit_insn_before (pat, get_insns ());
1535 /* Return the value in the proper mode for this function. */
1536 if (GET_MODE (result) == value_mode)
1537 target = result;
1538 else if (target != 0)
1539 convert_move (target, result, 0);
1540 else
1541 target = convert_to_mode (value_mode, result, 0);
1543 return target;
1547 /* Expand a call to the strstr builtin. Return 0 if we failed the
1548 caller should emit a normal call, otherwise try to get the result
1549 in TARGET, if convenient (and in mode MODE if that's convenient). */
1551 static rtx
1552 expand_builtin_strstr (arglist, target, mode)
1553 tree arglist;
1554 rtx target;
1555 enum machine_mode mode;
1557 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1558 || current_function_check_memory_usage)
1559 return 0;
1560 else
1562 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1563 tree fn;
1564 const char *p1, *p2;
1566 p2 = c_getstr (s2);
1567 if (p2 == NULL)
1568 return 0;
1570 p1 = c_getstr (s1);
1571 if (p1 != NULL)
1573 const char *r = strstr (p1, p2);
1575 if (r == NULL)
1576 return const0_rtx;
1578 /* Return an offset into the constant string argument. */
1579 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1580 s1, ssize_int (r - p1))),
1581 target, mode, EXPAND_NORMAL);
1584 if (p2[0] == '\0')
1585 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1587 if (p2[1] != '\0')
1588 return 0;
1590 fn = built_in_decls[BUILT_IN_STRCHR];
1591 if (!fn)
1592 return 0;
1594 /* New argument list transforming strstr(s1, s2) to
1595 strchr(s1, s2[0]). */
1596 arglist =
1597 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1598 arglist = tree_cons (NULL_TREE, s1, arglist);
1599 return expand_expr (build_function_call_expr (fn, arglist),
1600 target, mode, EXPAND_NORMAL);
1604 /* Expand a call to the strchr builtin. Return 0 if we failed the
1605 caller should emit a normal call, otherwise try to get the result
1606 in TARGET, if convenient (and in mode MODE if that's convenient). */
1608 static rtx
1609 expand_builtin_strchr (arglist, target, mode)
1610 tree arglist;
1611 rtx target;
1612 enum machine_mode mode;
1614 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1615 || current_function_check_memory_usage)
1616 return 0;
1617 else
1619 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1620 const char *p1;
1622 if (TREE_CODE (s2) != INTEGER_CST)
1623 return 0;
1625 p1 = c_getstr (s1);
1626 if (p1 != NULL)
1628 char c;
1629 const char *r;
1631 if (target_char_cast (s2, &c))
1632 return 0;
1634 r = strchr (p1, c);
1636 if (r == NULL)
1637 return const0_rtx;
1639 /* Return an offset into the constant string argument. */
1640 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1641 s1, ssize_int (r - p1))),
1642 target, mode, EXPAND_NORMAL);
1645 /* FIXME: Should use here strchrM optab so that ports can optimize
1646 this. */
1647 return 0;
1651 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1652 caller should emit a normal call, otherwise try to get the result
1653 in TARGET, if convenient (and in mode MODE if that's convenient). */
1655 static rtx
1656 expand_builtin_strrchr (arglist, target, mode)
1657 tree arglist;
1658 rtx target;
1659 enum machine_mode mode;
1661 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1662 || current_function_check_memory_usage)
1663 return 0;
1664 else
1666 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1667 tree fn;
1668 const char *p1;
1670 if (TREE_CODE (s2) != INTEGER_CST)
1671 return 0;
1673 p1 = c_getstr (s1);
1674 if (p1 != NULL)
1676 char c;
1677 const char *r;
1679 if (target_char_cast (s2, &c))
1680 return 0;
1682 r = strrchr (p1, c);
1684 if (r == NULL)
1685 return const0_rtx;
1687 /* Return an offset into the constant string argument. */
1688 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1689 s1, ssize_int (r - p1))),
1690 target, mode, EXPAND_NORMAL);
1693 if (! integer_zerop (s2))
1694 return 0;
1696 fn = built_in_decls[BUILT_IN_STRCHR];
1697 if (!fn)
1698 return 0;
1700 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1701 return expand_expr (build_function_call_expr (fn, arglist),
1702 target, mode, EXPAND_NORMAL);
1706 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1707 caller should emit a normal call, otherwise try to get the result
1708 in TARGET, if convenient (and in mode MODE if that's convenient). */
1710 static rtx
1711 expand_builtin_strpbrk (arglist, target, mode)
1712 tree arglist;
1713 rtx target;
1714 enum machine_mode mode;
1716 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1717 || current_function_check_memory_usage)
1718 return 0;
1719 else
1721 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1722 tree fn;
1723 const char *p1, *p2;
1725 p2 = c_getstr (s2);
1726 if (p2 == NULL)
1727 return 0;
1729 p1 = c_getstr (s1);
1730 if (p1 != NULL)
1732 const char *r = strpbrk (p1, p2);
1734 if (r == NULL)
1735 return const0_rtx;
1737 /* Return an offset into the constant string argument. */
1738 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1739 s1, ssize_int (r - p1))),
1740 target, mode, EXPAND_NORMAL);
1743 if (p2[0] == '\0')
1745 /* strpbrk(x, "") == NULL.
1746 Evaluate and ignore the arguments in case they had
1747 side-effects. */
1748 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1749 return const0_rtx;
1752 if (p2[1] != '\0')
1753 return 0; /* Really call strpbrk. */
1755 fn = built_in_decls[BUILT_IN_STRCHR];
1756 if (!fn)
1757 return 0;
1759 /* New argument list transforming strpbrk(s1, s2) to
1760 strchr(s1, s2[0]). */
1761 arglist =
1762 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1763 arglist = tree_cons (NULL_TREE, s1, arglist);
1764 return expand_expr (build_function_call_expr (fn, arglist),
1765 target, mode, EXPAND_NORMAL);
1769 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1770 bytes from constant string DATA + OFFSET and return it as target
1771 constant. */
1773 static rtx
1774 builtin_memcpy_read_str (data, offset, mode)
1775 PTR data;
1776 HOST_WIDE_INT offset;
1777 enum machine_mode mode;
1779 const char *str = (const char *) data;
1781 if (offset < 0
1782 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
1783 > strlen (str) + 1))
1784 abort (); /* Attempt to read past the end of constant string. */
1786 return c_readstr (str + offset, mode);
1789 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1791 static rtx
1792 expand_builtin_memcpy (arglist)
1793 tree arglist;
1795 if (!validate_arglist (arglist,
1796 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1797 return 0;
1798 else
1800 tree dest = TREE_VALUE (arglist);
1801 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1802 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1803 const char *src_str;
1805 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1806 unsigned int dest_align
1807 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1808 rtx dest_mem, src_mem, dest_addr, len_rtx;
1810 /* If either SRC or DEST is not a pointer type, don't do
1811 this operation in-line. */
1812 if (src_align == 0 || dest_align == 0)
1813 return 0;
1815 dest_mem = get_memory_rtx (dest);
1816 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1817 src_str = c_getstr (src);
1819 /* If SRC is a string constant and block move would be done
1820 by pieces, we can avoid loading the string from memory
1821 and only stored the computed constants. */
1822 if (src_str
1823 && !current_function_check_memory_usage
1824 && GET_CODE (len_rtx) == CONST_INT
1825 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
1826 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
1827 (PTR) src_str, dest_align))
1829 store_by_pieces (dest_mem, INTVAL (len_rtx),
1830 builtin_memcpy_read_str,
1831 (PTR) src_str, dest_align);
1832 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1835 src_mem = get_memory_rtx (src);
1837 /* Just copy the rights of SRC to the rights of DEST. */
1838 if (current_function_check_memory_usage)
1839 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1840 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1841 XEXP (src_mem, 0), Pmode,
1842 len_rtx, TYPE_MODE (sizetype));
1844 /* Copy word part most expediently. */
1845 dest_addr
1846 = emit_block_move (dest_mem, src_mem, len_rtx,
1847 MIN (src_align, dest_align));
1849 if (dest_addr == 0)
1850 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1852 return dest_addr;
1856 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1857 if we failed the caller should emit a normal call. */
1859 static rtx
1860 expand_builtin_strcpy (exp)
1861 tree exp;
1863 tree arglist = TREE_OPERAND (exp, 1);
1864 rtx result;
1866 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1867 return 0;
1868 else
1870 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1872 if (len == 0)
1873 return 0;
1875 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1876 chainon (arglist, build_tree_list (NULL_TREE, len));
1879 result = expand_builtin_memcpy (arglist);
1881 if (! result)
1882 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1883 return result;
1886 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1887 bytes from constant string DATA + OFFSET and return it as target
1888 constant. */
1890 static rtx
1891 builtin_strncpy_read_str (data, offset, mode)
1892 PTR data;
1893 HOST_WIDE_INT offset;
1894 enum machine_mode mode;
1896 const char *str = (const char *) data;
1898 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
1899 return const0_rtx;
1901 return c_readstr (str + offset, mode);
1904 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
1905 if we failed the caller should emit a normal call. */
1907 static rtx
1908 expand_builtin_strncpy (arglist, target, mode)
1909 tree arglist;
1910 rtx target;
1911 enum machine_mode mode;
1913 if (!validate_arglist (arglist,
1914 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1915 return 0;
1916 else
1918 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1919 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1921 /* We must be passed a constant len parameter. */
1922 if (TREE_CODE (len) != INTEGER_CST)
1923 return 0;
1925 /* If the len parameter is zero, return the dst parameter. */
1926 if (compare_tree_int (len, 0) == 0)
1928 /* Evaluate and ignore the src argument in case it has
1929 side-effects. */
1930 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
1931 VOIDmode, EXPAND_NORMAL);
1932 /* Return the dst parameter. */
1933 return expand_expr (TREE_VALUE (arglist), target, mode,
1934 EXPAND_NORMAL);
1937 /* Now, we must be passed a constant src ptr parameter. */
1938 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
1939 return 0;
1941 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
1943 /* We're required to pad with trailing zeros if the requested
1944 len is greater than strlen(s2)+1. In that case try to
1945 use store_by_pieces, if it fails, punt. */
1946 if (tree_int_cst_lt (slen, len))
1948 tree dest = TREE_VALUE (arglist);
1949 unsigned int dest_align
1950 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1951 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
1952 rtx dest_mem;
1954 if (!p || dest_align == 0 || !host_integerp (len, 1)
1955 || !can_store_by_pieces (tree_low_cst (len, 1),
1956 builtin_strncpy_read_str,
1957 (PTR) p, dest_align))
1958 return 0;
1960 dest_mem = get_memory_rtx (dest);
1961 store_by_pieces (dest_mem, tree_low_cst (len, 1),
1962 builtin_strncpy_read_str,
1963 (PTR) p, dest_align);
1964 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1967 /* OK transform into builtin memcpy. */
1968 return expand_builtin_memcpy (arglist);
1972 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1973 bytes from constant string DATA + OFFSET and return it as target
1974 constant. */
1976 static rtx
1977 builtin_memset_read_str (data, offset, mode)
1978 PTR data;
1979 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
1980 enum machine_mode mode;
1982 const char *c = (const char *) data;
1983 char *p = alloca (GET_MODE_SIZE (mode));
1985 memset (p, *c, GET_MODE_SIZE (mode));
1987 return c_readstr (p, mode);
1990 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1991 if we failed the caller should emit a normal call. */
1993 static rtx
1994 expand_builtin_memset (exp)
1995 tree exp;
1997 tree arglist = TREE_OPERAND (exp, 1);
1999 if (!validate_arglist (arglist,
2000 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2001 return 0;
2002 else
2004 tree dest = TREE_VALUE (arglist);
2005 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2006 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2007 char c;
2009 unsigned int dest_align
2010 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2011 rtx dest_mem, dest_addr, len_rtx;
2013 /* If DEST is not a pointer type, don't do this
2014 operation in-line. */
2015 if (dest_align == 0)
2016 return 0;
2018 if (TREE_CODE (val) != INTEGER_CST)
2019 return 0;
2021 if (target_char_cast (val, &c))
2022 return 0;
2024 if (c)
2026 if (!host_integerp (len, 1))
2027 return 0;
2028 if (current_function_check_memory_usage
2029 || !can_store_by_pieces (tree_low_cst (len, 1),
2030 builtin_memset_read_str,
2031 (PTR) &c, dest_align))
2032 return 0;
2034 dest_mem = get_memory_rtx (dest);
2035 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2036 builtin_memset_read_str,
2037 (PTR) &c, dest_align);
2038 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
2041 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2043 dest_mem = get_memory_rtx (dest);
2045 /* Just check DST is writable and mark it as readable. */
2046 if (current_function_check_memory_usage)
2047 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
2048 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
2049 len_rtx, TYPE_MODE (sizetype),
2050 GEN_INT (MEMORY_USE_WO),
2051 TYPE_MODE (integer_type_node));
2054 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
2056 if (dest_addr == 0)
2057 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2059 return dest_addr;
2063 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2064 if we failed the caller should emit a normal call. */
2066 static rtx
2067 expand_builtin_bzero (exp)
2068 tree exp;
2070 tree arglist = TREE_OPERAND (exp, 1);
2071 tree dest, size, newarglist;
2072 rtx result;
2074 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2075 return NULL_RTX;
2077 dest = TREE_VALUE (arglist);
2078 size = TREE_VALUE (TREE_CHAIN (arglist));
2080 /* New argument list transforming bzero(ptr x, int y) to
2081 memset(ptr x, int 0, size_t y). */
2083 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2084 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2085 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2087 TREE_OPERAND (exp, 1) = newarglist;
2088 result = expand_builtin_memset(exp);
2090 /* Always restore the original arguments. */
2091 TREE_OPERAND (exp, 1) = arglist;
2093 return result;
2096 #ifdef HAVE_cmpstrsi
2098 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2099 ARGLIST is the argument list for this call. Return 0 if we failed and the
2100 caller should emit a normal call, otherwise try to get the result in
2101 TARGET, if convenient. */
2103 static rtx
2104 expand_builtin_memcmp (exp, arglist, target)
2105 tree exp;
2106 tree arglist;
2107 rtx target;
2109 /* If we need to check memory accesses, call the library function. */
2110 if (current_function_check_memory_usage)
2111 return 0;
2113 if (!validate_arglist (arglist,
2114 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2115 return 0;
2118 enum machine_mode mode;
2119 tree arg1 = TREE_VALUE (arglist);
2120 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2121 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2122 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2123 rtx result;
2124 rtx insn;
2126 int arg1_align
2127 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2128 int arg2_align
2129 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2130 enum machine_mode insn_mode
2131 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2133 /* If we don't have POINTER_TYPE, call the function. */
2134 if (arg1_align == 0 || arg2_align == 0)
2135 return 0;
2137 /* Make a place to write the result of the instruction. */
2138 result = target;
2139 if (! (result != 0
2140 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2141 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2142 result = gen_reg_rtx (insn_mode);
2144 arg1_rtx = get_memory_rtx (arg1);
2145 arg2_rtx = get_memory_rtx (arg2);
2146 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2147 if (!HAVE_cmpstrsi)
2148 insn = NULL_RTX;
2149 else
2150 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2151 GEN_INT (MIN (arg1_align, arg2_align)));
2153 if (insn)
2154 emit_insn (insn);
2155 else
2156 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2157 TYPE_MODE (integer_type_node), 3,
2158 XEXP (arg1_rtx, 0), Pmode,
2159 XEXP (arg2_rtx, 0), Pmode,
2160 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2161 TREE_UNSIGNED (sizetype)),
2162 TYPE_MODE (sizetype));
2164 /* Return the value in the proper mode for this function. */
2165 mode = TYPE_MODE (TREE_TYPE (exp));
2166 if (GET_MODE (result) == mode)
2167 return result;
2168 else if (target != 0)
2170 convert_move (target, result, 0);
2171 return target;
2173 else
2174 return convert_to_mode (mode, result, 0);
2177 #endif
2179 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2180 if we failed the caller should emit a normal call, otherwise try to get
2181 the result in TARGET, if convenient. */
2183 static rtx
2184 expand_builtin_strcmp (exp, target, mode)
2185 tree exp;
2186 rtx target;
2187 enum machine_mode mode;
2189 tree arglist = TREE_OPERAND (exp, 1);
2190 tree arg1, arg2;
2191 const char *p1, *p2;
2193 /* If we need to check memory accesses, call the library function. */
2194 if (current_function_check_memory_usage)
2195 return 0;
2197 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2198 return 0;
2200 arg1 = TREE_VALUE (arglist);
2201 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2203 p1 = c_getstr (arg1);
2204 p2 = c_getstr (arg2);
2206 if (p1 && p2)
2208 const int i = strcmp (p1, p2);
2209 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2212 /* If either arg is "", return an expression corresponding to
2213 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2214 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2216 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2217 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2218 tree ind1 =
2219 fold (build1 (CONVERT_EXPR, integer_type_node,
2220 build1 (INDIRECT_REF, cst_uchar_node,
2221 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2222 tree ind2 =
2223 fold (build1 (CONVERT_EXPR, integer_type_node,
2224 build1 (INDIRECT_REF, cst_uchar_node,
2225 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2226 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2227 return expand_expr (result, target, mode, EXPAND_NORMAL);
2230 #ifdef HAVE_cmpstrsi
2231 if (! HAVE_cmpstrsi)
2232 return 0;
2235 tree len = c_strlen (arg1);
2236 tree len2 = c_strlen (arg2);
2237 rtx result;
2239 if (len)
2240 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2242 if (len2)
2243 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2245 /* If we don't have a constant length for the first, use the length
2246 of the second, if we know it. We don't require a constant for
2247 this case; some cost analysis could be done if both are available
2248 but neither is constant. For now, assume they're equally cheap
2249 unless one has side effects.
2251 If both strings have constant lengths, use the smaller. This
2252 could arise if optimization results in strcpy being called with
2253 two fixed strings, or if the code was machine-generated. We should
2254 add some code to the `memcmp' handler below to deal with such
2255 situations, someday. */
2257 if (!len || TREE_CODE (len) != INTEGER_CST)
2259 if (len2 && !TREE_SIDE_EFFECTS (len2))
2260 len = len2;
2261 else if (len == 0)
2262 return 0;
2264 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2265 && tree_int_cst_lt (len2, len))
2266 len = len2;
2268 /* If both arguments have side effects, we cannot optimize. */
2269 if (TREE_SIDE_EFFECTS (len))
2270 return 0;
2272 chainon (arglist, build_tree_list (NULL_TREE, len));
2273 result = expand_builtin_memcmp (exp, arglist, target);
2274 if (! result)
2275 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2277 return result;
2279 #else
2280 return 0;
2281 #endif
2284 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2285 if we failed the caller should emit a normal call, otherwise try to get
2286 the result in TARGET, if convenient. */
2288 static rtx
2289 expand_builtin_strncmp (exp, target, mode)
2290 tree exp;
2291 rtx target;
2292 enum machine_mode mode;
2294 tree arglist = TREE_OPERAND (exp, 1);
2295 tree arg1, arg2, arg3;
2296 const char *p1, *p2;
2298 /* If we need to check memory accesses, call the library function. */
2299 if (current_function_check_memory_usage)
2300 return 0;
2302 if (!validate_arglist (arglist,
2303 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2304 return 0;
2306 arg1 = TREE_VALUE (arglist);
2307 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2308 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2310 /* If the len parameter is zero, return zero. */
2311 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2313 /* Evaluate and ignore arg1 and arg2 in case they have
2314 side-effects. */
2315 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2316 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2317 return const0_rtx;
2320 p1 = c_getstr (arg1);
2321 p2 = c_getstr (arg2);
2323 /* If all arguments are constant, evaluate at compile-time. */
2324 if (host_integerp (arg3, 1) && p1 && p2)
2326 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2327 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2330 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2331 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2332 if (host_integerp (arg3, 1)
2333 && (tree_low_cst (arg3, 1) == 1
2334 || (tree_low_cst (arg3, 1) > 1
2335 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2337 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2338 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2339 tree ind1 =
2340 fold (build1 (CONVERT_EXPR, integer_type_node,
2341 build1 (INDIRECT_REF, cst_uchar_node,
2342 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2343 tree ind2 =
2344 fold (build1 (CONVERT_EXPR, integer_type_node,
2345 build1 (INDIRECT_REF, cst_uchar_node,
2346 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2347 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2348 return expand_expr (result, target, mode, EXPAND_NORMAL);
2351 #ifdef HAVE_cmpstrsi
2352 /* If c_strlen can determine an expression for one of the string
2353 lengths, and it doesn't have side effects, then call
2354 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
2355 if (HAVE_cmpstrsi)
2357 tree newarglist, len = 0;
2359 /* Perhaps one of the strings is really constant, if so prefer
2360 that constant length over the other string's length. */
2361 if (p1)
2362 len = c_strlen (arg1);
2363 else if (p2)
2364 len = c_strlen (arg2);
2366 /* If we still don't have a len, try either string arg as long
2367 as they don't have side effects. */
2368 if (!len && !TREE_SIDE_EFFECTS (arg1))
2369 len = c_strlen (arg1);
2370 if (!len && !TREE_SIDE_EFFECTS (arg2))
2371 len = c_strlen (arg2);
2372 /* If we still don't have a length, punt. */
2373 if (!len)
2374 return 0;
2376 /* Add one to the string length. */
2377 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2379 /* The actual new length parameter is MIN(len,arg3). */
2380 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2382 newarglist = build_tree_list (NULL_TREE, len);
2383 newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2384 newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2385 return expand_builtin_memcmp (exp, newarglist, target);
2387 #endif
2389 return 0;
2392 /* Expand expression EXP, which is a call to the strcat builtin.
2393 Return 0 if we failed the caller should emit a normal call,
2394 otherwise try to get the result in TARGET, if convenient. */
2396 static rtx
2397 expand_builtin_strcat (arglist, target, mode)
2398 tree arglist;
2399 rtx target;
2400 enum machine_mode mode;
2402 /* If we need to check memory accesses, call the library function. */
2403 if (current_function_check_memory_usage)
2404 return 0;
2406 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2407 return 0;
2408 else
2410 tree dst = TREE_VALUE (arglist),
2411 src = TREE_VALUE (TREE_CHAIN (arglist));
2412 const char *p = c_getstr (src);
2414 /* If the string length is zero, return the dst parameter. */
2415 if (p && *p == '\0')
2416 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2418 return 0;
2422 /* Expand expression EXP, which is a call to the strncat builtin.
2423 Return 0 if we failed the caller should emit a normal call,
2424 otherwise try to get the result in TARGET, if convenient. */
2426 static rtx
2427 expand_builtin_strncat (arglist, target, mode)
2428 tree arglist;
2429 rtx target;
2430 enum machine_mode mode;
2432 /* If we need to check memory accesses, call the library function. */
2433 if (current_function_check_memory_usage)
2434 return 0;
2436 if (!validate_arglist (arglist,
2437 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2438 return 0;
2439 else
2441 tree dst = TREE_VALUE (arglist),
2442 src = TREE_VALUE (TREE_CHAIN (arglist)),
2443 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2444 const char *p = c_getstr (src);
2446 /* If the requested length is zero, or the src parameter string
2447 length is zero, return the dst parameter. */
2448 if ((TREE_CODE (len) == INTEGER_CST && compare_tree_int (len, 0) == 0)
2449 || (p && *p == '\0'))
2451 /* Evaluate and ignore the src and len parameters in case
2452 they have side-effects. */
2453 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2454 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2455 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2458 /* If the requested len is greater than or equal to the string
2459 length, call strcat. */
2460 if (TREE_CODE (len) == INTEGER_CST && p
2461 && compare_tree_int (len, strlen (p)) >= 0)
2463 tree newarglist =
2464 tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)),
2465 fn = built_in_decls[BUILT_IN_STRCAT];
2467 /* If the replacement _DECL isn't initialized, don't do the
2468 transformation. */
2469 if (!fn)
2470 return 0;
2472 return expand_expr (build_function_call_expr (fn, newarglist),
2473 target, mode, EXPAND_NORMAL);
2475 return 0;
2479 /* Expand expression EXP, which is a call to the strspn builtin.
2480 Return 0 if we failed the caller should emit a normal call,
2481 otherwise try to get the result in TARGET, if convenient. */
2483 static rtx
2484 expand_builtin_strspn (arglist, target, mode)
2485 tree arglist;
2486 rtx target;
2487 enum machine_mode mode;
2489 /* If we need to check memory accesses, call the library function. */
2490 if (current_function_check_memory_usage)
2491 return 0;
2493 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2494 return 0;
2495 else
2497 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2498 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2500 /* If both arguments are constants, evaluate at compile-time. */
2501 if (p1 && p2)
2503 const size_t r = strspn (p1, p2);
2504 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2507 /* If either argument is "", return 0. */
2508 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2510 /* Evaluate and ignore both arguments in case either one has
2511 side-effects. */
2512 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2513 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2514 return const0_rtx;
2516 return 0;
2520 /* Expand expression EXP, which is a call to the strcspn builtin.
2521 Return 0 if we failed the caller should emit a normal call,
2522 otherwise try to get the result in TARGET, if convenient. */
2524 static rtx
2525 expand_builtin_strcspn (arglist, target, mode)
2526 tree arglist;
2527 rtx target;
2528 enum machine_mode mode;
2530 /* If we need to check memory accesses, call the library function. */
2531 if (current_function_check_memory_usage)
2532 return 0;
2534 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2535 return 0;
2536 else
2538 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2539 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2541 /* If both arguments are constants, evaluate at compile-time. */
2542 if (p1 && p2)
2544 const size_t r = strcspn (p1, p2);
2545 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2548 /* If the first argument is "", return 0. */
2549 if (p1 && *p1 == '\0')
2551 /* Evaluate and ignore argument s2 in case it has
2552 side-effects. */
2553 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2554 return const0_rtx;
2557 /* If the second argument is "", return __builtin_strlen(s1). */
2558 if (p2 && *p2 == '\0')
2560 tree newarglist = build_tree_list (NULL_TREE, s1),
2561 fn = built_in_decls[BUILT_IN_STRLEN];
2563 /* If the replacement _DECL isn't initialized, don't do the
2564 transformation. */
2565 if (!fn)
2566 return 0;
2568 return expand_expr (build_function_call_expr (fn, newarglist),
2569 target, mode, EXPAND_NORMAL);
2571 return 0;
2575 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2576 if that's convenient. */
2579 expand_builtin_saveregs ()
2581 rtx val, seq;
2583 /* Don't do __builtin_saveregs more than once in a function.
2584 Save the result of the first call and reuse it. */
2585 if (saveregs_value != 0)
2586 return saveregs_value;
2588 /* When this function is called, it means that registers must be
2589 saved on entry to this function. So we migrate the call to the
2590 first insn of this function. */
2592 start_sequence ();
2594 #ifdef EXPAND_BUILTIN_SAVEREGS
2595 /* Do whatever the machine needs done in this case. */
2596 val = EXPAND_BUILTIN_SAVEREGS ();
2597 #else
2598 /* ??? We used to try and build up a call to the out of line function,
2599 guessing about what registers needed saving etc. This became much
2600 harder with __builtin_va_start, since we don't have a tree for a
2601 call to __builtin_saveregs to fall back on. There was exactly one
2602 port (i860) that used this code, and I'm unconvinced it could actually
2603 handle the general case. So we no longer try to handle anything
2604 weird and make the backend absorb the evil. */
2606 error ("__builtin_saveregs not supported by this target");
2607 val = const0_rtx;
2608 #endif
2610 seq = get_insns ();
2611 end_sequence ();
2613 saveregs_value = val;
2615 /* Put the sequence after the NOTE that starts the function. If this
2616 is inside a SEQUENCE, make the outer-level insn chain current, so
2617 the code is placed at the start of the function. */
2618 push_topmost_sequence ();
2619 emit_insns_after (seq, get_insns ());
2620 pop_topmost_sequence ();
2622 return val;
2625 /* __builtin_args_info (N) returns word N of the arg space info
2626 for the current function. The number and meanings of words
2627 is controlled by the definition of CUMULATIVE_ARGS. */
2629 static rtx
2630 expand_builtin_args_info (exp)
2631 tree exp;
2633 tree arglist = TREE_OPERAND (exp, 1);
2634 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2635 int *word_ptr = (int *) &current_function_args_info;
2636 #if 0
2637 /* These are used by the code below that is if 0'ed away */
2638 int i;
2639 tree type, elts, result;
2640 #endif
2642 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2643 abort ();
2645 if (arglist != 0)
2647 if (!host_integerp (TREE_VALUE (arglist), 0))
2648 error ("argument of `__builtin_args_info' must be constant");
2649 else
2651 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
2653 if (wordnum < 0 || wordnum >= nwords)
2654 error ("argument of `__builtin_args_info' out of range");
2655 else
2656 return GEN_INT (word_ptr[wordnum]);
2659 else
2660 error ("missing argument in `__builtin_args_info'");
2662 return const0_rtx;
2664 #if 0
2665 for (i = 0; i < nwords; i++)
2666 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2668 type = build_array_type (integer_type_node,
2669 build_index_type (build_int_2 (nwords, 0)));
2670 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2671 TREE_CONSTANT (result) = 1;
2672 TREE_STATIC (result) = 1;
2673 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2674 TREE_CONSTANT (result) = 1;
2675 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2676 #endif
2679 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2681 static rtx
2682 expand_builtin_next_arg (arglist)
2683 tree arglist;
2685 tree fntype = TREE_TYPE (current_function_decl);
2687 if ((TYPE_ARG_TYPES (fntype) == 0
2688 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2689 == void_type_node))
2690 && ! current_function_varargs)
2692 error ("`va_start' used in function with fixed args");
2693 return const0_rtx;
2696 if (arglist)
2698 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2699 tree arg = TREE_VALUE (arglist);
2701 /* Strip off all nops for the sake of the comparison. This
2702 is not quite the same as STRIP_NOPS. It does more.
2703 We must also strip off INDIRECT_EXPR for C++ reference
2704 parameters. */
2705 while (TREE_CODE (arg) == NOP_EXPR
2706 || TREE_CODE (arg) == CONVERT_EXPR
2707 || TREE_CODE (arg) == NON_LVALUE_EXPR
2708 || TREE_CODE (arg) == INDIRECT_REF)
2709 arg = TREE_OPERAND (arg, 0);
2710 if (arg != last_parm)
2711 warning ("second parameter of `va_start' not last named argument");
2713 else if (! current_function_varargs)
2714 /* Evidently an out of date version of <stdarg.h>; can't validate
2715 va_start's second argument, but can still work as intended. */
2716 warning ("`__builtin_next_arg' called without an argument");
2718 return expand_binop (Pmode, add_optab,
2719 current_function_internal_arg_pointer,
2720 current_function_arg_offset_rtx,
2721 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2724 /* Make it easier for the backends by protecting the valist argument
2725 from multiple evaluations. */
2727 static tree
2728 stabilize_va_list (valist, needs_lvalue)
2729 tree valist;
2730 int needs_lvalue;
2732 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2734 if (TREE_SIDE_EFFECTS (valist))
2735 valist = save_expr (valist);
2737 /* For this case, the backends will be expecting a pointer to
2738 TREE_TYPE (va_list_type_node), but it's possible we've
2739 actually been given an array (an actual va_list_type_node).
2740 So fix it. */
2741 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2743 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2744 tree p2 = build_pointer_type (va_list_type_node);
2746 valist = build1 (ADDR_EXPR, p2, valist);
2747 valist = fold (build1 (NOP_EXPR, p1, valist));
2750 else
2752 tree pt;
2754 if (! needs_lvalue)
2756 if (! TREE_SIDE_EFFECTS (valist))
2757 return valist;
2759 pt = build_pointer_type (va_list_type_node);
2760 valist = fold (build1 (ADDR_EXPR, pt, valist));
2761 TREE_SIDE_EFFECTS (valist) = 1;
2764 if (TREE_SIDE_EFFECTS (valist))
2765 valist = save_expr (valist);
2766 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2767 valist));
2770 return valist;
2773 /* The "standard" implementation of va_start: just assign `nextarg' to
2774 the variable. */
2776 void
2777 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2778 int stdarg_p;
2779 tree valist;
2780 rtx nextarg;
2782 tree t;
2784 if (! stdarg_p)
2786 /* The dummy named parameter is declared as a 'word' sized
2787 object, but if a 'word' is smaller than an 'int', it would
2788 have been promoted to int when it was added to the arglist. */
2789 int align = PARM_BOUNDARY / BITS_PER_UNIT;
2790 int size = MAX (UNITS_PER_WORD,
2791 GET_MODE_SIZE (TYPE_MODE (integer_type_node)));
2792 int offset = ((size + align - 1) / align) * align;
2793 nextarg = plus_constant (nextarg, -offset);
2796 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2797 make_tree (ptr_type_node, nextarg));
2798 TREE_SIDE_EFFECTS (t) = 1;
2800 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2803 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2804 __builtin_varargs_va_start, depending on STDARG_P. */
2806 static rtx
2807 expand_builtin_va_start (stdarg_p, arglist)
2808 int stdarg_p;
2809 tree arglist;
2811 rtx nextarg;
2812 tree chain = arglist, valist;
2814 if (stdarg_p)
2815 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2816 else
2817 nextarg = expand_builtin_next_arg (NULL_TREE);
2819 if (TREE_CHAIN (chain))
2820 error ("too many arguments to function `va_start'");
2822 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2824 #ifdef EXPAND_BUILTIN_VA_START
2825 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2826 #else
2827 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2828 #endif
2830 return const0_rtx;
2833 /* The "standard" implementation of va_arg: read the value from the
2834 current (padded) address and increment by the (padded) size. */
2837 std_expand_builtin_va_arg (valist, type)
2838 tree valist, type;
2840 tree addr_tree, t;
2841 HOST_WIDE_INT align;
2842 HOST_WIDE_INT rounded_size;
2843 rtx addr;
2845 /* Compute the rounded size of the type. */
2846 align = PARM_BOUNDARY / BITS_PER_UNIT;
2847 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2849 /* Get AP. */
2850 addr_tree = valist;
2851 if (PAD_VARARGS_DOWN)
2853 /* Small args are padded downward. */
2855 HOST_WIDE_INT adj
2856 = rounded_size > align ? rounded_size : int_size_in_bytes (type);
2858 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2859 build_int_2 (rounded_size - adj, 0));
2862 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2863 addr = copy_to_reg (addr);
2865 /* Compute new value for AP. */
2866 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2867 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2868 build_int_2 (rounded_size, 0)));
2869 TREE_SIDE_EFFECTS (t) = 1;
2870 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2872 return addr;
2875 /* Expand __builtin_va_arg, which is not really a builtin function, but
2876 a very special sort of operator. */
2879 expand_builtin_va_arg (valist, type)
2880 tree valist, type;
2882 rtx addr, result;
2883 tree promoted_type, want_va_type, have_va_type;
2885 /* Verify that valist is of the proper type. */
2887 want_va_type = va_list_type_node;
2888 have_va_type = TREE_TYPE (valist);
2889 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2891 /* If va_list is an array type, the argument may have decayed
2892 to a pointer type, e.g. by being passed to another function.
2893 In that case, unwrap both types so that we can compare the
2894 underlying records. */
2895 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2896 || TREE_CODE (have_va_type) == POINTER_TYPE)
2898 want_va_type = TREE_TYPE (want_va_type);
2899 have_va_type = TREE_TYPE (have_va_type);
2902 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2904 error ("first argument to `va_arg' not of type `va_list'");
2905 addr = const0_rtx;
2908 /* Generate a diagnostic for requesting data of a type that cannot
2909 be passed through `...' due to type promotion at the call site. */
2910 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2912 const char *name = "<anonymous type>", *pname = 0;
2913 static int gave_help;
2915 if (TYPE_NAME (type))
2917 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2918 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2919 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2920 && DECL_NAME (TYPE_NAME (type)))
2921 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2923 if (TYPE_NAME (promoted_type))
2925 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2926 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2927 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2928 && DECL_NAME (TYPE_NAME (promoted_type)))
2929 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2932 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2933 if (! gave_help)
2935 gave_help = 1;
2936 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2939 addr = const0_rtx;
2941 else
2943 /* Make it easier for the backends by protecting the valist argument
2944 from multiple evaluations. */
2945 valist = stabilize_va_list (valist, 0);
2947 #ifdef EXPAND_BUILTIN_VA_ARG
2948 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2949 #else
2950 addr = std_expand_builtin_va_arg (valist, type);
2951 #endif
2954 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2955 set_mem_alias_set (result, get_varargs_alias_set ());
2957 return result;
2960 /* Expand ARGLIST, from a call to __builtin_va_end. */
2962 static rtx
2963 expand_builtin_va_end (arglist)
2964 tree arglist;
2966 tree valist = TREE_VALUE (arglist);
2968 #ifdef EXPAND_BUILTIN_VA_END
2969 valist = stabilize_va_list (valist, 0);
2970 EXPAND_BUILTIN_VA_END(arglist);
2971 #else
2972 /* Evaluate for side effects, if needed. I hate macros that don't
2973 do that. */
2974 if (TREE_SIDE_EFFECTS (valist))
2975 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2976 #endif
2978 return const0_rtx;
2981 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2982 builtin rather than just as an assignment in stdarg.h because of the
2983 nastiness of array-type va_list types. */
2985 static rtx
2986 expand_builtin_va_copy (arglist)
2987 tree arglist;
2989 tree dst, src, t;
2991 dst = TREE_VALUE (arglist);
2992 src = TREE_VALUE (TREE_CHAIN (arglist));
2994 dst = stabilize_va_list (dst, 1);
2995 src = stabilize_va_list (src, 0);
2997 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2999 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3000 TREE_SIDE_EFFECTS (t) = 1;
3001 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3003 else
3005 rtx dstb, srcb, size;
3007 /* Evaluate to pointers. */
3008 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3009 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3010 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3011 VOIDmode, EXPAND_NORMAL);
3013 /* "Dereference" to BLKmode memories. */
3014 dstb = gen_rtx_MEM (BLKmode, dstb);
3015 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3016 srcb = gen_rtx_MEM (BLKmode, srcb);
3017 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3019 /* Copy. */
3020 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
3023 return const0_rtx;
3026 /* Expand a call to one of the builtin functions __builtin_frame_address or
3027 __builtin_return_address. */
3029 static rtx
3030 expand_builtin_frame_address (exp)
3031 tree exp;
3033 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3034 tree arglist = TREE_OPERAND (exp, 1);
3036 /* The argument must be a nonnegative integer constant.
3037 It counts the number of frames to scan up the stack.
3038 The value is the return address saved in that frame. */
3039 if (arglist == 0)
3040 /* Warning about missing arg was already issued. */
3041 return const0_rtx;
3042 else if (! host_integerp (TREE_VALUE (arglist), 1))
3044 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3045 error ("invalid arg to `__builtin_frame_address'");
3046 else
3047 error ("invalid arg to `__builtin_return_address'");
3048 return const0_rtx;
3050 else
3052 rtx tem
3053 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3054 tree_low_cst (TREE_VALUE (arglist), 1),
3055 hard_frame_pointer_rtx);
3057 /* Some ports cannot access arbitrary stack frames. */
3058 if (tem == NULL)
3060 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3061 warning ("unsupported arg to `__builtin_frame_address'");
3062 else
3063 warning ("unsupported arg to `__builtin_return_address'");
3064 return const0_rtx;
3067 /* For __builtin_frame_address, return what we've got. */
3068 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3069 return tem;
3071 if (GET_CODE (tem) != REG
3072 && ! CONSTANT_P (tem))
3073 tem = copy_to_mode_reg (Pmode, tem);
3074 return tem;
3078 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3079 we failed and the caller should emit a normal call, otherwise try to get
3080 the result in TARGET, if convenient. */
3082 static rtx
3083 expand_builtin_alloca (arglist, target)
3084 tree arglist;
3085 rtx target;
3087 rtx op0;
3088 rtx result;
3090 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3091 return 0;
3093 /* Compute the argument. */
3094 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3096 /* Allocate the desired space. */
3097 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3099 #ifdef POINTERS_EXTEND_UNSIGNED
3100 result = convert_memory_address (ptr_mode, result);
3101 #endif
3103 return result;
3106 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
3107 Return 0 if a normal call should be emitted rather than expanding the
3108 function in-line. If convenient, the result should be placed in TARGET.
3109 SUBTARGET may be used as the target for computing one of EXP's operands. */
3111 static rtx
3112 expand_builtin_ffs (arglist, target, subtarget)
3113 tree arglist;
3114 rtx target, subtarget;
3116 rtx op0;
3117 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3118 return 0;
3120 /* Compute the argument. */
3121 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3122 /* Compute ffs, into TARGET if possible.
3123 Set TARGET to wherever the result comes back. */
3124 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3125 ffs_optab, op0, target, 1);
3126 if (target == 0)
3127 abort ();
3128 return target;
3131 /* If the string passed to fputs is a constant and is one character
3132 long, we attempt to transform this call into __builtin_fputc(). */
3134 static rtx
3135 expand_builtin_fputs (arglist, ignore)
3136 tree arglist;
3137 int ignore;
3139 tree len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
3140 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
3142 /* If the return value is used, or the replacement _DECL isn't
3143 initialized, don't do the transformation. */
3144 if (!ignore || !fn_fputc || !fn_fwrite)
3145 return 0;
3147 /* Verify the arguments in the original call. */
3148 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
3149 || current_function_check_memory_usage)
3150 return 0;
3152 /* Get the length of the string passed to fputs. If the length
3153 can't be determined, punt. */
3154 if (!(len = c_strlen (TREE_VALUE (arglist)))
3155 || TREE_CODE (len) != INTEGER_CST)
3156 return 0;
3158 switch (compare_tree_int (len, 1))
3160 case -1: /* length is 0, delete the call entirely . */
3162 /* Evaluate and ignore the argument in case it has
3163 side-effects. */
3164 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3165 VOIDmode, EXPAND_NORMAL);
3166 return const0_rtx;
3168 case 0: /* length is 1, call fputc. */
3170 const char *p = c_getstr (TREE_VALUE (arglist));
3172 if (p != NULL)
3174 /* New argument list transforming fputs(string, stream) to
3175 fputc(string[0], stream). */
3176 arglist =
3177 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3178 arglist =
3179 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3180 fn = fn_fputc;
3181 break;
3184 /* FALLTHROUGH */
3185 case 1: /* length is greater than 1, call fwrite. */
3187 tree string_arg = TREE_VALUE (arglist);
3189 /* New argument list transforming fputs(string, stream) to
3190 fwrite(string, 1, len, stream). */
3191 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3192 arglist = tree_cons (NULL_TREE, len, arglist);
3193 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3194 arglist = tree_cons (NULL_TREE, string_arg, arglist);
3195 fn = fn_fwrite;
3196 break;
3198 default:
3199 abort();
3202 return expand_expr (build_function_call_expr (fn, arglist),
3203 (ignore ? const0_rtx : NULL_RTX),
3204 VOIDmode, EXPAND_NORMAL);
3207 /* Expand a call to __builtin_expect. We return our argument and emit a
3208 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3209 a non-jump context. */
3211 static rtx
3212 expand_builtin_expect (arglist, target)
3213 tree arglist;
3214 rtx target;
3216 tree exp, c;
3217 rtx note, rtx_c;
3219 if (arglist == NULL_TREE
3220 || TREE_CHAIN (arglist) == NULL_TREE)
3221 return const0_rtx;
3222 exp = TREE_VALUE (arglist);
3223 c = TREE_VALUE (TREE_CHAIN (arglist));
3225 if (TREE_CODE (c) != INTEGER_CST)
3227 error ("second arg to `__builtin_expect' must be a constant");
3228 c = integer_zero_node;
3231 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3233 /* Don't bother with expected value notes for integral constants. */
3234 if (GET_CODE (target) != CONST_INT)
3236 /* We do need to force this into a register so that we can be
3237 moderately sure to be able to correctly interpret the branch
3238 condition later. */
3239 target = force_reg (GET_MODE (target), target);
3241 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3243 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3244 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3247 return target;
3250 /* Like expand_builtin_expect, except do this in a jump context. This is
3251 called from do_jump if the conditional is a __builtin_expect. Return either
3252 a SEQUENCE of insns to emit the jump or NULL if we cannot optimize
3253 __builtin_expect. We need to optimize this at jump time so that machines
3254 like the PowerPC don't turn the test into a SCC operation, and then jump
3255 based on the test being 0/1. */
3258 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3259 tree exp;
3260 rtx if_false_label;
3261 rtx if_true_label;
3263 tree arglist = TREE_OPERAND (exp, 1);
3264 tree arg0 = TREE_VALUE (arglist);
3265 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3266 rtx ret = NULL_RTX;
3268 /* Only handle __builtin_expect (test, 0) and
3269 __builtin_expect (test, 1). */
3270 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3271 && (integer_zerop (arg1) || integer_onep (arg1)))
3273 int j;
3274 int num_jumps = 0;
3276 /* If we fail to locate an appropriate conditional jump, we'll
3277 fall back to normal evaluation. Ensure that the expression
3278 can be re-evaluated. */
3279 switch (unsafe_for_reeval (arg0))
3281 case 0: /* Safe. */
3282 break;
3284 case 1: /* Mildly unsafe. */
3285 arg0 = unsave_expr (arg0);
3286 break;
3288 case 2: /* Wildly unsafe. */
3289 return NULL_RTX;
3292 /* Expand the jump insns. */
3293 start_sequence ();
3294 do_jump (arg0, if_false_label, if_true_label);
3295 ret = gen_sequence ();
3296 end_sequence ();
3298 /* Now that the __builtin_expect has been validated, go through and add
3299 the expect's to each of the conditional jumps. If we run into an
3300 error, just give up and generate the 'safe' code of doing a SCC
3301 operation and then doing a branch on that. */
3302 for (j = 0; j < XVECLEN (ret, 0); j++)
3304 rtx insn = XVECEXP (ret, 0, j);
3305 rtx pattern;
3307 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3308 && (pattern = pc_set (insn)) != NULL_RTX)
3310 rtx ifelse = SET_SRC (pattern);
3311 rtx label;
3312 int taken;
3314 if (GET_CODE (ifelse) != IF_THEN_ELSE)
3315 continue;
3317 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3319 taken = 1;
3320 label = XEXP (XEXP (ifelse, 1), 0);
3322 /* An inverted jump reverses the probabilities. */
3323 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3325 taken = 0;
3326 label = XEXP (XEXP (ifelse, 2), 0);
3328 /* We shouldn't have to worry about conditional returns during
3329 the expansion stage, but handle it gracefully anyway. */
3330 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3332 taken = 1;
3333 label = NULL_RTX;
3335 /* An inverted return reverses the probabilities. */
3336 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3338 taken = 0;
3339 label = NULL_RTX;
3341 else
3342 continue;
3344 /* If the test is expected to fail, reverse the
3345 probabilities. */
3346 if (integer_zerop (arg1))
3347 taken = 1 - taken;
3349 /* If we are jumping to the false label, reverse the
3350 probabilities. */
3351 if (label == NULL_RTX)
3352 ; /* conditional return */
3353 else if (label == if_false_label)
3354 taken = 1 - taken;
3355 else if (label != if_true_label)
3356 continue;
3358 num_jumps++;
3359 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3363 /* If no jumps were modified, fail and do __builtin_expect the normal
3364 way. */
3365 if (num_jumps == 0)
3366 ret = NULL_RTX;
3369 return ret;
3372 /* Expand an expression EXP that calls a built-in function,
3373 with result going to TARGET if that's convenient
3374 (and in mode MODE if that's convenient).
3375 SUBTARGET may be used as the target for computing one of EXP's operands.
3376 IGNORE is nonzero if the value is to be ignored. */
3379 expand_builtin (exp, target, subtarget, mode, ignore)
3380 tree exp;
3381 rtx target;
3382 rtx subtarget;
3383 enum machine_mode mode;
3384 int ignore;
3386 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3387 tree arglist = TREE_OPERAND (exp, 1);
3388 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3390 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3391 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
3393 /* When not optimizing, generate calls to library functions for a certain
3394 set of builtins. */
3395 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
3396 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
3397 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_SQRTF
3398 || fcode == BUILT_IN_SQRTL || fcode == BUILT_IN_MEMSET
3399 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
3400 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
3401 || fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
3402 || fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
3403 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
3404 || fcode == BUILT_IN_STRNCPY || fcode == BUILT_IN_STRNCMP
3405 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
3406 || fcode == BUILT_IN_STRCAT || fcode == BUILT_IN_STRNCAT
3407 || fcode == BUILT_IN_STRSPN || fcode == BUILT_IN_STRCSPN
3408 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
3409 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
3410 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
3411 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
3412 return expand_call (exp, target, ignore);
3414 switch (fcode)
3416 case BUILT_IN_ABS:
3417 case BUILT_IN_LABS:
3418 case BUILT_IN_LLABS:
3419 case BUILT_IN_IMAXABS:
3420 case BUILT_IN_FABS:
3421 case BUILT_IN_FABSF:
3422 case BUILT_IN_FABSL:
3423 /* build_function_call changes these into ABS_EXPR. */
3424 abort ();
3426 case BUILT_IN_CONJ:
3427 case BUILT_IN_CONJF:
3428 case BUILT_IN_CONJL:
3429 case BUILT_IN_CREAL:
3430 case BUILT_IN_CREALF:
3431 case BUILT_IN_CREALL:
3432 case BUILT_IN_CIMAG:
3433 case BUILT_IN_CIMAGF:
3434 case BUILT_IN_CIMAGL:
3435 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3436 and IMAGPART_EXPR. */
3437 abort ();
3439 case BUILT_IN_SIN:
3440 case BUILT_IN_SINF:
3441 case BUILT_IN_SINL:
3442 case BUILT_IN_COS:
3443 case BUILT_IN_COSF:
3444 case BUILT_IN_COSL:
3445 /* Treat these like sqrt only if unsafe math optimizations are allowed,
3446 because of possible accuracy problems. */
3447 if (! flag_unsafe_math_optimizations)
3448 break;
3449 case BUILT_IN_FSQRT:
3450 case BUILT_IN_SQRTF:
3451 case BUILT_IN_SQRTL:
3452 target = expand_builtin_mathfn (exp, target, subtarget);
3453 if (target)
3454 return target;
3455 break;
3457 case BUILT_IN_FMOD:
3458 break;
3460 case BUILT_IN_APPLY_ARGS:
3461 return expand_builtin_apply_args ();
3463 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3464 FUNCTION with a copy of the parameters described by
3465 ARGUMENTS, and ARGSIZE. It returns a block of memory
3466 allocated on the stack into which is stored all the registers
3467 that might possibly be used for returning the result of a
3468 function. ARGUMENTS is the value returned by
3469 __builtin_apply_args. ARGSIZE is the number of bytes of
3470 arguments that must be copied. ??? How should this value be
3471 computed? We'll also need a safe worst case value for varargs
3472 functions. */
3473 case BUILT_IN_APPLY:
3474 if (!validate_arglist (arglist, POINTER_TYPE,
3475 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
3476 && !validate_arglist (arglist, REFERENCE_TYPE,
3477 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3478 return const0_rtx;
3479 else
3481 int i;
3482 tree t;
3483 rtx ops[3];
3485 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
3486 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
3488 return expand_builtin_apply (ops[0], ops[1], ops[2]);
3491 /* __builtin_return (RESULT) causes the function to return the
3492 value described by RESULT. RESULT is address of the block of
3493 memory returned by __builtin_apply. */
3494 case BUILT_IN_RETURN:
3495 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3496 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
3497 NULL_RTX, VOIDmode, 0));
3498 return const0_rtx;
3500 case BUILT_IN_SAVEREGS:
3501 return expand_builtin_saveregs ();
3503 case BUILT_IN_ARGS_INFO:
3504 return expand_builtin_args_info (exp);
3506 /* Return the address of the first anonymous stack arg. */
3507 case BUILT_IN_NEXT_ARG:
3508 return expand_builtin_next_arg (arglist);
3510 case BUILT_IN_CLASSIFY_TYPE:
3511 return expand_builtin_classify_type (arglist);
3513 case BUILT_IN_CONSTANT_P:
3514 return expand_builtin_constant_p (exp);
3516 case BUILT_IN_FRAME_ADDRESS:
3517 case BUILT_IN_RETURN_ADDRESS:
3518 return expand_builtin_frame_address (exp);
3520 /* Returns the address of the area where the structure is returned.
3521 0 otherwise. */
3522 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
3523 if (arglist != 0
3524 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3525 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
3526 return const0_rtx;
3527 else
3528 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3530 case BUILT_IN_ALLOCA:
3531 target = expand_builtin_alloca (arglist, target);
3532 if (target)
3533 return target;
3534 break;
3536 case BUILT_IN_FFS:
3537 target = expand_builtin_ffs (arglist, target, subtarget);
3538 if (target)
3539 return target;
3540 break;
3542 case BUILT_IN_STRLEN:
3543 target = expand_builtin_strlen (exp, target);
3544 if (target)
3545 return target;
3546 break;
3548 case BUILT_IN_STRCPY:
3549 target = expand_builtin_strcpy (exp);
3550 if (target)
3551 return target;
3552 break;
3554 case BUILT_IN_STRNCPY:
3555 target = expand_builtin_strncpy (arglist, target, mode);
3556 if (target)
3557 return target;
3558 break;
3560 case BUILT_IN_STRCAT:
3561 target = expand_builtin_strcat (arglist, target, mode);
3562 if (target)
3563 return target;
3564 break;
3566 case BUILT_IN_STRNCAT:
3567 target = expand_builtin_strncat (arglist, target, mode);
3568 if (target)
3569 return target;
3570 break;
3572 case BUILT_IN_STRSPN:
3573 target = expand_builtin_strspn (arglist, target, mode);
3574 if (target)
3575 return target;
3576 break;
3578 case BUILT_IN_STRCSPN:
3579 target = expand_builtin_strcspn (arglist, target, mode);
3580 if (target)
3581 return target;
3582 break;
3584 case BUILT_IN_STRSTR:
3585 target = expand_builtin_strstr (arglist, target, mode);
3586 if (target)
3587 return target;
3588 break;
3590 case BUILT_IN_STRPBRK:
3591 target = expand_builtin_strpbrk (arglist, target, mode);
3592 if (target)
3593 return target;
3594 break;
3596 case BUILT_IN_INDEX:
3597 case BUILT_IN_STRCHR:
3598 target = expand_builtin_strchr (arglist, target, mode);
3599 if (target)
3600 return target;
3601 break;
3603 case BUILT_IN_RINDEX:
3604 case BUILT_IN_STRRCHR:
3605 target = expand_builtin_strrchr (arglist, target, mode);
3606 if (target)
3607 return target;
3608 break;
3610 case BUILT_IN_MEMCPY:
3611 target = expand_builtin_memcpy (arglist);
3612 if (target)
3613 return target;
3614 break;
3616 case BUILT_IN_MEMSET:
3617 target = expand_builtin_memset (exp);
3618 if (target)
3619 return target;
3620 break;
3622 case BUILT_IN_BZERO:
3623 target = expand_builtin_bzero (exp);
3624 if (target)
3625 return target;
3626 break;
3628 case BUILT_IN_STRCMP:
3629 target = expand_builtin_strcmp (exp, target, mode);
3630 if (target)
3631 return target;
3632 break;
3634 case BUILT_IN_STRNCMP:
3635 target = expand_builtin_strncmp (exp, target, mode);
3636 if (target)
3637 return target;
3638 break;
3640 /* These comparison functions need an instruction that returns an actual
3641 index. An ordinary compare that just sets the condition codes
3642 is not enough. */
3643 #ifdef HAVE_cmpstrsi
3644 case BUILT_IN_BCMP:
3645 case BUILT_IN_MEMCMP:
3646 target = expand_builtin_memcmp (exp, arglist, target);
3647 if (target)
3648 return target;
3649 break;
3650 #else
3651 case BUILT_IN_BCMP:
3652 case BUILT_IN_MEMCMP:
3653 break;
3654 #endif
3656 case BUILT_IN_SETJMP:
3657 target = expand_builtin_setjmp (arglist, target);
3658 if (target)
3659 return target;
3660 break;
3662 /* __builtin_longjmp is passed a pointer to an array of five words.
3663 It's similar to the C library longjmp function but works with
3664 __builtin_setjmp above. */
3665 case BUILT_IN_LONGJMP:
3666 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3667 break;
3668 else
3670 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3671 VOIDmode, 0);
3672 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
3673 NULL_RTX, VOIDmode, 0);
3675 if (value != const1_rtx)
3677 error ("__builtin_longjmp second argument must be 1");
3678 return const0_rtx;
3681 expand_builtin_longjmp (buf_addr, value);
3682 return const0_rtx;
3685 case BUILT_IN_TRAP:
3686 #ifdef HAVE_trap
3687 if (HAVE_trap)
3688 emit_insn (gen_trap ());
3689 else
3690 #endif
3691 error ("__builtin_trap not supported by this target");
3692 emit_barrier ();
3693 return const0_rtx;
3695 case BUILT_IN_PUTCHAR:
3696 case BUILT_IN_PUTS:
3697 case BUILT_IN_FPUTC:
3698 case BUILT_IN_FWRITE:
3699 break;
3700 case BUILT_IN_FPUTS:
3701 target = expand_builtin_fputs (arglist, ignore);
3702 if (target)
3703 return target;
3704 break;
3706 /* Various hooks for the DWARF 2 __throw routine. */
3707 case BUILT_IN_UNWIND_INIT:
3708 expand_builtin_unwind_init ();
3709 return const0_rtx;
3710 case BUILT_IN_DWARF_CFA:
3711 return virtual_cfa_rtx;
3712 #ifdef DWARF2_UNWIND_INFO
3713 case BUILT_IN_DWARF_FP_REGNUM:
3714 return expand_builtin_dwarf_fp_regnum ();
3715 case BUILT_IN_INIT_DWARF_REG_SIZES:
3716 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3717 return const0_rtx;
3718 #endif
3719 case BUILT_IN_FROB_RETURN_ADDR:
3720 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3721 case BUILT_IN_EXTRACT_RETURN_ADDR:
3722 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3723 case BUILT_IN_EH_RETURN:
3724 expand_builtin_eh_return (TREE_VALUE (arglist),
3725 TREE_VALUE (TREE_CHAIN (arglist)));
3726 return const0_rtx;
3727 #ifdef EH_RETURN_DATA_REGNO
3728 case BUILT_IN_EH_RETURN_DATA_REGNO:
3729 return expand_builtin_eh_return_data_regno (arglist);
3730 #endif
3731 case BUILT_IN_VARARGS_START:
3732 return expand_builtin_va_start (0, arglist);
3733 case BUILT_IN_STDARG_START:
3734 return expand_builtin_va_start (1, arglist);
3735 case BUILT_IN_VA_END:
3736 return expand_builtin_va_end (arglist);
3737 case BUILT_IN_VA_COPY:
3738 return expand_builtin_va_copy (arglist);
3739 case BUILT_IN_EXPECT:
3740 return expand_builtin_expect (arglist, target);
3742 default: /* just do library call, if unknown builtin */
3743 error ("built-in function `%s' not currently supported",
3744 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3747 /* The switch statement above can drop through to cause the function
3748 to be called normally. */
3749 return expand_call (exp, target, ignore);
3752 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3753 constant. ARGLIST is the argument list of the call. */
3755 static tree
3756 fold_builtin_constant_p (arglist)
3757 tree arglist;
3759 if (arglist == 0)
3760 return 0;
3762 arglist = TREE_VALUE (arglist);
3764 /* We return 1 for a numeric type that's known to be a constant
3765 value at compile-time or for an aggregate type that's a
3766 literal constant. */
3767 STRIP_NOPS (arglist);
3769 /* If we know this is a constant, emit the constant of one. */
3770 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3771 || (TREE_CODE (arglist) == CONSTRUCTOR
3772 && TREE_CONSTANT (arglist))
3773 || (TREE_CODE (arglist) == ADDR_EXPR
3774 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3775 return integer_one_node;
3777 /* If we aren't going to be running CSE or this expression
3778 has side effects, show we don't know it to be a constant.
3779 Likewise if it's a pointer or aggregate type since in those
3780 case we only want literals, since those are only optimized
3781 when generating RTL, not later.
3782 And finally, if we are compiling an initializer, not code, we
3783 need to return a definite result now; there's not going to be any
3784 more optimization done. */
3785 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3786 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3787 || POINTER_TYPE_P (TREE_TYPE (arglist))
3788 || cfun == 0)
3789 return integer_zero_node;
3791 return 0;
3794 /* Fold a call to __builtin_classify_type. */
3796 static tree
3797 fold_builtin_classify_type (arglist)
3798 tree arglist;
3800 if (arglist == 0)
3801 return build_int_2 (no_type_class, 0);
3803 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
3806 /* Used by constant folding to eliminate some builtin calls early. EXP is
3807 the CALL_EXPR of a call to a builtin function. */
3809 tree
3810 fold_builtin (exp)
3811 tree exp;
3813 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3814 tree arglist = TREE_OPERAND (exp, 1);
3815 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3817 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3818 return 0;
3820 switch (fcode)
3822 case BUILT_IN_CONSTANT_P:
3823 return fold_builtin_constant_p (arglist);
3825 case BUILT_IN_CLASSIFY_TYPE:
3826 return fold_builtin_classify_type (arglist);
3828 case BUILT_IN_STRLEN:
3829 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3831 tree len = c_strlen (TREE_VALUE (arglist));
3832 if (len != 0)
3833 return len;
3835 break;
3837 default:
3838 break;
3841 return 0;
3844 static tree
3845 build_function_call_expr (fn, arglist)
3846 tree fn, arglist;
3848 tree call_expr;
3850 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3851 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
3852 call_expr, arglist);
3853 TREE_SIDE_EFFECTS (call_expr) = 1;
3854 return fold (call_expr);
3857 /* This function validates the types of a function call argument list
3858 represented as a tree chain of parameters against a specified list
3859 of tree_codes. If the last specifier is a 0, that represents an
3860 ellipses, otherwise the last specifier must be a VOID_TYPE. */
3862 static int
3863 validate_arglist VPARAMS ((tree arglist, ...))
3865 enum tree_code code;
3866 int res = 0;
3868 VA_OPEN (ap, arglist);
3869 VA_FIXEDARG (ap, tree, arglist);
3871 do {
3872 code = va_arg (ap, enum tree_code);
3873 switch (code)
3875 case 0:
3876 /* This signifies an ellipses, any further arguments are all ok. */
3877 res = 1;
3878 goto end;
3879 case VOID_TYPE:
3880 /* This signifies an endlink, if no arguments remain, return
3881 true, otherwise return false. */
3882 res = arglist == 0;
3883 goto end;
3884 default:
3885 /* If no parameters remain or the parameter's code does not
3886 match the specified code, return false. Otherwise continue
3887 checking any remaining arguments. */
3888 if (arglist == 0 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
3889 goto end;
3890 break;
3892 arglist = TREE_CHAIN (arglist);
3893 } while (1);
3895 /* We need gotos here since we can only have one VA_CLOSE in a
3896 function. */
3897 end: ;
3898 VA_CLOSE (ap);
3900 return res;
3903 /* Default version of target-specific builtin setup that does nothing. */
3905 void
3906 default_init_builtins ()
3910 /* Default target-specific builtin expander that does nothing. */
3913 default_expand_builtin (exp, target, subtarget, mode, ignore)
3914 tree exp ATTRIBUTE_UNUSED;
3915 rtx target ATTRIBUTE_UNUSED;
3916 rtx subtarget ATTRIBUTE_UNUSED;
3917 enum machine_mode mode ATTRIBUTE_UNUSED;
3918 int ignore ATTRIBUTE_UNUSED;
3920 return NULL_RTX;