* configure.in: Arrange to include defaults.h in [ht]config.h/tm.h.
[official-gcc.git] / gcc / builtins.c
bloba49fc17325e5179ffe7ab38de8053731451ff023
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 GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 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-flags.h"
34 #include "insn-codes.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "recog.h"
38 #include "output.h"
39 #include "typeclass.h"
40 #include "toplev.h"
41 #include "tm_p.h"
43 #define CALLED_AS_BUILT_IN(NODE) \
44 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
46 /* Register mappings for target machines without register windows. */
47 #ifndef INCOMING_REGNO
48 #define INCOMING_REGNO(OUT) (OUT)
49 #endif
50 #ifndef OUTGOING_REGNO
51 #define OUTGOING_REGNO(IN) (IN)
52 #endif
54 #ifndef PAD_VARARGS_DOWN
55 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56 #endif
58 /* Define the names of the builtin function types and codes. */
59 const char *const built_in_class_names[4]
60 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
62 #define DEF_BUILTIN(x) STRINGIFY(x),
63 const char *const built_in_names[(int) END_BUILTINS] =
65 #include "builtins.def"
67 #undef DEF_BUILTIN
69 /* Setup an array of _DECL trees, make sure each element is
70 initialized to NULL_TREE. */
71 #define DEF_BUILTIN(x) NULL_TREE,
72 tree built_in_decls[(int) END_BUILTINS] =
74 #include "builtins.def"
76 #undef DEF_BUILTIN
78 tree (*lang_type_promotes_to) PARAMS ((tree));
80 static int get_pointer_alignment PARAMS ((tree, unsigned));
81 static tree c_strlen PARAMS ((tree));
82 static const char *c_getstr PARAMS ((tree));
83 static rtx c_readstr PARAMS ((const char *,
84 enum machine_mode));
85 static int target_char_cast PARAMS ((tree, char *));
86 static rtx get_memory_rtx PARAMS ((tree));
87 static int apply_args_size PARAMS ((void));
88 static int apply_result_size PARAMS ((void));
89 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
90 static rtx result_vector PARAMS ((int, rtx));
91 #endif
92 static rtx expand_builtin_setjmp PARAMS ((tree, rtx));
93 static rtx expand_builtin_apply_args PARAMS ((void));
94 static rtx expand_builtin_apply_args_1 PARAMS ((void));
95 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
96 static void expand_builtin_return PARAMS ((rtx));
97 static rtx expand_builtin_classify_type PARAMS ((tree));
98 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
99 static rtx expand_builtin_constant_p PARAMS ((tree));
100 static rtx expand_builtin_args_info PARAMS ((tree));
101 static rtx expand_builtin_next_arg PARAMS ((tree));
102 static rtx expand_builtin_va_start PARAMS ((int, tree));
103 static rtx expand_builtin_va_end PARAMS ((tree));
104 static rtx expand_builtin_va_copy PARAMS ((tree));
105 #ifdef HAVE_cmpstrsi
106 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
107 #endif
108 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
109 enum machine_mode));
110 static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
111 enum machine_mode));
112 static rtx builtin_memcpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
113 enum machine_mode));
114 static rtx expand_builtin_strcat PARAMS ((tree, rtx,
115 enum machine_mode));
116 static rtx expand_builtin_strncat PARAMS ((tree, rtx,
117 enum machine_mode));
118 static rtx expand_builtin_strspn PARAMS ((tree, rtx,
119 enum machine_mode));
120 static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
121 enum machine_mode));
122 static rtx expand_builtin_memcpy PARAMS ((tree));
123 static rtx expand_builtin_strcpy PARAMS ((tree));
124 static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
125 enum machine_mode));
126 static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
127 enum machine_mode));
128 static rtx builtin_memset_read_str PARAMS ((PTR, HOST_WIDE_INT,
129 enum machine_mode));
130 static rtx expand_builtin_memset PARAMS ((tree));
131 static rtx expand_builtin_bzero PARAMS ((tree));
132 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
133 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
134 enum machine_mode));
135 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
136 enum machine_mode));
137 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
138 enum machine_mode));
139 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
140 enum machine_mode));
141 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
142 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
143 static rtx expand_builtin_frame_address PARAMS ((tree));
144 static rtx expand_builtin_fputs PARAMS ((tree, int));
145 static tree stabilize_va_list PARAMS ((tree, int));
146 static rtx expand_builtin_expect PARAMS ((tree, rtx));
147 static tree fold_builtin_constant_p PARAMS ((tree));
148 static tree build_function_call_expr PARAMS ((tree, tree));
149 static int validate_arglist PARAMS ((tree, ...));
151 /* Return the alignment in bits of EXP, a pointer valued expression.
152 But don't return more than MAX_ALIGN no matter what.
153 The alignment returned is, by default, the alignment of the thing that
154 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
156 Otherwise, look at the expression to see if we can do better, i.e., if the
157 expression is actually pointing at an object whose alignment is tighter. */
159 static int
160 get_pointer_alignment (exp, max_align)
161 tree exp;
162 unsigned max_align;
164 unsigned align, inner;
166 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
167 return 0;
169 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
170 align = MIN (align, max_align);
172 while (1)
174 switch (TREE_CODE (exp))
176 case NOP_EXPR:
177 case CONVERT_EXPR:
178 case NON_LVALUE_EXPR:
179 exp = TREE_OPERAND (exp, 0);
180 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
181 return align;
183 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
184 align = MIN (inner, max_align);
185 break;
187 case PLUS_EXPR:
188 /* If sum of pointer + int, restrict our maximum alignment to that
189 imposed by the integer. If not, we can't do any better than
190 ALIGN. */
191 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
192 return align;
194 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1) * BITS_PER_UNIT)
195 & (max_align - 1))
196 != 0)
197 max_align >>= 1;
199 exp = TREE_OPERAND (exp, 0);
200 break;
202 case ADDR_EXPR:
203 /* See what we are pointing at and look at its alignment. */
204 exp = TREE_OPERAND (exp, 0);
205 if (TREE_CODE (exp) == FUNCTION_DECL)
206 align = FUNCTION_BOUNDARY;
207 else if (DECL_P (exp))
208 align = DECL_ALIGN (exp);
209 #ifdef CONSTANT_ALIGNMENT
210 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
211 align = CONSTANT_ALIGNMENT (exp, align);
212 #endif
213 return MIN (align, max_align);
215 default:
216 return align;
221 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
222 way, because it could contain a zero byte in the middle.
223 TREE_STRING_LENGTH is the size of the character array, not the string.
225 The value returned is of type `ssizetype'.
227 Unfortunately, string_constant can't access the values of const char
228 arrays with initializers, so neither can we do so here. */
230 static tree
231 c_strlen (src)
232 tree src;
234 tree offset_node;
235 int offset, 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. */
268 if (offset_node == 0)
269 offset = 0;
270 else
272 /* Did we get a long long offset? If so, punt. */
273 if (TREE_INT_CST_HIGH (offset_node) != 0)
274 return 0;
275 offset = TREE_INT_CST_LOW (offset_node);
278 /* If the offset is known to be out of bounds, warn, and call strlen at
279 runtime. */
280 if (offset < 0 || offset > max)
282 warning ("offset outside bounds of constant string");
283 return 0;
286 /* Use strlen to search for the first zero byte. Since any strings
287 constructed with build_string will have nulls appended, we win even
288 if we get handed something like (char[4])"abcd".
290 Since OFFSET is our starting index into the string, no further
291 calculation is needed. */
292 return ssize_int (strlen (ptr + offset));
295 /* Return a char pointer for a C string if it is a string constant
296 or sum of string constant and integer constant. */
298 static const char *
299 c_getstr (src)
300 tree src;
302 tree offset_node;
303 int offset, max;
304 const char *ptr;
306 src = string_constant (src, &offset_node);
307 if (src == 0)
308 return 0;
310 max = TREE_STRING_LENGTH (src) - 1;
311 ptr = TREE_STRING_POINTER (src);
313 if (!offset_node)
314 offset = 0;
315 else if (TREE_CODE (offset_node) != INTEGER_CST)
316 return 0;
317 else
319 /* Did we get a long long offset? If so, punt. */
320 if (TREE_INT_CST_HIGH (offset_node) != 0)
321 return 0;
322 offset = TREE_INT_CST_LOW (offset_node);
323 if (offset < 0 || offset > max)
324 return 0;
327 return ptr + offset;
330 /* Return a CONST_INT or CONST_DOUBLE corresponding to target
331 reading GET_MODE_BITSIZE (MODE) bits from string constant
332 STR. */
334 static rtx
335 c_readstr (str, mode)
336 const char *str;
337 enum machine_mode mode;
339 HOST_WIDE_INT c[2];
340 HOST_WIDE_INT ch;
341 unsigned int i, j;
343 if (GET_MODE_CLASS (mode) != MODE_INT)
344 abort ();
345 c[0] = 0;
346 c[1] = 0;
347 ch = 1;
348 for (i = 0; i < GET_MODE_SIZE (mode); i++)
350 j = i;
351 if (WORDS_BIG_ENDIAN)
352 j = GET_MODE_SIZE (mode) - i - 1;
353 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
354 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
355 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
356 j *= BITS_PER_UNIT;
357 if (j > 2 * HOST_BITS_PER_WIDE_INT)
358 abort ();
359 if (ch)
360 ch = (unsigned char) str[i];
361 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
363 return immed_double_const (c[0], c[1], mode);
366 /* Cast a target constant CST to target CHAR and if that value fits into
367 host char type, return zero and put that value into variable pointed by
368 P. */
370 static int
371 target_char_cast (cst, p)
372 tree cst;
373 char *p;
375 unsigned HOST_WIDE_INT val, hostval;
377 if (TREE_CODE (cst) != INTEGER_CST
378 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
379 return 1;
381 val = TREE_INT_CST_LOW (cst);
382 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
383 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
385 hostval = val;
386 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
387 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
389 if (val != hostval)
390 return 1;
392 *p = hostval;
393 return 0;
396 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
397 times to get the address of either a higher stack frame, or a return
398 address located within it (depending on FNDECL_CODE). */
401 expand_builtin_return_addr (fndecl_code, count, tem)
402 enum built_in_function fndecl_code;
403 int count;
404 rtx tem;
406 int i;
408 /* Some machines need special handling before we can access
409 arbitrary frames. For example, on the sparc, we must first flush
410 all register windows to the stack. */
411 #ifdef SETUP_FRAME_ADDRESSES
412 if (count > 0)
413 SETUP_FRAME_ADDRESSES ();
414 #endif
416 /* On the sparc, the return address is not in the frame, it is in a
417 register. There is no way to access it off of the current frame
418 pointer, but it can be accessed off the previous frame pointer by
419 reading the value from the register window save area. */
420 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
421 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
422 count--;
423 #endif
425 /* Scan back COUNT frames to the specified frame. */
426 for (i = 0; i < count; i++)
428 /* Assume the dynamic chain pointer is in the word that the
429 frame address points to, unless otherwise specified. */
430 #ifdef DYNAMIC_CHAIN_ADDRESS
431 tem = DYNAMIC_CHAIN_ADDRESS (tem);
432 #endif
433 tem = memory_address (Pmode, tem);
434 tem = gen_rtx_MEM (Pmode, tem);
435 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
436 tem = copy_to_reg (tem);
439 /* For __builtin_frame_address, return what we've got. */
440 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
441 return tem;
443 /* For __builtin_return_address, Get the return address from that
444 frame. */
445 #ifdef RETURN_ADDR_RTX
446 tem = RETURN_ADDR_RTX (count, tem);
447 #else
448 tem = memory_address (Pmode,
449 plus_constant (tem, GET_MODE_SIZE (Pmode)));
450 tem = gen_rtx_MEM (Pmode, tem);
451 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
452 #endif
453 return tem;
456 /* Alias set used for setjmp buffer. */
457 static HOST_WIDE_INT setjmp_alias_set = -1;
459 /* Construct the leading half of a __builtin_setjmp call. Control will
460 return to RECEIVER_LABEL. This is used directly by sjlj exception
461 handling code. */
463 void
464 expand_builtin_setjmp_setup (buf_addr, receiver_label)
465 rtx buf_addr;
466 rtx receiver_label;
468 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
469 rtx stack_save;
470 rtx mem;
472 if (setjmp_alias_set == -1)
473 setjmp_alias_set = new_alias_set ();
475 #ifdef POINTERS_EXTEND_UNSIGNED
476 buf_addr = convert_memory_address (Pmode, buf_addr);
477 #endif
479 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
481 emit_queue ();
483 /* We store the frame pointer and the address of receiver_label in
484 the buffer and use the rest of it for the stack save area, which
485 is machine-dependent. */
487 #ifndef BUILTIN_SETJMP_FRAME_VALUE
488 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
489 #endif
491 mem = gen_rtx_MEM (Pmode, buf_addr);
492 MEM_ALIAS_SET (mem) = setjmp_alias_set;
493 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
495 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
496 MEM_ALIAS_SET (mem) = setjmp_alias_set;
498 emit_move_insn (validize_mem (mem),
499 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
501 stack_save = gen_rtx_MEM (sa_mode,
502 plus_constant (buf_addr,
503 2 * GET_MODE_SIZE (Pmode)));
504 MEM_ALIAS_SET (stack_save) = setjmp_alias_set;
505 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
507 /* If there is further processing to do, do it. */
508 #ifdef HAVE_builtin_setjmp_setup
509 if (HAVE_builtin_setjmp_setup)
510 emit_insn (gen_builtin_setjmp_setup (buf_addr));
511 #endif
513 /* Tell optimize_save_area_alloca that extra work is going to
514 need to go on during alloca. */
515 current_function_calls_setjmp = 1;
517 /* Set this so all the registers get saved in our frame; we need to be
518 able to copy the saved values for any registers from frames we unwind. */
519 current_function_has_nonlocal_label = 1;
522 /* Construct the trailing part of a __builtin_setjmp call.
523 This is used directly by sjlj exception handling code. */
525 void
526 expand_builtin_setjmp_receiver (receiver_label)
527 rtx receiver_label ATTRIBUTE_UNUSED;
529 /* Clobber the FP when we get here, so we have to make sure it's
530 marked as used by this function. */
531 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
533 /* Mark the static chain as clobbered here so life information
534 doesn't get messed up for it. */
535 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
537 /* Now put in the code to restore the frame pointer, and argument
538 pointer, if needed. The code below is from expand_end_bindings
539 in stmt.c; see detailed documentation there. */
540 #ifdef HAVE_nonlocal_goto
541 if (! HAVE_nonlocal_goto)
542 #endif
543 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
545 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
546 if (fixed_regs[ARG_POINTER_REGNUM])
548 #ifdef ELIMINABLE_REGS
549 size_t i;
550 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
552 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
553 if (elim_regs[i].from == ARG_POINTER_REGNUM
554 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
555 break;
557 if (i == ARRAY_SIZE (elim_regs))
558 #endif
560 /* Now restore our arg pointer from the address at which it
561 was saved in our stack frame.
562 If there hasn't be space allocated for it yet, make
563 some now. */
564 if (arg_pointer_save_area == 0)
565 arg_pointer_save_area
566 = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
567 emit_move_insn (virtual_incoming_args_rtx,
568 copy_to_reg (arg_pointer_save_area));
571 #endif
573 #ifdef HAVE_builtin_setjmp_receiver
574 if (HAVE_builtin_setjmp_receiver)
575 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
576 else
577 #endif
578 #ifdef HAVE_nonlocal_goto_receiver
579 if (HAVE_nonlocal_goto_receiver)
580 emit_insn (gen_nonlocal_goto_receiver ());
581 else
582 #endif
583 { /* Nothing */ }
586 /* __builtin_setjmp is passed a pointer to an array of five words (not
587 all will be used on all machines). It operates similarly to the C
588 library function of the same name, but is more efficient. Much of
589 the code below (and for longjmp) is copied from the handling of
590 non-local gotos.
592 NOTE: This is intended for use by GNAT and the exception handling
593 scheme in the compiler and will only work in the method used by
594 them. */
596 static rtx
597 expand_builtin_setjmp (arglist, target)
598 tree arglist;
599 rtx target;
601 rtx buf_addr, next_lab, cont_lab;
603 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
604 return NULL_RTX;
606 if (target == 0 || GET_CODE (target) != REG
607 || REGNO (target) < FIRST_PSEUDO_REGISTER)
608 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
610 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
612 next_lab = gen_label_rtx ();
613 cont_lab = gen_label_rtx ();
615 expand_builtin_setjmp_setup (buf_addr, next_lab);
617 /* Set TARGET to zero and branch to the continue label. */
618 emit_move_insn (target, const0_rtx);
619 emit_jump_insn (gen_jump (cont_lab));
620 emit_barrier ();
621 emit_label (next_lab);
623 expand_builtin_setjmp_receiver (next_lab);
625 /* Set TARGET to one. */
626 emit_move_insn (target, const1_rtx);
627 emit_label (cont_lab);
629 /* Tell flow about the strange goings on. Putting `next_lab' on
630 `nonlocal_goto_handler_labels' to indicates that function
631 calls may traverse the arc back to this label. */
633 current_function_has_nonlocal_label = 1;
634 nonlocal_goto_handler_labels
635 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
637 return target;
640 /* __builtin_longjmp is passed a pointer to an array of five words (not
641 all will be used on all machines). It operates similarly to the C
642 library function of the same name, but is more efficient. Much of
643 the code below is copied from the handling of non-local gotos.
645 NOTE: This is intended for use by GNAT and the exception handling
646 scheme in the compiler and will only work in the method used by
647 them. */
649 void
650 expand_builtin_longjmp (buf_addr, value)
651 rtx buf_addr, value;
653 rtx fp, lab, stack, insn;
654 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
656 if (setjmp_alias_set == -1)
657 setjmp_alias_set = new_alias_set ();
659 #ifdef POINTERS_EXTEND_UNSIGNED
660 buf_addr = convert_memory_address (Pmode, buf_addr);
661 #endif
662 buf_addr = force_reg (Pmode, buf_addr);
664 /* We used to store value in static_chain_rtx, but that fails if pointers
665 are smaller than integers. We instead require that the user must pass
666 a second argument of 1, because that is what builtin_setjmp will
667 return. This also makes EH slightly more efficient, since we are no
668 longer copying around a value that we don't care about. */
669 if (value != const1_rtx)
670 abort ();
672 current_function_calls_longjmp = 1;
674 #ifdef HAVE_builtin_longjmp
675 if (HAVE_builtin_longjmp)
676 emit_insn (gen_builtin_longjmp (buf_addr));
677 else
678 #endif
680 fp = gen_rtx_MEM (Pmode, buf_addr);
681 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
682 GET_MODE_SIZE (Pmode)));
684 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
685 2 * GET_MODE_SIZE (Pmode)));
686 MEM_ALIAS_SET (fp) = MEM_ALIAS_SET (lab) = MEM_ALIAS_SET (stack)
687 = setjmp_alias_set;
689 /* Pick up FP, label, and SP from the block and jump. This code is
690 from expand_goto in stmt.c; see there for detailed comments. */
691 #if HAVE_nonlocal_goto
692 if (HAVE_nonlocal_goto)
693 /* We have to pass a value to the nonlocal_goto pattern that will
694 get copied into the static_chain pointer, but it does not matter
695 what that value is, because builtin_setjmp does not use it. */
696 emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
697 else
698 #endif
700 lab = copy_to_reg (lab);
702 emit_move_insn (hard_frame_pointer_rtx, fp);
703 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
705 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
706 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
707 emit_indirect_jump (lab);
711 /* Search backwards and mark the jump insn as a non-local goto.
712 Note that this precludes the use of __builtin_longjmp to a
713 __builtin_setjmp target in the same function. However, we've
714 already cautioned the user that these functions are for
715 internal exception handling use only. */
716 for (insn = get_last_insn ();
717 GET_CODE (insn) != JUMP_INSN;
718 insn = PREV_INSN (insn))
719 continue;
720 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
721 REG_NOTES (insn));
724 /* Get a MEM rtx for expression EXP which is the address of an operand
725 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
727 static rtx
728 get_memory_rtx (exp)
729 tree exp;
731 rtx mem = gen_rtx_MEM (BLKmode,
732 memory_address (BLKmode,
733 expand_expr (exp, NULL_RTX,
734 ptr_mode, EXPAND_SUM)));
736 /* Get an expression we can use to find the attributes to assign to MEM.
737 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
738 we can. First remove any nops. */
739 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
740 || TREE_CODE (exp) == NON_LVALUE_EXPR)
741 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
742 exp = TREE_OPERAND (exp, 0);
744 if (TREE_CODE (exp) == ADDR_EXPR)
745 exp = TREE_OPERAND (exp, 0);
746 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
747 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
748 else
749 return mem;
751 set_mem_attributes (mem, exp, 0);
753 /* memcpy, memset and other builtin stringops can alias with anything. */
754 MEM_ALIAS_SET (mem) = 0;
755 return mem;
758 /* Built-in functions to perform an untyped call and return. */
760 /* For each register that may be used for calling a function, this
761 gives a mode used to copy the register's value. VOIDmode indicates
762 the register is not used for calling a function. If the machine
763 has register windows, this gives only the outbound registers.
764 INCOMING_REGNO gives the corresponding inbound register. */
765 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
767 /* For each register that may be used for returning values, this gives
768 a mode used to copy the register's value. VOIDmode indicates the
769 register is not used for returning values. If the machine has
770 register windows, this gives only the outbound registers.
771 INCOMING_REGNO gives the corresponding inbound register. */
772 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
774 /* For each register that may be used for calling a function, this
775 gives the offset of that register into the block returned by
776 __builtin_apply_args. 0 indicates that the register is not
777 used for calling a function. */
778 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
780 /* Return the offset of register REGNO into the block returned by
781 __builtin_apply_args. This is not declared static, since it is
782 needed in objc-act.c. */
784 int
785 apply_args_register_offset (regno)
786 int regno;
788 apply_args_size ();
790 /* Arguments are always put in outgoing registers (in the argument
791 block) if such make sense. */
792 #ifdef OUTGOING_REGNO
793 regno = OUTGOING_REGNO(regno);
794 #endif
795 return apply_args_reg_offset[regno];
798 /* Return the size required for the block returned by __builtin_apply_args,
799 and initialize apply_args_mode. */
801 static int
802 apply_args_size ()
804 static int size = -1;
805 int align, regno;
806 enum machine_mode mode;
808 /* The values computed by this function never change. */
809 if (size < 0)
811 /* The first value is the incoming arg-pointer. */
812 size = GET_MODE_SIZE (Pmode);
814 /* The second value is the structure value address unless this is
815 passed as an "invisible" first argument. */
816 if (struct_value_rtx)
817 size += GET_MODE_SIZE (Pmode);
819 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
820 if (FUNCTION_ARG_REGNO_P (regno))
822 /* Search for the proper mode for copying this register's
823 value. I'm not sure this is right, but it works so far. */
824 enum machine_mode best_mode = VOIDmode;
826 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
827 mode != VOIDmode;
828 mode = GET_MODE_WIDER_MODE (mode))
829 if (HARD_REGNO_MODE_OK (regno, mode)
830 && HARD_REGNO_NREGS (regno, mode) == 1)
831 best_mode = mode;
833 if (best_mode == VOIDmode)
834 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
835 mode != VOIDmode;
836 mode = GET_MODE_WIDER_MODE (mode))
837 if (HARD_REGNO_MODE_OK (regno, mode)
838 && (mov_optab->handlers[(int) mode].insn_code
839 != CODE_FOR_nothing))
840 best_mode = mode;
842 mode = best_mode;
843 if (mode == VOIDmode)
844 abort ();
846 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
847 if (size % align != 0)
848 size = CEIL (size, align) * align;
849 apply_args_reg_offset[regno] = size;
850 size += GET_MODE_SIZE (mode);
851 apply_args_mode[regno] = mode;
853 else
855 apply_args_mode[regno] = VOIDmode;
856 apply_args_reg_offset[regno] = 0;
859 return size;
862 /* Return the size required for the block returned by __builtin_apply,
863 and initialize apply_result_mode. */
865 static int
866 apply_result_size ()
868 static int size = -1;
869 int align, regno;
870 enum machine_mode mode;
872 /* The values computed by this function never change. */
873 if (size < 0)
875 size = 0;
877 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
878 if (FUNCTION_VALUE_REGNO_P (regno))
880 /* Search for the proper mode for copying this register's
881 value. I'm not sure this is right, but it works so far. */
882 enum machine_mode best_mode = VOIDmode;
884 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
885 mode != TImode;
886 mode = GET_MODE_WIDER_MODE (mode))
887 if (HARD_REGNO_MODE_OK (regno, mode))
888 best_mode = mode;
890 if (best_mode == VOIDmode)
891 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
892 mode != VOIDmode;
893 mode = GET_MODE_WIDER_MODE (mode))
894 if (HARD_REGNO_MODE_OK (regno, mode)
895 && (mov_optab->handlers[(int) mode].insn_code
896 != CODE_FOR_nothing))
897 best_mode = mode;
899 mode = best_mode;
900 if (mode == VOIDmode)
901 abort ();
903 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
904 if (size % align != 0)
905 size = CEIL (size, align) * align;
906 size += GET_MODE_SIZE (mode);
907 apply_result_mode[regno] = mode;
909 else
910 apply_result_mode[regno] = VOIDmode;
912 /* Allow targets that use untyped_call and untyped_return to override
913 the size so that machine-specific information can be stored here. */
914 #ifdef APPLY_RESULT_SIZE
915 size = APPLY_RESULT_SIZE;
916 #endif
918 return size;
921 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
922 /* Create a vector describing the result block RESULT. If SAVEP is true,
923 the result block is used to save the values; otherwise it is used to
924 restore the values. */
926 static rtx
927 result_vector (savep, result)
928 int savep;
929 rtx result;
931 int regno, size, align, nelts;
932 enum machine_mode mode;
933 rtx reg, mem;
934 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
936 size = nelts = 0;
937 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
938 if ((mode = apply_result_mode[regno]) != VOIDmode)
940 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
941 if (size % align != 0)
942 size = CEIL (size, align) * align;
943 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
944 mem = change_address (result, mode,
945 plus_constant (XEXP (result, 0), size));
946 savevec[nelts++] = (savep
947 ? gen_rtx_SET (VOIDmode, mem, reg)
948 : gen_rtx_SET (VOIDmode, reg, mem));
949 size += GET_MODE_SIZE (mode);
951 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
953 #endif /* HAVE_untyped_call or HAVE_untyped_return */
955 /* Save the state required to perform an untyped call with the same
956 arguments as were passed to the current function. */
958 static rtx
959 expand_builtin_apply_args_1 ()
961 rtx registers;
962 int size, align, regno;
963 enum machine_mode mode;
965 /* Create a block where the arg-pointer, structure value address,
966 and argument registers can be saved. */
967 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
969 /* Walk past the arg-pointer and structure value address. */
970 size = GET_MODE_SIZE (Pmode);
971 if (struct_value_rtx)
972 size += GET_MODE_SIZE (Pmode);
974 /* Save each register used in calling a function to the block. */
975 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
976 if ((mode = apply_args_mode[regno]) != VOIDmode)
978 rtx tem;
980 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
981 if (size % align != 0)
982 size = CEIL (size, align) * align;
984 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
986 emit_move_insn (change_address (registers, mode,
987 plus_constant (XEXP (registers, 0),
988 size)),
989 tem);
990 size += GET_MODE_SIZE (mode);
993 /* Save the arg pointer to the block. */
994 emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
995 copy_to_reg (virtual_incoming_args_rtx));
996 size = GET_MODE_SIZE (Pmode);
998 /* Save the structure value address unless this is passed as an
999 "invisible" first argument. */
1000 if (struct_value_incoming_rtx)
1002 emit_move_insn (change_address (registers, Pmode,
1003 plus_constant (XEXP (registers, 0),
1004 size)),
1005 copy_to_reg (struct_value_incoming_rtx));
1006 size += GET_MODE_SIZE (Pmode);
1009 /* Return the address of the block. */
1010 return copy_addr_to_reg (XEXP (registers, 0));
1013 /* __builtin_apply_args returns block of memory allocated on
1014 the stack into which is stored the arg pointer, structure
1015 value address, static chain, and all the registers that might
1016 possibly be used in performing a function call. The code is
1017 moved to the start of the function so the incoming values are
1018 saved. */
1019 static rtx
1020 expand_builtin_apply_args ()
1022 /* Don't do __builtin_apply_args more than once in a function.
1023 Save the result of the first call and reuse it. */
1024 if (apply_args_value != 0)
1025 return apply_args_value;
1027 /* When this function is called, it means that registers must be
1028 saved on entry to this function. So we migrate the
1029 call to the first insn of this function. */
1030 rtx temp;
1031 rtx seq;
1033 start_sequence ();
1034 temp = expand_builtin_apply_args_1 ();
1035 seq = get_insns ();
1036 end_sequence ();
1038 apply_args_value = temp;
1040 /* Put the sequence after the NOTE that starts the function.
1041 If this is inside a SEQUENCE, make the outer-level insn
1042 chain current, so the code is placed at the start of the
1043 function. */
1044 push_topmost_sequence ();
1045 emit_insns_before (seq, NEXT_INSN (get_insns ()));
1046 pop_topmost_sequence ();
1047 return temp;
1051 /* Perform an untyped call and save the state required to perform an
1052 untyped return of whatever value was returned by the given function. */
1054 static rtx
1055 expand_builtin_apply (function, arguments, argsize)
1056 rtx function, arguments, argsize;
1058 int size, align, regno;
1059 enum machine_mode mode;
1060 rtx incoming_args, result, reg, dest, call_insn;
1061 rtx old_stack_level = 0;
1062 rtx call_fusage = 0;
1064 /* Create a block where the return registers can be saved. */
1065 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1067 /* Fetch the arg pointer from the ARGUMENTS block. */
1068 incoming_args = gen_reg_rtx (Pmode);
1069 emit_move_insn (incoming_args,
1070 gen_rtx_MEM (Pmode, arguments));
1071 #ifndef STACK_GROWS_DOWNWARD
1072 incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
1073 incoming_args, 0, OPTAB_LIB_WIDEN);
1074 #endif
1076 /* Perform postincrements before actually calling the function. */
1077 emit_queue ();
1079 /* Push a new argument block and copy the arguments. Do not allow
1080 the (potential) memcpy call below to interfere with our stack
1081 manipulations. */
1082 do_pending_stack_adjust ();
1083 NO_DEFER_POP;
1085 /* Save the stack with nonlocal if available */
1086 #ifdef HAVE_save_stack_nonlocal
1087 if (HAVE_save_stack_nonlocal)
1088 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1089 else
1090 #endif
1091 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1093 /* Push a block of memory onto the stack to store the memory arguments.
1094 Save the address in a register, and copy the memory arguments. ??? I
1095 haven't figured out how the calling convention macros effect this,
1096 but it's likely that the source and/or destination addresses in
1097 the block copy will need updating in machine specific ways. */
1098 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1099 emit_block_move (gen_rtx_MEM (BLKmode, dest),
1100 gen_rtx_MEM (BLKmode, incoming_args),
1101 argsize, PARM_BOUNDARY);
1103 /* Refer to the argument block. */
1104 apply_args_size ();
1105 arguments = gen_rtx_MEM (BLKmode, arguments);
1107 /* Walk past the arg-pointer and structure value address. */
1108 size = GET_MODE_SIZE (Pmode);
1109 if (struct_value_rtx)
1110 size += GET_MODE_SIZE (Pmode);
1112 /* Restore each of the registers previously saved. Make USE insns
1113 for each of these registers for use in making the call. */
1114 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1115 if ((mode = apply_args_mode[regno]) != VOIDmode)
1117 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1118 if (size % align != 0)
1119 size = CEIL (size, align) * align;
1120 reg = gen_rtx_REG (mode, regno);
1121 emit_move_insn (reg,
1122 change_address (arguments, mode,
1123 plus_constant (XEXP (arguments, 0),
1124 size)));
1126 use_reg (&call_fusage, reg);
1127 size += GET_MODE_SIZE (mode);
1130 /* Restore the structure value address unless this is passed as an
1131 "invisible" first argument. */
1132 size = GET_MODE_SIZE (Pmode);
1133 if (struct_value_rtx)
1135 rtx value = gen_reg_rtx (Pmode);
1136 emit_move_insn (value,
1137 change_address (arguments, Pmode,
1138 plus_constant (XEXP (arguments, 0),
1139 size)));
1140 emit_move_insn (struct_value_rtx, value);
1141 if (GET_CODE (struct_value_rtx) == REG)
1142 use_reg (&call_fusage, struct_value_rtx);
1143 size += GET_MODE_SIZE (Pmode);
1146 /* All arguments and registers used for the call are set up by now! */
1147 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
1149 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1150 and we don't want to load it into a register as an optimization,
1151 because prepare_call_address already did it if it should be done. */
1152 if (GET_CODE (function) != SYMBOL_REF)
1153 function = memory_address (FUNCTION_MODE, function);
1155 /* Generate the actual call instruction and save the return value. */
1156 #ifdef HAVE_untyped_call
1157 if (HAVE_untyped_call)
1158 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1159 result, result_vector (1, result)));
1160 else
1161 #endif
1162 #ifdef HAVE_call_value
1163 if (HAVE_call_value)
1165 rtx valreg = 0;
1167 /* Locate the unique return register. It is not possible to
1168 express a call that sets more than one return register using
1169 call_value; use untyped_call for that. In fact, untyped_call
1170 only needs to save the return registers in the given block. */
1171 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1172 if ((mode = apply_result_mode[regno]) != VOIDmode)
1174 if (valreg)
1175 abort (); /* HAVE_untyped_call required. */
1176 valreg = gen_rtx_REG (mode, regno);
1179 emit_call_insn (GEN_CALL_VALUE (valreg,
1180 gen_rtx_MEM (FUNCTION_MODE, function),
1181 const0_rtx, NULL_RTX, const0_rtx));
1183 emit_move_insn (change_address (result, GET_MODE (valreg),
1184 XEXP (result, 0)),
1185 valreg);
1187 else
1188 #endif
1189 abort ();
1191 /* Find the CALL insn we just emitted. */
1192 for (call_insn = get_last_insn ();
1193 call_insn && GET_CODE (call_insn) != CALL_INSN;
1194 call_insn = PREV_INSN (call_insn))
1197 if (! call_insn)
1198 abort ();
1200 /* Put the register usage information on the CALL. If there is already
1201 some usage information, put ours at the end. */
1202 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1204 rtx link;
1206 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1207 link = XEXP (link, 1))
1210 XEXP (link, 1) = call_fusage;
1212 else
1213 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1215 /* Restore the stack. */
1216 #ifdef HAVE_save_stack_nonlocal
1217 if (HAVE_save_stack_nonlocal)
1218 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1219 else
1220 #endif
1221 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1223 OK_DEFER_POP;
1225 /* Return the address of the result block. */
1226 return copy_addr_to_reg (XEXP (result, 0));
1229 /* Perform an untyped return. */
1231 static void
1232 expand_builtin_return (result)
1233 rtx result;
1235 int size, align, regno;
1236 enum machine_mode mode;
1237 rtx reg;
1238 rtx call_fusage = 0;
1240 apply_result_size ();
1241 result = gen_rtx_MEM (BLKmode, result);
1243 #ifdef HAVE_untyped_return
1244 if (HAVE_untyped_return)
1246 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1247 emit_barrier ();
1248 return;
1250 #endif
1252 /* Restore the return value and note that each value is used. */
1253 size = 0;
1254 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1255 if ((mode = apply_result_mode[regno]) != VOIDmode)
1257 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1258 if (size % align != 0)
1259 size = CEIL (size, align) * align;
1260 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1261 emit_move_insn (reg,
1262 change_address (result, mode,
1263 plus_constant (XEXP (result, 0),
1264 size)));
1266 push_to_sequence (call_fusage);
1267 emit_insn (gen_rtx_USE (VOIDmode, reg));
1268 call_fusage = get_insns ();
1269 end_sequence ();
1270 size += GET_MODE_SIZE (mode);
1273 /* Put the USE insns before the return. */
1274 emit_insns (call_fusage);
1276 /* Return whatever values was restored by jumping directly to the end
1277 of the function. */
1278 expand_null_return ();
1281 /* Expand a call to __builtin_classify_type with arguments found in
1282 ARGLIST. */
1283 static rtx
1284 expand_builtin_classify_type (arglist)
1285 tree arglist;
1287 if (arglist != 0)
1289 tree type = TREE_TYPE (TREE_VALUE (arglist));
1290 enum tree_code code = TREE_CODE (type);
1291 if (code == VOID_TYPE)
1292 return GEN_INT (void_type_class);
1293 if (code == INTEGER_TYPE)
1294 return GEN_INT (integer_type_class);
1295 if (code == CHAR_TYPE)
1296 return GEN_INT (char_type_class);
1297 if (code == ENUMERAL_TYPE)
1298 return GEN_INT (enumeral_type_class);
1299 if (code == BOOLEAN_TYPE)
1300 return GEN_INT (boolean_type_class);
1301 if (code == POINTER_TYPE)
1302 return GEN_INT (pointer_type_class);
1303 if (code == REFERENCE_TYPE)
1304 return GEN_INT (reference_type_class);
1305 if (code == OFFSET_TYPE)
1306 return GEN_INT (offset_type_class);
1307 if (code == REAL_TYPE)
1308 return GEN_INT (real_type_class);
1309 if (code == COMPLEX_TYPE)
1310 return GEN_INT (complex_type_class);
1311 if (code == FUNCTION_TYPE)
1312 return GEN_INT (function_type_class);
1313 if (code == METHOD_TYPE)
1314 return GEN_INT (method_type_class);
1315 if (code == RECORD_TYPE)
1316 return GEN_INT (record_type_class);
1317 if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
1318 return GEN_INT (union_type_class);
1319 if (code == ARRAY_TYPE)
1321 if (TYPE_STRING_FLAG (type))
1322 return GEN_INT (string_type_class);
1323 else
1324 return GEN_INT (array_type_class);
1326 if (code == SET_TYPE)
1327 return GEN_INT (set_type_class);
1328 if (code == FILE_TYPE)
1329 return GEN_INT (file_type_class);
1330 if (code == LANG_TYPE)
1331 return GEN_INT (lang_type_class);
1333 return GEN_INT (no_type_class);
1336 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1337 static rtx
1338 expand_builtin_constant_p (exp)
1339 tree exp;
1341 tree arglist = TREE_OPERAND (exp, 1);
1342 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1343 rtx tmp;
1345 if (arglist == 0)
1346 return const0_rtx;
1347 arglist = TREE_VALUE (arglist);
1349 /* We have taken care of the easy cases during constant folding. This
1350 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1351 chance to see if it can deduce whether ARGLIST is constant. */
1353 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1354 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1355 return tmp;
1358 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1359 Return 0 if a normal call should be emitted rather than expanding the
1360 function in-line. EXP is the expression that is a call to the builtin
1361 function; if convenient, the result should be placed in TARGET.
1362 SUBTARGET may be used as the target for computing one of EXP's operands. */
1363 static rtx
1364 expand_builtin_mathfn (exp, target, subtarget)
1365 tree exp;
1366 rtx target, subtarget;
1368 optab builtin_optab;
1369 rtx op0, insns;
1370 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1371 tree arglist = TREE_OPERAND (exp, 1);
1373 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1374 return 0;
1376 /* Stabilize and compute the argument. */
1377 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1378 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1380 exp = copy_node (exp);
1381 TREE_OPERAND (exp, 1) = arglist;
1382 /* Wrap the computation of the argument in a SAVE_EXPR. That
1383 way, if we need to expand the argument again (as in the
1384 flag_errno_math case below where we cannot directly set
1385 errno), we will not perform side-effects more than once.
1386 Note that here we're mutating the original EXP as well as the
1387 copy; that's the right thing to do in case the original EXP
1388 is expanded later. */
1389 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1390 arglist = copy_node (arglist);
1392 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1394 /* Make a suitable register to place result in. */
1395 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1397 emit_queue ();
1398 start_sequence ();
1400 switch (DECL_FUNCTION_CODE (fndecl))
1402 case BUILT_IN_SIN:
1403 builtin_optab = sin_optab; break;
1404 case BUILT_IN_COS:
1405 builtin_optab = cos_optab; break;
1406 case BUILT_IN_FSQRT:
1407 builtin_optab = sqrt_optab; break;
1408 default:
1409 abort ();
1412 /* Compute into TARGET.
1413 Set TARGET to wherever the result comes back. */
1414 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1415 builtin_optab, op0, target, 0);
1417 /* If we were unable to expand via the builtin, stop the
1418 sequence (without outputting the insns) and return 0, causing
1419 a call to the library function. */
1420 if (target == 0)
1422 end_sequence ();
1423 return 0;
1426 /* Check the results by default. But if flag_fast_math is turned on,
1427 then assume sqrt will always be called with valid arguments. */
1429 if (flag_errno_math && ! flag_fast_math)
1431 rtx lab1;
1433 /* Don't define the builtin FP instructions
1434 if your machine is not IEEE. */
1435 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1436 abort ();
1438 lab1 = gen_label_rtx ();
1440 /* Test the result; if it is NaN, set errno=EDOM because
1441 the argument was not in the domain. */
1442 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1443 0, 0, lab1);
1445 #ifdef TARGET_EDOM
1447 #ifdef GEN_ERRNO_RTX
1448 rtx errno_rtx = GEN_ERRNO_RTX;
1449 #else
1450 rtx errno_rtx
1451 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1452 #endif
1454 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1456 #else
1457 /* We can't set errno=EDOM directly; let the library call do it.
1458 Pop the arguments right away in case the call gets deleted. */
1459 NO_DEFER_POP;
1460 expand_call (exp, target, 0);
1461 OK_DEFER_POP;
1462 #endif
1464 emit_label (lab1);
1467 /* Output the entire sequence. */
1468 insns = get_insns ();
1469 end_sequence ();
1470 emit_insns (insns);
1472 return target;
1475 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1476 if we failed the caller should emit a normal call, otherwise
1477 try to get the result in TARGET, if convenient. */
1479 static rtx
1480 expand_builtin_strlen (exp, target)
1481 tree exp;
1482 rtx target;
1484 tree arglist = TREE_OPERAND (exp, 1);
1485 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1487 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1488 return 0;
1489 else
1491 rtx pat;
1492 tree src = TREE_VALUE (arglist);
1494 int align
1495 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1497 rtx result, src_reg, char_rtx, before_strlen;
1498 enum machine_mode insn_mode = value_mode, char_mode;
1499 enum insn_code icode = CODE_FOR_nothing;
1501 /* If SRC is not a pointer type, don't do this operation inline. */
1502 if (align == 0)
1503 return 0;
1505 /* Bail out if we can't compute strlen in the right mode. */
1506 while (insn_mode != VOIDmode)
1508 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1509 if (icode != CODE_FOR_nothing)
1510 break;
1512 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1514 if (insn_mode == VOIDmode)
1515 return 0;
1517 /* Make a place to write the result of the instruction. */
1518 result = target;
1519 if (! (result != 0
1520 && GET_CODE (result) == REG
1521 && GET_MODE (result) == insn_mode
1522 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1523 result = gen_reg_rtx (insn_mode);
1525 /* Make a place to hold the source address. We will not expand
1526 the actual source until we are sure that the expansion will
1527 not fail -- there are trees that cannot be expanded twice. */
1528 src_reg = gen_reg_rtx (Pmode);
1530 /* Mark the beginning of the strlen sequence so we can emit the
1531 source operand later. */
1532 before_strlen = get_last_insn();
1534 /* Check the string is readable and has an end. */
1535 if (current_function_check_memory_usage)
1536 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1537 VOIDmode, 2, src_reg, Pmode,
1538 GEN_INT (MEMORY_USE_RO),
1539 TYPE_MODE (integer_type_node));
1541 char_rtx = const0_rtx;
1542 char_mode = insn_data[(int) icode].operand[2].mode;
1543 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1544 char_mode))
1545 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1547 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1548 char_rtx, GEN_INT (align));
1549 if (! pat)
1550 return 0;
1551 emit_insn (pat);
1553 /* Now that we are assured of success, expand the source. */
1554 start_sequence ();
1555 pat = memory_address (BLKmode,
1556 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1557 if (pat != src_reg)
1558 emit_move_insn (src_reg, pat);
1559 pat = gen_sequence ();
1560 end_sequence ();
1562 if (before_strlen)
1563 emit_insn_after (pat, before_strlen);
1564 else
1565 emit_insn_before (pat, get_insns ());
1567 /* Return the value in the proper mode for this function. */
1568 if (GET_MODE (result) == value_mode)
1569 target = result;
1570 else if (target != 0)
1571 convert_move (target, result, 0);
1572 else
1573 target = convert_to_mode (value_mode, result, 0);
1575 return target;
1579 /* Expand a call to the strstr builtin. Return 0 if we failed the
1580 caller should emit a normal call, otherwise try to get the result
1581 in TARGET, if convenient (and in mode MODE if that's convenient). */
1583 static rtx
1584 expand_builtin_strstr (arglist, target, mode)
1585 tree arglist;
1586 rtx target;
1587 enum machine_mode mode;
1589 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1590 || current_function_check_memory_usage)
1591 return 0;
1592 else
1594 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1595 tree fn;
1596 const char *p1, *p2;
1598 p2 = c_getstr (s2);
1599 if (p2 == NULL)
1600 return 0;
1602 p1 = c_getstr (s1);
1603 if (p1 != NULL)
1605 const char *r = strstr (p1, p2);
1607 if (r == NULL)
1608 return const0_rtx;
1610 /* Return an offset into the constant string argument. */
1611 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1612 s1, ssize_int (r - p1))),
1613 target, mode, EXPAND_NORMAL);
1616 if (p2[0] == '\0')
1617 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1619 if (p2[1] != '\0')
1620 return 0;
1622 fn = built_in_decls[BUILT_IN_STRCHR];
1623 if (!fn)
1624 return 0;
1626 /* New argument list transforming strstr(s1, s2) to
1627 strchr(s1, s2[0]). */
1628 arglist =
1629 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1630 arglist = tree_cons (NULL_TREE, s1, arglist);
1631 return expand_expr (build_function_call_expr (fn, arglist),
1632 target, mode, EXPAND_NORMAL);
1636 /* Expand a call to the strchr builtin. Return 0 if we failed the
1637 caller should emit a normal call, otherwise try to get the result
1638 in TARGET, if convenient (and in mode MODE if that's convenient). */
1640 static rtx
1641 expand_builtin_strchr (arglist, target, mode)
1642 tree arglist;
1643 rtx target;
1644 enum machine_mode mode;
1646 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1647 || current_function_check_memory_usage)
1648 return 0;
1649 else
1651 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1652 const char *p1;
1654 if (TREE_CODE (s2) != INTEGER_CST)
1655 return 0;
1657 p1 = c_getstr (s1);
1658 if (p1 != NULL)
1660 char c;
1661 const char *r;
1663 if (target_char_cast (s2, &c))
1664 return 0;
1666 r = strchr (p1, c);
1668 if (r == NULL)
1669 return const0_rtx;
1671 /* Return an offset into the constant string argument. */
1672 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1673 s1, ssize_int (r - p1))),
1674 target, mode, EXPAND_NORMAL);
1677 /* FIXME: Should use here strchrM optab so that ports can optimize
1678 this. */
1679 return 0;
1683 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1684 caller should emit a normal call, otherwise try to get the result
1685 in TARGET, if convenient (and in mode MODE if that's convenient). */
1687 static rtx
1688 expand_builtin_strrchr (arglist, target, mode)
1689 tree arglist;
1690 rtx target;
1691 enum machine_mode mode;
1693 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1694 || current_function_check_memory_usage)
1695 return 0;
1696 else
1698 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1699 tree fn;
1700 const char *p1;
1702 if (TREE_CODE (s2) != INTEGER_CST)
1703 return 0;
1705 p1 = c_getstr (s1);
1706 if (p1 != NULL)
1708 char c;
1709 const char *r;
1711 if (target_char_cast (s2, &c))
1712 return 0;
1714 r = strrchr (p1, c);
1716 if (r == NULL)
1717 return const0_rtx;
1719 /* Return an offset into the constant string argument. */
1720 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1721 s1, ssize_int (r - p1))),
1722 target, mode, EXPAND_NORMAL);
1725 if (! integer_zerop (s2))
1726 return 0;
1728 fn = built_in_decls[BUILT_IN_STRCHR];
1729 if (!fn)
1730 return 0;
1732 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1733 return expand_expr (build_function_call_expr (fn, arglist),
1734 target, mode, EXPAND_NORMAL);
1738 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1739 caller should emit a normal call, otherwise try to get the result
1740 in TARGET, if convenient (and in mode MODE if that's convenient). */
1742 static rtx
1743 expand_builtin_strpbrk (arglist, target, mode)
1744 tree arglist;
1745 rtx target;
1746 enum machine_mode mode;
1748 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1749 || current_function_check_memory_usage)
1750 return 0;
1751 else
1753 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1754 tree fn;
1755 const char *p1, *p2;
1757 p2 = c_getstr (s2);
1758 if (p2 == NULL)
1759 return 0;
1761 p1 = c_getstr (s1);
1762 if (p1 != NULL)
1764 const char *r = strpbrk (p1, p2);
1766 if (r == NULL)
1767 return const0_rtx;
1769 /* Return an offset into the constant string argument. */
1770 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1771 s1, ssize_int (r - p1))),
1772 target, mode, EXPAND_NORMAL);
1775 if (p2[0] == '\0')
1777 /* strpbrk(x, "") == NULL.
1778 Evaluate and ignore the arguments in case they had
1779 side-effects. */
1780 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1781 return const0_rtx;
1784 if (p2[1] != '\0')
1785 return 0; /* Really call strpbrk. */
1787 fn = built_in_decls[BUILT_IN_STRCHR];
1788 if (!fn)
1789 return 0;
1791 /* New argument list transforming strpbrk(s1, s2) to
1792 strchr(s1, s2[0]). */
1793 arglist =
1794 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1795 arglist = tree_cons (NULL_TREE, s1, arglist);
1796 return expand_expr (build_function_call_expr (fn, arglist),
1797 target, mode, EXPAND_NORMAL);
1801 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1802 bytes from constant string DATA + OFFSET and return it as target
1803 constant. */
1805 static rtx
1806 builtin_memcpy_read_str (data, offset, mode)
1807 PTR data;
1808 HOST_WIDE_INT offset;
1809 enum machine_mode mode;
1811 const char *str = (const char *) data;
1813 if (offset + GET_MODE_SIZE (mode) > strlen (str) + 1)
1814 abort (); /* Attempt to read past the end of constant string. */
1816 return c_readstr (str + offset, mode);
1819 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1820 static rtx
1821 expand_builtin_memcpy (arglist)
1822 tree arglist;
1824 if (!validate_arglist (arglist,
1825 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1826 return 0;
1827 else
1829 tree dest = TREE_VALUE (arglist);
1830 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1831 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1832 const char *src_str;
1834 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1835 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1836 rtx dest_mem, src_mem, dest_addr, len_rtx;
1838 /* If either SRC or DEST is not a pointer type, don't do
1839 this operation in-line. */
1840 if (src_align == 0 || dest_align == 0)
1841 return 0;
1843 dest_mem = get_memory_rtx (dest);
1844 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1845 src_str = c_getstr (src);
1847 /* If SRC is a string constant and block move would be done
1848 by pieces, we can avoid loading the string from memory
1849 and only stored the computed constants. */
1850 if (src_str
1851 && !current_function_check_memory_usage
1852 && GET_CODE (len_rtx) == CONST_INT
1853 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
1854 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
1855 (PTR) src_str, dest_align))
1857 store_by_pieces (dest_mem, INTVAL (len_rtx),
1858 builtin_memcpy_read_str,
1859 (PTR) src_str, dest_align);
1860 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1863 src_mem = get_memory_rtx (src);
1865 /* Just copy the rights of SRC to the rights of DEST. */
1866 if (current_function_check_memory_usage)
1867 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1868 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1869 XEXP (src_mem, 0), Pmode,
1870 len_rtx, TYPE_MODE (sizetype));
1872 /* Copy word part most expediently. */
1873 dest_addr
1874 = emit_block_move (dest_mem, src_mem, len_rtx,
1875 MIN (src_align, dest_align));
1877 if (dest_addr == 0)
1878 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1880 return dest_addr;
1884 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1885 if we failed the caller should emit a normal call. */
1887 static rtx
1888 expand_builtin_strcpy (exp)
1889 tree exp;
1891 tree arglist = TREE_OPERAND (exp, 1);
1892 rtx result;
1894 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1895 return 0;
1896 else
1898 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1900 if (len == 0)
1901 return 0;
1903 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1904 chainon (arglist, build_tree_list (NULL_TREE, len));
1907 result = expand_builtin_memcpy (arglist);
1909 if (! result)
1910 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1911 return result;
1914 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1915 bytes from constant string DATA + OFFSET and return it as target
1916 constant. */
1918 static rtx
1919 builtin_strncpy_read_str (data, offset, mode)
1920 PTR data;
1921 HOST_WIDE_INT offset;
1922 enum machine_mode mode;
1924 const char *str = (const char *) data;
1926 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
1927 return const0_rtx;
1929 return c_readstr (str + offset, mode);
1932 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
1933 if we failed the caller should emit a normal call. */
1935 static rtx
1936 expand_builtin_strncpy (arglist, target, mode)
1937 tree arglist;
1938 rtx target;
1939 enum machine_mode mode;
1941 if (!validate_arglist (arglist,
1942 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1943 return 0;
1944 else
1946 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1947 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1949 /* We must be passed a constant len parameter. */
1950 if (TREE_CODE (len) != INTEGER_CST)
1951 return 0;
1953 /* If the len parameter is zero, return the dst parameter. */
1954 if (compare_tree_int (len, 0) == 0)
1956 /* Evaluate and ignore the src argument in case it has
1957 side-effects. */
1958 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
1959 VOIDmode, EXPAND_NORMAL);
1960 /* Return the dst parameter. */
1961 return expand_expr (TREE_VALUE (arglist), target, mode,
1962 EXPAND_NORMAL);
1965 /* Now, we must be passed a constant src ptr parameter. */
1966 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
1967 return 0;
1969 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
1971 /* We're required to pad with trailing zeros if the requested
1972 len is greater than strlen(s2)+1. In that case try to
1973 use store_by_pieces, if it fails, punt. */
1974 if (tree_int_cst_lt (slen, len))
1976 tree dest = TREE_VALUE (arglist);
1977 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1978 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
1979 rtx dest_mem;
1981 if (!p || !dest_align || TREE_INT_CST_HIGH (len)
1982 || !can_store_by_pieces (TREE_INT_CST_LOW (len),
1983 builtin_strncpy_read_str,
1984 (PTR) p, dest_align))
1985 return 0;
1987 dest_mem = get_memory_rtx (dest);
1988 store_by_pieces (dest_mem, TREE_INT_CST_LOW (len),
1989 builtin_strncpy_read_str,
1990 (PTR) p, dest_align);
1991 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1994 /* OK transform into builtin memcpy. */
1995 return expand_builtin_memcpy (arglist);
1999 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2000 bytes from constant string DATA + OFFSET and return it as target
2001 constant. */
2003 static rtx
2004 builtin_memset_read_str (data, offset, mode)
2005 PTR data;
2006 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2007 enum machine_mode mode;
2009 const char *c = (const char *) data;
2010 char *p = alloca (GET_MODE_SIZE (mode));
2012 memset (p, *c, GET_MODE_SIZE (mode));
2014 return c_readstr (p, mode);
2017 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2018 if we failed the caller should emit a normal call. */
2020 static rtx
2021 expand_builtin_memset (exp)
2022 tree exp;
2024 tree arglist = TREE_OPERAND (exp, 1);
2026 if (!validate_arglist (arglist,
2027 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2028 return 0;
2029 else
2031 tree dest = TREE_VALUE (arglist);
2032 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2033 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2034 char c;
2036 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2037 rtx dest_mem, dest_addr, len_rtx;
2039 /* If DEST is not a pointer type, don't do this
2040 operation in-line. */
2041 if (dest_align == 0)
2042 return 0;
2044 if (TREE_CODE (val) != INTEGER_CST)
2045 return 0;
2047 if (target_char_cast (val, &c))
2048 return 0;
2050 if (c)
2052 if (TREE_CODE (len) != INTEGER_CST || TREE_INT_CST_HIGH (len))
2053 return 0;
2054 if (current_function_check_memory_usage
2055 || !can_store_by_pieces (TREE_INT_CST_LOW (len),
2056 builtin_memset_read_str,
2057 (PTR) &c, dest_align))
2058 return 0;
2060 dest_mem = get_memory_rtx (dest);
2061 store_by_pieces (dest_mem, TREE_INT_CST_LOW (len),
2062 builtin_memset_read_str,
2063 (PTR) &c, dest_align);
2064 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
2067 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2069 dest_mem = get_memory_rtx (dest);
2071 /* Just check DST is writable and mark it as readable. */
2072 if (current_function_check_memory_usage)
2073 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
2074 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
2075 len_rtx, TYPE_MODE (sizetype),
2076 GEN_INT (MEMORY_USE_WO),
2077 TYPE_MODE (integer_type_node));
2080 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
2082 if (dest_addr == 0)
2083 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2085 return dest_addr;
2089 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2090 if we failed the caller should emit a normal call. */
2091 static rtx
2092 expand_builtin_bzero (exp)
2093 tree exp;
2095 tree arglist = TREE_OPERAND (exp, 1);
2096 tree dest, size, newarglist;
2097 rtx result;
2099 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2100 return NULL_RTX;
2102 dest = TREE_VALUE (arglist);
2103 size = TREE_VALUE (TREE_CHAIN (arglist));
2105 /* New argument list transforming bzero(ptr x, int y) to
2106 memset(ptr x, int 0, size_t y). */
2108 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2109 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2110 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2112 TREE_OPERAND (exp, 1) = newarglist;
2113 result = expand_builtin_memset(exp);
2115 /* Always restore the original arguments. */
2116 TREE_OPERAND (exp, 1) = arglist;
2118 return result;
2121 #ifdef HAVE_cmpstrsi
2122 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2123 ARGLIST is the argument list for this call. Return 0 if we failed and the
2124 caller should emit a normal call, otherwise try to get the result in
2125 TARGET, if convenient. */
2126 static rtx
2127 expand_builtin_memcmp (exp, arglist, target)
2128 tree exp;
2129 tree arglist;
2130 rtx target;
2132 /* If we need to check memory accesses, call the library function. */
2133 if (current_function_check_memory_usage)
2134 return 0;
2136 if (!validate_arglist (arglist,
2137 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2138 return 0;
2141 enum machine_mode mode;
2142 tree arg1 = TREE_VALUE (arglist);
2143 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2144 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2145 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2146 rtx result;
2147 rtx insn;
2149 int arg1_align
2150 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2151 int arg2_align
2152 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2153 enum machine_mode insn_mode
2154 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2156 /* If we don't have POINTER_TYPE, call the function. */
2157 if (arg1_align == 0 || arg2_align == 0)
2158 return 0;
2160 /* Make a place to write the result of the instruction. */
2161 result = target;
2162 if (! (result != 0
2163 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2164 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2165 result = gen_reg_rtx (insn_mode);
2167 arg1_rtx = get_memory_rtx (arg1);
2168 arg2_rtx = get_memory_rtx (arg2);
2169 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2170 if (!HAVE_cmpstrsi)
2171 insn = NULL_RTX;
2172 else
2173 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2174 GEN_INT (MIN (arg1_align, arg2_align)));
2176 if (insn)
2177 emit_insn (insn);
2178 else
2179 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2180 TYPE_MODE (integer_type_node), 3,
2181 XEXP (arg1_rtx, 0), Pmode,
2182 XEXP (arg2_rtx, 0), Pmode,
2183 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2184 TREE_UNSIGNED (sizetype)),
2185 TYPE_MODE (sizetype));
2187 /* Return the value in the proper mode for this function. */
2188 mode = TYPE_MODE (TREE_TYPE (exp));
2189 if (GET_MODE (result) == mode)
2190 return result;
2191 else if (target != 0)
2193 convert_move (target, result, 0);
2194 return target;
2196 else
2197 return convert_to_mode (mode, result, 0);
2200 #endif
2202 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2203 if we failed the caller should emit a normal call, otherwise try to get
2204 the result in TARGET, if convenient. */
2206 static rtx
2207 expand_builtin_strcmp (exp, target, mode)
2208 tree exp;
2209 rtx target;
2210 enum machine_mode mode;
2212 tree arglist = TREE_OPERAND (exp, 1);
2213 tree arg1, arg2;
2214 const char *p1, *p2;
2216 /* If we need to check memory accesses, call the library function. */
2217 if (current_function_check_memory_usage)
2218 return 0;
2220 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2221 return 0;
2223 arg1 = TREE_VALUE (arglist);
2224 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2226 p1 = c_getstr (arg1);
2227 p2 = c_getstr (arg2);
2229 if (p1 && p2)
2231 const int i = strcmp (p1, p2);
2232 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2235 /* If either arg is "", return an expression corresponding to
2236 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2237 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2239 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2240 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2241 tree ind1 =
2242 fold (build1 (CONVERT_EXPR, integer_type_node,
2243 build1 (INDIRECT_REF, cst_uchar_node,
2244 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2245 tree ind2 =
2246 fold (build1 (CONVERT_EXPR, integer_type_node,
2247 build1 (INDIRECT_REF, cst_uchar_node,
2248 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2249 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2250 return expand_expr (result, target, mode, EXPAND_NORMAL);
2253 #ifdef HAVE_cmpstrsi
2254 if (! HAVE_cmpstrsi)
2255 return 0;
2258 tree len = c_strlen (arg1);
2259 tree len2 = c_strlen (arg2);
2260 rtx result;
2262 if (len)
2263 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2265 if (len2)
2266 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2268 /* If we don't have a constant length for the first, use the length
2269 of the second, if we know it. We don't require a constant for
2270 this case; some cost analysis could be done if both are available
2271 but neither is constant. For now, assume they're equally cheap
2272 unless one has side effects.
2274 If both strings have constant lengths, use the smaller. This
2275 could arise if optimization results in strcpy being called with
2276 two fixed strings, or if the code was machine-generated. We should
2277 add some code to the `memcmp' handler below to deal with such
2278 situations, someday. */
2280 if (!len || TREE_CODE (len) != INTEGER_CST)
2282 if (len2 && !TREE_SIDE_EFFECTS (len2))
2283 len = len2;
2284 else if (len == 0)
2285 return 0;
2287 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2288 && tree_int_cst_lt (len2, len))
2289 len = len2;
2291 /* If both arguments have side effects, we cannot optimize. */
2292 if (TREE_SIDE_EFFECTS (len))
2293 return 0;
2295 chainon (arglist, build_tree_list (NULL_TREE, len));
2296 result = expand_builtin_memcmp (exp, arglist, target);
2297 if (! result)
2298 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2300 return result;
2302 #else
2303 return 0;
2304 #endif
2307 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2308 if we failed the caller should emit a normal call, otherwise try to get
2309 the result in TARGET, if convenient. */
2310 static rtx
2311 expand_builtin_strncmp (exp, target, mode)
2312 tree exp;
2313 rtx target;
2314 enum machine_mode mode;
2316 tree arglist = TREE_OPERAND (exp, 1);
2317 tree arg1, arg2, arg3;
2318 const char *p1, *p2;
2320 /* If we need to check memory accesses, call the library function. */
2321 if (current_function_check_memory_usage)
2322 return 0;
2324 if (!validate_arglist (arglist,
2325 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2326 return 0;
2328 arg1 = TREE_VALUE (arglist);
2329 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2330 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2332 /* If the len parameter is zero, return zero. */
2333 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2335 /* Evaluate and ignore arg1 and arg2 in case they have
2336 side-effects. */
2337 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2338 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2339 return const0_rtx;
2342 p1 = c_getstr (arg1);
2343 p2 = c_getstr (arg2);
2345 /* If all arguments are constant, evaluate at compile-time. */
2346 if (host_integerp (arg3, 1) && p1 && p2)
2348 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2349 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2352 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2353 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2354 if (host_integerp (arg3, 1)
2355 && (tree_low_cst (arg3, 1) == 1
2356 || (tree_low_cst (arg3, 1) > 1
2357 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2359 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2360 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2361 tree ind1 =
2362 fold (build1 (CONVERT_EXPR, integer_type_node,
2363 build1 (INDIRECT_REF, cst_uchar_node,
2364 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2365 tree ind2 =
2366 fold (build1 (CONVERT_EXPR, integer_type_node,
2367 build1 (INDIRECT_REF, cst_uchar_node,
2368 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2369 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2370 return expand_expr (result, target, mode, EXPAND_NORMAL);
2373 #ifdef HAVE_cmpstrsi
2374 /* If c_strlen can determine an expression for one of the string
2375 lengths, and it doesn't have side effects, then call
2376 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
2377 if (HAVE_cmpstrsi)
2379 tree newarglist, len = 0;
2381 /* Perhaps one of the strings is really constant, if so prefer
2382 that constant length over the other string's length. */
2383 if (p1)
2384 len = c_strlen (arg1);
2385 else if (p2)
2386 len = c_strlen (arg2);
2388 /* If we still don't have a len, try either string arg as long
2389 as they don't have side effects. */
2390 if (!len && !TREE_SIDE_EFFECTS (arg1))
2391 len = c_strlen (arg1);
2392 if (!len && !TREE_SIDE_EFFECTS (arg2))
2393 len = c_strlen (arg2);
2394 /* If we still don't have a length, punt. */
2395 if (!len)
2396 return 0;
2398 /* Add one to the string length. */
2399 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2401 /* The actual new length parameter is MIN(len,arg3). */
2402 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2404 newarglist = build_tree_list (NULL_TREE, len);
2405 newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2406 newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2407 return expand_builtin_memcmp (exp, newarglist, target);
2409 #endif
2411 return 0;
2414 /* Expand expression EXP, which is a call to the strcat builtin.
2415 Return 0 if we failed the caller should emit a normal call,
2416 otherwise try to get the result in TARGET, if convenient. */
2417 static rtx
2418 expand_builtin_strcat (arglist, target, mode)
2419 tree arglist;
2420 rtx target;
2421 enum machine_mode mode;
2423 /* If we need to check memory accesses, call the library function. */
2424 if (current_function_check_memory_usage)
2425 return 0;
2427 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2428 return 0;
2429 else
2431 tree dst = TREE_VALUE (arglist),
2432 src = TREE_VALUE (TREE_CHAIN (arglist));
2433 const char *p = c_getstr (src);
2435 /* If the string length is zero, return the dst parameter. */
2436 if (p && *p == '\0')
2437 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2439 return 0;
2443 /* Expand expression EXP, which is a call to the strncat builtin.
2444 Return 0 if we failed the caller should emit a normal call,
2445 otherwise try to get the result in TARGET, if convenient. */
2446 static rtx
2447 expand_builtin_strncat (arglist, target, mode)
2448 tree arglist;
2449 rtx target;
2450 enum machine_mode mode;
2452 /* If we need to check memory accesses, call the library function. */
2453 if (current_function_check_memory_usage)
2454 return 0;
2456 if (!validate_arglist (arglist,
2457 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2458 return 0;
2459 else
2461 tree dst = TREE_VALUE (arglist),
2462 src = TREE_VALUE (TREE_CHAIN (arglist)),
2463 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2464 const char *p = c_getstr (src);
2466 /* If the requested length is zero, or the src parameter string
2467 length is zero, return the dst parameter. */
2468 if ((TREE_CODE (len) == INTEGER_CST && compare_tree_int (len, 0) == 0)
2469 || (p && *p == '\0'))
2471 /* Evaluate and ignore the src and len parameters in case
2472 they have side-effects. */
2473 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2474 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2475 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2478 /* If the requested len is greater than or equal to the string
2479 length, call strcat. */
2480 if (TREE_CODE (len) == INTEGER_CST && p
2481 && compare_tree_int (len, strlen (p)) >= 0)
2483 tree newarglist =
2484 tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)),
2485 fn = built_in_decls[BUILT_IN_STRCAT];
2487 /* If the replacement _DECL isn't initialized, don't do the
2488 transformation. */
2489 if (!fn)
2490 return 0;
2492 return expand_expr (build_function_call_expr (fn, newarglist),
2493 target, mode, EXPAND_NORMAL);
2495 return 0;
2499 /* Expand expression EXP, which is a call to the strspn builtin.
2500 Return 0 if we failed the caller should emit a normal call,
2501 otherwise try to get the result in TARGET, if convenient. */
2502 static rtx
2503 expand_builtin_strspn (arglist, target, mode)
2504 tree arglist;
2505 rtx target;
2506 enum machine_mode mode;
2508 /* If we need to check memory accesses, call the library function. */
2509 if (current_function_check_memory_usage)
2510 return 0;
2512 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2513 return 0;
2514 else
2516 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2517 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2519 /* If both arguments are constants, evaluate at compile-time. */
2520 if (p1 && p2)
2522 const size_t r = strspn (p1, p2);
2523 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2526 /* If either argument is "", return 0. */
2527 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2529 /* Evaluate and ignore both arguments in case either one has
2530 side-effects. */
2531 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2532 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2533 return const0_rtx;
2535 return 0;
2539 /* Expand expression EXP, which is a call to the strcspn builtin.
2540 Return 0 if we failed the caller should emit a normal call,
2541 otherwise try to get the result in TARGET, if convenient. */
2542 static rtx
2543 expand_builtin_strcspn (arglist, target, mode)
2544 tree arglist;
2545 rtx target;
2546 enum machine_mode mode;
2548 /* If we need to check memory accesses, call the library function. */
2549 if (current_function_check_memory_usage)
2550 return 0;
2552 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2553 return 0;
2554 else
2556 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2557 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2559 /* If both arguments are constants, evaluate at compile-time. */
2560 if (p1 && p2)
2562 const size_t r = strcspn (p1, p2);
2563 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2566 /* If the first argument is "", return 0. */
2567 if (p1 && *p1 == '\0')
2569 /* Evaluate and ignore argument s2 in case it has
2570 side-effects. */
2571 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2572 return const0_rtx;
2575 /* If the second argument is "", return __builtin_strlen(s1). */
2576 if (p2 && *p2 == '\0')
2578 tree newarglist = build_tree_list (NULL_TREE, s1),
2579 fn = built_in_decls[BUILT_IN_STRLEN];
2581 /* If the replacement _DECL isn't initialized, don't do the
2582 transformation. */
2583 if (!fn)
2584 return 0;
2586 return expand_expr (build_function_call_expr (fn, newarglist),
2587 target, mode, EXPAND_NORMAL);
2589 return 0;
2593 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2594 if that's convenient. */
2597 expand_builtin_saveregs ()
2599 rtx val, seq;
2601 /* Don't do __builtin_saveregs more than once in a function.
2602 Save the result of the first call and reuse it. */
2603 if (saveregs_value != 0)
2604 return saveregs_value;
2606 /* When this function is called, it means that registers must be
2607 saved on entry to this function. So we migrate the call to the
2608 first insn of this function. */
2610 start_sequence ();
2612 #ifdef EXPAND_BUILTIN_SAVEREGS
2613 /* Do whatever the machine needs done in this case. */
2614 val = EXPAND_BUILTIN_SAVEREGS ();
2615 #else
2616 /* ??? We used to try and build up a call to the out of line function,
2617 guessing about what registers needed saving etc. This became much
2618 harder with __builtin_va_start, since we don't have a tree for a
2619 call to __builtin_saveregs to fall back on. There was exactly one
2620 port (i860) that used this code, and I'm unconvinced it could actually
2621 handle the general case. So we no longer try to handle anything
2622 weird and make the backend absorb the evil. */
2624 error ("__builtin_saveregs not supported by this target");
2625 val = const0_rtx;
2626 #endif
2628 seq = get_insns ();
2629 end_sequence ();
2631 saveregs_value = val;
2633 /* Put the sequence after the NOTE that starts the function. If this
2634 is inside a SEQUENCE, make the outer-level insn chain current, so
2635 the code is placed at the start of the function. */
2636 push_topmost_sequence ();
2637 emit_insns_after (seq, get_insns ());
2638 pop_topmost_sequence ();
2640 return val;
2643 /* __builtin_args_info (N) returns word N of the arg space info
2644 for the current function. The number and meanings of words
2645 is controlled by the definition of CUMULATIVE_ARGS. */
2647 static rtx
2648 expand_builtin_args_info (exp)
2649 tree exp;
2651 tree arglist = TREE_OPERAND (exp, 1);
2652 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2653 int *word_ptr = (int *) &current_function_args_info;
2654 #if 0
2655 /* These are used by the code below that is if 0'ed away */
2656 int i;
2657 tree type, elts, result;
2658 #endif
2660 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2661 abort ();
2663 if (arglist != 0)
2665 tree arg = TREE_VALUE (arglist);
2666 if (TREE_CODE (arg) != INTEGER_CST)
2667 error ("argument of `__builtin_args_info' must be constant");
2668 else
2670 int wordnum = TREE_INT_CST_LOW (arg);
2672 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
2673 error ("argument of `__builtin_args_info' out of range");
2674 else
2675 return GEN_INT (word_ptr[wordnum]);
2678 else
2679 error ("missing argument in `__builtin_args_info'");
2681 return const0_rtx;
2683 #if 0
2684 for (i = 0; i < nwords; i++)
2685 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2687 type = build_array_type (integer_type_node,
2688 build_index_type (build_int_2 (nwords, 0)));
2689 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2690 TREE_CONSTANT (result) = 1;
2691 TREE_STATIC (result) = 1;
2692 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2693 TREE_CONSTANT (result) = 1;
2694 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2695 #endif
2698 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2699 static rtx
2700 expand_builtin_next_arg (arglist)
2701 tree arglist;
2703 tree fntype = TREE_TYPE (current_function_decl);
2705 if ((TYPE_ARG_TYPES (fntype) == 0
2706 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2707 == void_type_node))
2708 && ! current_function_varargs)
2710 error ("`va_start' used in function with fixed args");
2711 return const0_rtx;
2714 if (arglist)
2716 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2717 tree arg = TREE_VALUE (arglist);
2719 /* Strip off all nops for the sake of the comparison. This
2720 is not quite the same as STRIP_NOPS. It does more.
2721 We must also strip off INDIRECT_EXPR for C++ reference
2722 parameters. */
2723 while (TREE_CODE (arg) == NOP_EXPR
2724 || TREE_CODE (arg) == CONVERT_EXPR
2725 || TREE_CODE (arg) == NON_LVALUE_EXPR
2726 || TREE_CODE (arg) == INDIRECT_REF)
2727 arg = TREE_OPERAND (arg, 0);
2728 if (arg != last_parm)
2729 warning ("second parameter of `va_start' not last named argument");
2731 else if (! current_function_varargs)
2732 /* Evidently an out of date version of <stdarg.h>; can't validate
2733 va_start's second argument, but can still work as intended. */
2734 warning ("`__builtin_next_arg' called without an argument");
2736 return expand_binop (Pmode, add_optab,
2737 current_function_internal_arg_pointer,
2738 current_function_arg_offset_rtx,
2739 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2742 /* Make it easier for the backends by protecting the valist argument
2743 from multiple evaluations. */
2745 static tree
2746 stabilize_va_list (valist, needs_lvalue)
2747 tree valist;
2748 int needs_lvalue;
2750 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2752 if (TREE_SIDE_EFFECTS (valist))
2753 valist = save_expr (valist);
2755 /* For this case, the backends will be expecting a pointer to
2756 TREE_TYPE (va_list_type_node), but it's possible we've
2757 actually been given an array (an actual va_list_type_node).
2758 So fix it. */
2759 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2761 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2762 tree p2 = build_pointer_type (va_list_type_node);
2764 valist = build1 (ADDR_EXPR, p2, valist);
2765 valist = fold (build1 (NOP_EXPR, p1, valist));
2768 else
2770 tree pt;
2772 if (! needs_lvalue)
2774 if (! TREE_SIDE_EFFECTS (valist))
2775 return valist;
2777 pt = build_pointer_type (va_list_type_node);
2778 valist = fold (build1 (ADDR_EXPR, pt, valist));
2779 TREE_SIDE_EFFECTS (valist) = 1;
2782 if (TREE_SIDE_EFFECTS (valist))
2783 valist = save_expr (valist);
2784 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2785 valist));
2788 return valist;
2791 /* The "standard" implementation of va_start: just assign `nextarg' to
2792 the variable. */
2793 void
2794 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2795 int stdarg_p;
2796 tree valist;
2797 rtx nextarg;
2799 tree t;
2801 if (! stdarg_p)
2803 /* The dummy named parameter is declared as a 'word' sized
2804 object, but if a 'word' is smaller than an 'int', it would
2805 have been promoted to int when it was added to the arglist. */
2806 int align = PARM_BOUNDARY / BITS_PER_UNIT;
2807 int size = MAX (UNITS_PER_WORD,
2808 GET_MODE_SIZE (TYPE_MODE (integer_type_node)));
2809 int offset = ((size + align - 1) / align) * align;
2810 nextarg = plus_constant (nextarg, -offset);
2813 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2814 make_tree (ptr_type_node, nextarg));
2815 TREE_SIDE_EFFECTS (t) = 1;
2817 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2820 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2821 __builtin_varargs_va_start, depending on STDARG_P. */
2822 static rtx
2823 expand_builtin_va_start (stdarg_p, arglist)
2824 int stdarg_p;
2825 tree arglist;
2827 rtx nextarg;
2828 tree chain = arglist, valist;
2830 if (stdarg_p)
2831 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2832 else
2833 nextarg = expand_builtin_next_arg (NULL_TREE);
2835 if (TREE_CHAIN (chain))
2836 error ("too many arguments to function `va_start'");
2838 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2840 #ifdef EXPAND_BUILTIN_VA_START
2841 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2842 #else
2843 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2844 #endif
2846 return const0_rtx;
2849 /* The "standard" implementation of va_arg: read the value from the
2850 current (padded) address and increment by the (padded) size. */
2853 std_expand_builtin_va_arg (valist, type)
2854 tree valist, type;
2856 tree addr_tree, t;
2857 HOST_WIDE_INT align;
2858 HOST_WIDE_INT rounded_size;
2859 rtx addr;
2861 /* Compute the rounded size of the type. */
2862 align = PARM_BOUNDARY / BITS_PER_UNIT;
2863 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2865 /* Get AP. */
2866 addr_tree = valist;
2867 if (PAD_VARARGS_DOWN)
2869 /* Small args are padded downward. */
2871 HOST_WIDE_INT adj;
2872 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
2873 if (rounded_size > align)
2874 adj = rounded_size;
2876 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2877 build_int_2 (rounded_size - adj, 0));
2880 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2881 addr = copy_to_reg (addr);
2883 /* Compute new value for AP. */
2884 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2885 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2886 build_int_2 (rounded_size, 0)));
2887 TREE_SIDE_EFFECTS (t) = 1;
2888 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2890 return addr;
2893 /* Expand __builtin_va_arg, which is not really a builtin function, but
2894 a very special sort of operator. */
2897 expand_builtin_va_arg (valist, type)
2898 tree valist, type;
2900 rtx addr, result;
2901 tree promoted_type, want_va_type, have_va_type;
2903 /* Verify that valist is of the proper type. */
2905 want_va_type = va_list_type_node;
2906 have_va_type = TREE_TYPE (valist);
2907 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2909 /* If va_list is an array type, the argument may have decayed
2910 to a pointer type, e.g. by being passed to another function.
2911 In that case, unwrap both types so that we can compare the
2912 underlying records. */
2913 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2914 || TREE_CODE (have_va_type) == POINTER_TYPE)
2916 want_va_type = TREE_TYPE (want_va_type);
2917 have_va_type = TREE_TYPE (have_va_type);
2920 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2922 error ("first argument to `va_arg' not of type `va_list'");
2923 addr = const0_rtx;
2926 /* Generate a diagnostic for requesting data of a type that cannot
2927 be passed through `...' due to type promotion at the call site. */
2928 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2930 const char *name = "<anonymous type>", *pname = 0;
2931 static int gave_help;
2933 if (TYPE_NAME (type))
2935 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2936 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2937 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2938 && DECL_NAME (TYPE_NAME (type)))
2939 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2941 if (TYPE_NAME (promoted_type))
2943 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2944 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2945 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2946 && DECL_NAME (TYPE_NAME (promoted_type)))
2947 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2950 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2951 if (! gave_help)
2953 gave_help = 1;
2954 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2957 addr = const0_rtx;
2959 else
2961 /* Make it easier for the backends by protecting the valist argument
2962 from multiple evaluations. */
2963 valist = stabilize_va_list (valist, 0);
2965 #ifdef EXPAND_BUILTIN_VA_ARG
2966 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2967 #else
2968 addr = std_expand_builtin_va_arg (valist, type);
2969 #endif
2972 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2973 MEM_ALIAS_SET (result) = get_varargs_alias_set ();
2975 return result;
2978 /* Expand ARGLIST, from a call to __builtin_va_end. */
2980 static rtx
2981 expand_builtin_va_end (arglist)
2982 tree arglist;
2984 tree valist = TREE_VALUE (arglist);
2986 #ifdef EXPAND_BUILTIN_VA_END
2987 valist = stabilize_va_list (valist, 0);
2988 EXPAND_BUILTIN_VA_END(arglist);
2989 #else
2990 /* Evaluate for side effects, if needed. I hate macros that don't
2991 do that. */
2992 if (TREE_SIDE_EFFECTS (valist))
2993 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2994 #endif
2996 return const0_rtx;
2999 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3000 builtin rather than just as an assignment in stdarg.h because of the
3001 nastiness of array-type va_list types. */
3003 static rtx
3004 expand_builtin_va_copy (arglist)
3005 tree arglist;
3007 tree dst, src, t;
3009 dst = TREE_VALUE (arglist);
3010 src = TREE_VALUE (TREE_CHAIN (arglist));
3012 dst = stabilize_va_list (dst, 1);
3013 src = stabilize_va_list (src, 0);
3015 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3017 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3018 TREE_SIDE_EFFECTS (t) = 1;
3019 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3021 else
3023 rtx dstb, srcb, size;
3025 /* Evaluate to pointers. */
3026 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3027 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3028 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3029 VOIDmode, EXPAND_NORMAL);
3031 /* "Dereference" to BLKmode memories. */
3032 dstb = gen_rtx_MEM (BLKmode, dstb);
3033 MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
3034 srcb = gen_rtx_MEM (BLKmode, srcb);
3035 MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
3037 /* Copy. */
3038 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
3041 return const0_rtx;
3044 /* Expand a call to one of the builtin functions __builtin_frame_address or
3045 __builtin_return_address. */
3046 static rtx
3047 expand_builtin_frame_address (exp)
3048 tree exp;
3050 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3051 tree arglist = TREE_OPERAND (exp, 1);
3053 /* The argument must be a nonnegative integer constant.
3054 It counts the number of frames to scan up the stack.
3055 The value is the return address saved in that frame. */
3056 if (arglist == 0)
3057 /* Warning about missing arg was already issued. */
3058 return const0_rtx;
3059 else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST
3060 || tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
3062 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3063 error ("invalid arg to `__builtin_frame_address'");
3064 else
3065 error ("invalid arg to `__builtin_return_address'");
3066 return const0_rtx;
3068 else
3070 rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3071 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
3072 hard_frame_pointer_rtx);
3074 /* Some ports cannot access arbitrary stack frames. */
3075 if (tem == NULL)
3077 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3078 warning ("unsupported arg to `__builtin_frame_address'");
3079 else
3080 warning ("unsupported arg to `__builtin_return_address'");
3081 return const0_rtx;
3084 /* For __builtin_frame_address, return what we've got. */
3085 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3086 return tem;
3088 if (GET_CODE (tem) != REG
3089 && ! CONSTANT_P (tem))
3090 tem = copy_to_mode_reg (Pmode, tem);
3091 return tem;
3095 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3096 we failed and the caller should emit a normal call, otherwise try to get
3097 the result in TARGET, if convenient. */
3098 static rtx
3099 expand_builtin_alloca (arglist, target)
3100 tree arglist;
3101 rtx target;
3103 rtx op0;
3105 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3106 return 0;
3108 /* Compute the argument. */
3109 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3111 /* Allocate the desired space. */
3112 return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3115 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
3116 Return 0 if a normal call should be emitted rather than expanding the
3117 function in-line. If convenient, the result should be placed in TARGET.
3118 SUBTARGET may be used as the target for computing one of EXP's operands. */
3119 static rtx
3120 expand_builtin_ffs (arglist, target, subtarget)
3121 tree arglist;
3122 rtx target, subtarget;
3124 rtx op0;
3125 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3126 return 0;
3128 /* Compute the argument. */
3129 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3130 /* Compute ffs, into TARGET if possible.
3131 Set TARGET to wherever the result comes back. */
3132 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3133 ffs_optab, op0, target, 1);
3134 if (target == 0)
3135 abort ();
3136 return target;
3139 /* If the string passed to fputs is a constant and is one character
3140 long, we attempt to transform this call into __builtin_fputc(). */
3141 static rtx
3142 expand_builtin_fputs (arglist, ignore)
3143 tree arglist;
3144 int ignore;
3146 tree len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
3147 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
3149 /* If the return value is used, or the replacement _DECL isn't
3150 initialized, don't do the transformation. */
3151 if (!ignore || !fn_fputc || !fn_fwrite)
3152 return 0;
3154 /* Verify the arguments in the original call. */
3155 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
3156 || current_function_check_memory_usage)
3157 return 0;
3159 /* Get the length of the string passed to fputs. If the length
3160 can't be determined, punt. */
3161 if (!(len = c_strlen (TREE_VALUE (arglist)))
3162 || TREE_CODE (len) != INTEGER_CST)
3163 return 0;
3165 switch (compare_tree_int (len, 1))
3167 case -1: /* length is 0, delete the call entirely . */
3169 /* Evaluate and ignore the argument in case it has
3170 side-effects. */
3171 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3172 VOIDmode, EXPAND_NORMAL);
3173 return const0_rtx;
3175 case 0: /* length is 1, call fputc. */
3177 const char *p = c_getstr (TREE_VALUE (arglist));
3179 if (p != NULL)
3181 /* New argument list transforming fputs(string, stream) to
3182 fputc(string[0], stream). */
3183 arglist =
3184 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3185 arglist =
3186 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3187 fn = fn_fputc;
3188 break;
3191 /* FALLTHROUGH */
3192 case 1: /* length is greater than 1, call fwrite. */
3194 tree string_arg = TREE_VALUE (arglist);
3196 /* New argument list transforming fputs(string, stream) to
3197 fwrite(string, 1, len, stream). */
3198 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3199 arglist = tree_cons (NULL_TREE, len, arglist);
3200 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3201 arglist = tree_cons (NULL_TREE, string_arg, arglist);
3202 fn = fn_fwrite;
3203 break;
3205 default:
3206 abort();
3209 return expand_expr (build_function_call_expr (fn, arglist),
3210 (ignore ? const0_rtx : NULL_RTX),
3211 VOIDmode, EXPAND_NORMAL);
3214 /* Expand a call to __builtin_expect. We return our argument and
3215 emit a NOTE_INSN_EXPECTED_VALUE note. */
3217 static rtx
3218 expand_builtin_expect (arglist, target)
3219 tree arglist;
3220 rtx target;
3222 tree exp, c;
3223 rtx note, rtx_c;
3225 if (arglist == NULL_TREE
3226 || TREE_CHAIN (arglist) == NULL_TREE)
3227 return const0_rtx;
3228 exp = TREE_VALUE (arglist);
3229 c = TREE_VALUE (TREE_CHAIN (arglist));
3231 if (TREE_CODE (c) != INTEGER_CST)
3233 error ("second arg to `__builtin_expect' must be a constant");
3234 c = integer_zero_node;
3237 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3239 /* Don't bother with expected value notes for integral constants. */
3240 if (GET_CODE (target) != CONST_INT)
3242 /* We do need to force this into a register so that we can be
3243 moderately sure to be able to correctly interpret the branch
3244 condition later. */
3245 target = force_reg (GET_MODE (target), target);
3247 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3249 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3250 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3253 return target;
3256 /* Expand an expression EXP that calls a built-in function,
3257 with result going to TARGET if that's convenient
3258 (and in mode MODE if that's convenient).
3259 SUBTARGET may be used as the target for computing one of EXP's operands.
3260 IGNORE is nonzero if the value is to be ignored. */
3263 expand_builtin (exp, target, subtarget, mode, ignore)
3264 tree exp;
3265 rtx target;
3266 rtx subtarget;
3267 enum machine_mode mode;
3268 int ignore;
3270 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3271 tree arglist = TREE_OPERAND (exp, 1);
3272 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3274 #ifdef MD_EXPAND_BUILTIN
3275 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3276 return MD_EXPAND_BUILTIN (exp, target, subtarget, mode, ignore);
3277 #endif
3279 /* When not optimizing, generate calls to library functions for a certain
3280 set of builtins. */
3281 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
3282 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
3283 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_MEMSET
3284 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
3285 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
3286 || fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
3287 || fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
3288 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
3289 || fcode == BUILT_IN_STRNCPY || fcode == BUILT_IN_STRNCMP
3290 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
3291 || fcode == BUILT_IN_STRCAT || fcode == BUILT_IN_STRNCAT
3292 || fcode == BUILT_IN_STRSPN || fcode == BUILT_IN_STRCSPN
3293 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
3294 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
3295 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
3296 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
3297 return expand_call (exp, target, ignore);
3299 switch (fcode)
3301 case BUILT_IN_ABS:
3302 case BUILT_IN_FABS:
3303 /* build_function_call changes these into ABS_EXPR. */
3304 abort ();
3306 case BUILT_IN_CONJ:
3307 case BUILT_IN_CREAL:
3308 case BUILT_IN_CIMAG:
3309 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3310 and IMAGPART_EXPR. */
3311 abort ();
3313 case BUILT_IN_SIN:
3314 case BUILT_IN_COS:
3315 /* Treat these like sqrt, but only if the user asks for them. */
3316 if (! flag_fast_math)
3317 break;
3318 case BUILT_IN_FSQRT:
3319 target = expand_builtin_mathfn (exp, target, subtarget);
3320 if (target)
3321 return target;
3322 break;
3324 case BUILT_IN_FMOD:
3325 break;
3327 case BUILT_IN_APPLY_ARGS:
3328 return expand_builtin_apply_args ();
3330 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3331 FUNCTION with a copy of the parameters described by
3332 ARGUMENTS, and ARGSIZE. It returns a block of memory
3333 allocated on the stack into which is stored all the registers
3334 that might possibly be used for returning the result of a
3335 function. ARGUMENTS is the value returned by
3336 __builtin_apply_args. ARGSIZE is the number of bytes of
3337 arguments that must be copied. ??? How should this value be
3338 computed? We'll also need a safe worst case value for varargs
3339 functions. */
3340 case BUILT_IN_APPLY:
3341 if (!validate_arglist (arglist, POINTER_TYPE,
3342 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
3343 && !validate_arglist (arglist, REFERENCE_TYPE,
3344 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3345 return const0_rtx;
3346 else
3348 int i;
3349 tree t;
3350 rtx ops[3];
3352 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
3353 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
3355 return expand_builtin_apply (ops[0], ops[1], ops[2]);
3358 /* __builtin_return (RESULT) causes the function to return the
3359 value described by RESULT. RESULT is address of the block of
3360 memory returned by __builtin_apply. */
3361 case BUILT_IN_RETURN:
3362 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3363 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
3364 NULL_RTX, VOIDmode, 0));
3365 return const0_rtx;
3367 case BUILT_IN_SAVEREGS:
3368 return expand_builtin_saveregs ();
3370 case BUILT_IN_ARGS_INFO:
3371 return expand_builtin_args_info (exp);
3373 /* Return the address of the first anonymous stack arg. */
3374 case BUILT_IN_NEXT_ARG:
3375 return expand_builtin_next_arg (arglist);
3377 case BUILT_IN_CLASSIFY_TYPE:
3378 return expand_builtin_classify_type (arglist);
3380 case BUILT_IN_CONSTANT_P:
3381 return expand_builtin_constant_p (exp);
3383 case BUILT_IN_FRAME_ADDRESS:
3384 case BUILT_IN_RETURN_ADDRESS:
3385 return expand_builtin_frame_address (exp);
3387 /* Returns the address of the area where the structure is returned.
3388 0 otherwise. */
3389 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
3390 if (arglist != 0
3391 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3392 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
3393 return const0_rtx;
3394 else
3395 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3397 case BUILT_IN_ALLOCA:
3398 target = expand_builtin_alloca (arglist, target);
3399 if (target)
3400 return target;
3401 break;
3403 case BUILT_IN_FFS:
3404 target = expand_builtin_ffs (arglist, target, subtarget);
3405 if (target)
3406 return target;
3407 break;
3409 case BUILT_IN_STRLEN:
3410 target = expand_builtin_strlen (exp, target);
3411 if (target)
3412 return target;
3413 break;
3415 case BUILT_IN_STRCPY:
3416 target = expand_builtin_strcpy (exp);
3417 if (target)
3418 return target;
3419 break;
3421 case BUILT_IN_STRNCPY:
3422 target = expand_builtin_strncpy (arglist, target, mode);
3423 if (target)
3424 return target;
3425 break;
3427 case BUILT_IN_STRCAT:
3428 target = expand_builtin_strcat (arglist, target, mode);
3429 if (target)
3430 return target;
3431 break;
3433 case BUILT_IN_STRNCAT:
3434 target = expand_builtin_strncat (arglist, target, mode);
3435 if (target)
3436 return target;
3437 break;
3439 case BUILT_IN_STRSPN:
3440 target = expand_builtin_strspn (arglist, target, mode);
3441 if (target)
3442 return target;
3443 break;
3445 case BUILT_IN_STRCSPN:
3446 target = expand_builtin_strcspn (arglist, target, mode);
3447 if (target)
3448 return target;
3449 break;
3451 case BUILT_IN_STRSTR:
3452 target = expand_builtin_strstr (arglist, target, mode);
3453 if (target)
3454 return target;
3455 break;
3457 case BUILT_IN_STRPBRK:
3458 target = expand_builtin_strpbrk (arglist, target, mode);
3459 if (target)
3460 return target;
3461 break;
3463 case BUILT_IN_INDEX:
3464 case BUILT_IN_STRCHR:
3465 target = expand_builtin_strchr (arglist, target, mode);
3466 if (target)
3467 return target;
3468 break;
3470 case BUILT_IN_RINDEX:
3471 case BUILT_IN_STRRCHR:
3472 target = expand_builtin_strrchr (arglist, target, mode);
3473 if (target)
3474 return target;
3475 break;
3477 case BUILT_IN_MEMCPY:
3478 target = expand_builtin_memcpy (arglist);
3479 if (target)
3480 return target;
3481 break;
3483 case BUILT_IN_MEMSET:
3484 target = expand_builtin_memset (exp);
3485 if (target)
3486 return target;
3487 break;
3489 case BUILT_IN_BZERO:
3490 target = expand_builtin_bzero (exp);
3491 if (target)
3492 return target;
3493 break;
3495 case BUILT_IN_STRCMP:
3496 target = expand_builtin_strcmp (exp, target, mode);
3497 if (target)
3498 return target;
3499 break;
3501 case BUILT_IN_STRNCMP:
3502 target = expand_builtin_strncmp (exp, target, mode);
3503 if (target)
3504 return target;
3505 break;
3507 /* These comparison functions need an instruction that returns an actual
3508 index. An ordinary compare that just sets the condition codes
3509 is not enough. */
3510 #ifdef HAVE_cmpstrsi
3511 case BUILT_IN_BCMP:
3512 case BUILT_IN_MEMCMP:
3513 target = expand_builtin_memcmp (exp, arglist, target);
3514 if (target)
3515 return target;
3516 break;
3517 #else
3518 case BUILT_IN_BCMP:
3519 case BUILT_IN_MEMCMP:
3520 break;
3521 #endif
3523 case BUILT_IN_SETJMP:
3524 target = expand_builtin_setjmp (arglist, target);
3525 if (target)
3526 return target;
3527 break;
3529 /* __builtin_longjmp is passed a pointer to an array of five words.
3530 It's similar to the C library longjmp function but works with
3531 __builtin_setjmp above. */
3532 case BUILT_IN_LONGJMP:
3533 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3534 break;
3535 else
3537 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3538 VOIDmode, 0);
3539 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
3540 NULL_RTX, VOIDmode, 0);
3542 if (value != const1_rtx)
3544 error ("__builtin_longjmp second argument must be 1");
3545 return const0_rtx;
3548 expand_builtin_longjmp (buf_addr, value);
3549 return const0_rtx;
3552 case BUILT_IN_TRAP:
3553 #ifdef HAVE_trap
3554 if (HAVE_trap)
3555 emit_insn (gen_trap ());
3556 else
3557 #endif
3558 error ("__builtin_trap not supported by this target");
3559 emit_barrier ();
3560 return const0_rtx;
3562 case BUILT_IN_PUTCHAR:
3563 case BUILT_IN_PUTS:
3564 case BUILT_IN_FPUTC:
3565 case BUILT_IN_FWRITE:
3566 break;
3567 case BUILT_IN_FPUTS:
3568 target = expand_builtin_fputs (arglist, ignore);
3569 if (target)
3570 return target;
3571 break;
3573 /* Various hooks for the DWARF 2 __throw routine. */
3574 case BUILT_IN_UNWIND_INIT:
3575 expand_builtin_unwind_init ();
3576 return const0_rtx;
3577 case BUILT_IN_DWARF_CFA:
3578 return virtual_cfa_rtx;
3579 #ifdef DWARF2_UNWIND_INFO
3580 case BUILT_IN_DWARF_FP_REGNUM:
3581 return expand_builtin_dwarf_fp_regnum ();
3582 case BUILT_IN_INIT_DWARF_REG_SIZES:
3583 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3584 return const0_rtx;
3585 #endif
3586 case BUILT_IN_FROB_RETURN_ADDR:
3587 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3588 case BUILT_IN_EXTRACT_RETURN_ADDR:
3589 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3590 case BUILT_IN_EH_RETURN:
3591 expand_builtin_eh_return (TREE_VALUE (arglist),
3592 TREE_VALUE (TREE_CHAIN (arglist)),
3593 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
3594 return const0_rtx;
3595 case BUILT_IN_VARARGS_START:
3596 return expand_builtin_va_start (0, arglist);
3597 case BUILT_IN_STDARG_START:
3598 return expand_builtin_va_start (1, arglist);
3599 case BUILT_IN_VA_END:
3600 return expand_builtin_va_end (arglist);
3601 case BUILT_IN_VA_COPY:
3602 return expand_builtin_va_copy (arglist);
3603 case BUILT_IN_EXPECT:
3604 return expand_builtin_expect (arglist, target);
3606 default: /* just do library call, if unknown builtin */
3607 error ("built-in function `%s' not currently supported",
3608 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3611 /* The switch statement above can drop through to cause the function
3612 to be called normally. */
3613 return expand_call (exp, target, ignore);
3616 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3617 constant. ARGLIST is the argument list of the call. */
3619 static tree
3620 fold_builtin_constant_p (arglist)
3621 tree arglist;
3623 if (arglist == 0)
3624 return 0;
3626 arglist = TREE_VALUE (arglist);
3628 /* We return 1 for a numeric type that's known to be a constant
3629 value at compile-time or for an aggregate type that's a
3630 literal constant. */
3631 STRIP_NOPS (arglist);
3633 /* If we know this is a constant, emit the constant of one. */
3634 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3635 || (TREE_CODE (arglist) == CONSTRUCTOR
3636 && TREE_CONSTANT (arglist))
3637 || (TREE_CODE (arglist) == ADDR_EXPR
3638 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3639 return integer_one_node;
3641 /* If we aren't going to be running CSE or this expression
3642 has side effects, show we don't know it to be a constant.
3643 Likewise if it's a pointer or aggregate type since in those
3644 case we only want literals, since those are only optimized
3645 when generating RTL, not later. */
3646 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3647 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3648 || POINTER_TYPE_P (TREE_TYPE (arglist)))
3649 return integer_zero_node;
3651 return 0;
3654 /* Used by constant folding to eliminate some builtin calls early. EXP is
3655 the CALL_EXPR of a call to a builtin function. */
3657 tree
3658 fold_builtin (exp)
3659 tree exp;
3661 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3662 tree arglist = TREE_OPERAND (exp, 1);
3663 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3665 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3666 return 0;
3668 switch (fcode)
3670 case BUILT_IN_CONSTANT_P:
3671 return fold_builtin_constant_p (arglist);
3673 case BUILT_IN_STRLEN:
3674 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3676 tree len = c_strlen (TREE_VALUE (arglist));
3677 if (len != 0)
3678 return len;
3680 break;
3682 default:
3683 break;
3686 return 0;
3689 static tree
3690 build_function_call_expr (fn, arglist)
3691 tree fn, arglist;
3693 tree call_expr;
3695 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3696 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
3697 call_expr, arglist);
3698 TREE_SIDE_EFFECTS (call_expr) = 1;
3699 return fold (call_expr);
3702 /* This function validates the types of a function call argument list
3703 represented as a tree chain of parameters against a specified list
3704 of tree_codes. If the last specifier is a 0, that represents an
3705 ellipses, otherwise the last specifier must be a VOID_TYPE. */
3706 static int
3707 validate_arglist VPARAMS ((tree arglist, ...))
3709 #ifndef ANSI_PROTOTYPES
3710 tree arglist;
3711 #endif
3712 enum tree_code code;
3713 va_list ap;
3715 VA_START (ap, arglist);
3717 #ifndef ANSI_PROTOTYPES
3718 arglist = va_arg (ap, tree);
3719 #endif
3721 do {
3722 code = va_arg (ap, enum tree_code);
3723 switch (code)
3725 case 0:
3726 /* This signifies an ellipses, any further arguments are all ok. */
3727 va_end (ap);
3728 return 1;
3729 case VOID_TYPE:
3730 /* This signifies an endlink, if no arguments remain, return
3731 true, otherwise return false. */
3732 va_end (ap);
3733 return arglist == 0;
3734 default:
3735 /* If no parameters remain or the parameter's code does not
3736 match the specified code, return false. Otherwise continue
3737 checking any remaining arguments. */
3738 if (arglist == 0 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
3740 va_end (ap);
3741 return 0;
3743 break;
3745 arglist = TREE_CHAIN (arglist);
3746 } while (1);