* config/i386/i386.md (mmx_pinsrw): Output operands in correct
[official-gcc.git] / gcc / builtins.c
blob8430a23f82eeb0891daa152e5b4682ea60d48738
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 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 "defaults.h"
41 #include "toplev.h"
42 #include "tm_p.h"
44 #define CALLED_AS_BUILT_IN(NODE) \
45 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
47 /* Register mappings for target machines without register windows. */
48 #ifndef INCOMING_REGNO
49 #define INCOMING_REGNO(OUT) (OUT)
50 #endif
51 #ifndef OUTGOING_REGNO
52 #define OUTGOING_REGNO(IN) (IN)
53 #endif
55 #ifndef PAD_VARARGS_DOWN
56 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
57 #endif
59 /* Define the names of the builtin function types and codes. */
60 const char *const built_in_class_names[4]
61 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
63 #define DEF_BUILTIN(x) STRINGIFY(x),
64 const char *const built_in_names[(int) END_BUILTINS] =
66 #include "builtins.def"
68 #undef DEF_BUILTIN
70 /* Setup an array of _DECL trees, make sure each element is
71 initialized to NULL_TREE. */
72 #define DEF_BUILTIN(x) NULL_TREE,
73 tree built_in_decls[(int) END_BUILTINS] =
75 #include "builtins.def"
77 #undef DEF_BUILTIN
79 tree (*lang_type_promotes_to) PARAMS ((tree));
81 static int get_pointer_alignment PARAMS ((tree, unsigned));
82 static tree c_strlen PARAMS ((tree));
83 static const char *c_getstr PARAMS ((tree));
84 static rtx get_memory_rtx PARAMS ((tree));
85 static int apply_args_size PARAMS ((void));
86 static int apply_result_size PARAMS ((void));
87 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
88 static rtx result_vector PARAMS ((int, rtx));
89 #endif
90 static rtx expand_builtin_apply_args PARAMS ((void));
91 static rtx expand_builtin_apply_args_1 PARAMS ((void));
92 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
93 static void expand_builtin_return PARAMS ((rtx));
94 static rtx expand_builtin_classify_type PARAMS ((tree));
95 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
96 static rtx expand_builtin_constant_p PARAMS ((tree));
97 static rtx expand_builtin_args_info PARAMS ((tree));
98 static rtx expand_builtin_next_arg PARAMS ((tree));
99 static rtx expand_builtin_va_start PARAMS ((int, tree));
100 static rtx expand_builtin_va_end PARAMS ((tree));
101 static rtx expand_builtin_va_copy PARAMS ((tree));
102 #ifdef HAVE_cmpstrsi
103 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
104 #endif
105 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
106 enum machine_mode));
107 static rtx expand_builtin_memcpy PARAMS ((tree));
108 static rtx expand_builtin_strcpy PARAMS ((tree));
109 static rtx expand_builtin_memset PARAMS ((tree));
110 static rtx expand_builtin_bzero PARAMS ((tree));
111 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
112 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
113 enum machine_mode));
114 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
115 enum machine_mode));
116 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
117 enum machine_mode));
118 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
119 enum machine_mode));
120 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
121 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
122 static rtx expand_builtin_frame_address PARAMS ((tree));
123 static rtx expand_builtin_fputs PARAMS ((tree, int));
124 static tree stabilize_va_list PARAMS ((tree, int));
125 static rtx expand_builtin_expect PARAMS ((tree, rtx));
126 static tree fold_builtin_constant_p PARAMS ((tree));
128 /* Return the alignment in bits of EXP, a pointer valued expression.
129 But don't return more than MAX_ALIGN no matter what.
130 The alignment returned is, by default, the alignment of the thing that
131 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
133 Otherwise, look at the expression to see if we can do better, i.e., if the
134 expression is actually pointing at an object whose alignment is tighter. */
136 static int
137 get_pointer_alignment (exp, max_align)
138 tree exp;
139 unsigned max_align;
141 unsigned align, inner;
143 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
144 return 0;
146 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
147 align = MIN (align, max_align);
149 while (1)
151 switch (TREE_CODE (exp))
153 case NOP_EXPR:
154 case CONVERT_EXPR:
155 case NON_LVALUE_EXPR:
156 exp = TREE_OPERAND (exp, 0);
157 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
158 return align;
160 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
161 align = MIN (inner, max_align);
162 break;
164 case PLUS_EXPR:
165 /* If sum of pointer + int, restrict our maximum alignment to that
166 imposed by the integer. If not, we can't do any better than
167 ALIGN. */
168 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
169 return align;
171 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1) * BITS_PER_UNIT)
172 & (max_align - 1))
173 != 0)
174 max_align >>= 1;
176 exp = TREE_OPERAND (exp, 0);
177 break;
179 case ADDR_EXPR:
180 /* See what we are pointing at and look at its alignment. */
181 exp = TREE_OPERAND (exp, 0);
182 if (TREE_CODE (exp) == FUNCTION_DECL)
183 align = FUNCTION_BOUNDARY;
184 else if (DECL_P (exp))
185 align = DECL_ALIGN (exp);
186 #ifdef CONSTANT_ALIGNMENT
187 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
188 align = CONSTANT_ALIGNMENT (exp, align);
189 #endif
190 return MIN (align, max_align);
192 default:
193 return align;
198 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
199 way, because it could contain a zero byte in the middle.
200 TREE_STRING_LENGTH is the size of the character array, not the string.
202 The value returned is of type `ssizetype'.
204 Unfortunately, string_constant can't access the values of const char
205 arrays with initializers, so neither can we do so here. */
207 static tree
208 c_strlen (src)
209 tree src;
211 tree offset_node;
212 int offset, max;
213 char *ptr;
215 src = string_constant (src, &offset_node);
216 if (src == 0)
217 return 0;
219 max = TREE_STRING_LENGTH (src) - 1;
220 ptr = TREE_STRING_POINTER (src);
222 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
224 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
225 compute the offset to the following null if we don't know where to
226 start searching for it. */
227 int i;
229 for (i = 0; i < max; i++)
230 if (ptr[i] == 0)
231 return 0;
233 /* We don't know the starting offset, but we do know that the string
234 has no internal zero bytes. We can assume that the offset falls
235 within the bounds of the string; otherwise, the programmer deserves
236 what he gets. Subtract the offset from the length of the string,
237 and return that. This would perhaps not be valid if we were dealing
238 with named arrays in addition to literal string constants. */
240 return size_diffop (size_int (max), offset_node);
243 /* We have a known offset into the string. Start searching there for
244 a null character. */
245 if (offset_node == 0)
246 offset = 0;
247 else
249 /* Did we get a long long offset? If so, punt. */
250 if (TREE_INT_CST_HIGH (offset_node) != 0)
251 return 0;
252 offset = TREE_INT_CST_LOW (offset_node);
255 /* If the offset is known to be out of bounds, warn, and call strlen at
256 runtime. */
257 if (offset < 0 || offset > max)
259 warning ("offset outside bounds of constant string");
260 return 0;
263 /* Use strlen to search for the first zero byte. Since any strings
264 constructed with build_string will have nulls appended, we win even
265 if we get handed something like (char[4])"abcd".
267 Since OFFSET is our starting index into the string, no further
268 calculation is needed. */
269 return ssize_int (strlen (ptr + offset));
272 /* Return a char pointer for a C string if it is a string constant
273 or sum of string constant and integer constant. */
275 static const char *
276 c_getstr (src)
277 tree src;
279 tree offset_node;
280 int offset, max;
281 char *ptr;
283 src = string_constant (src, &offset_node);
284 if (src == 0)
285 return 0;
287 max = TREE_STRING_LENGTH (src) - 1;
288 ptr = TREE_STRING_POINTER (src);
290 if (!offset_node)
291 offset = 0;
292 else if (TREE_CODE (offset_node) != INTEGER_CST)
293 return 0;
294 else
296 /* Did we get a long long offset? If so, punt. */
297 if (TREE_INT_CST_HIGH (offset_node) != 0)
298 return 0;
299 offset = TREE_INT_CST_LOW (offset_node);
300 if (offset < 0 || offset > max)
301 return 0;
304 return (const char *) ptr + offset;
307 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
308 times to get the address of either a higher stack frame, or a return
309 address located within it (depending on FNDECL_CODE). */
312 expand_builtin_return_addr (fndecl_code, count, tem)
313 enum built_in_function fndecl_code;
314 int count;
315 rtx tem;
317 int i;
319 /* Some machines need special handling before we can access
320 arbitrary frames. For example, on the sparc, we must first flush
321 all register windows to the stack. */
322 #ifdef SETUP_FRAME_ADDRESSES
323 if (count > 0)
324 SETUP_FRAME_ADDRESSES ();
325 #endif
327 /* On the sparc, the return address is not in the frame, it is in a
328 register. There is no way to access it off of the current frame
329 pointer, but it can be accessed off the previous frame pointer by
330 reading the value from the register window save area. */
331 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
332 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
333 count--;
334 #endif
336 /* Scan back COUNT frames to the specified frame. */
337 for (i = 0; i < count; i++)
339 /* Assume the dynamic chain pointer is in the word that the
340 frame address points to, unless otherwise specified. */
341 #ifdef DYNAMIC_CHAIN_ADDRESS
342 tem = DYNAMIC_CHAIN_ADDRESS (tem);
343 #endif
344 tem = memory_address (Pmode, tem);
345 tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
346 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
349 /* For __builtin_frame_address, return what we've got. */
350 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
351 return tem;
353 /* For __builtin_return_address, Get the return address from that
354 frame. */
355 #ifdef RETURN_ADDR_RTX
356 tem = RETURN_ADDR_RTX (count, tem);
357 #else
358 tem = memory_address (Pmode,
359 plus_constant (tem, GET_MODE_SIZE (Pmode)));
360 tem = gen_rtx_MEM (Pmode, tem);
361 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
362 #endif
363 return tem;
366 /* Alias set used for setjmp buffer. */
367 static HOST_WIDE_INT setjmp_alias_set = -1;
369 /* __builtin_setjmp is passed a pointer to an array of five words (not
370 all will be used on all machines). It operates similarly to the C
371 library function of the same name, but is more efficient. Much of
372 the code below (and for longjmp) is copied from the handling of
373 non-local gotos.
375 NOTE: This is intended for use by GNAT and the exception handling
376 scheme in the compiler and will only work in the method used by
377 them. */
380 expand_builtin_setjmp (buf_addr, target, first_label, next_label)
381 rtx buf_addr;
382 rtx target;
383 rtx first_label, next_label;
385 rtx lab1 = gen_label_rtx ();
386 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
387 enum machine_mode value_mode;
388 rtx stack_save;
389 rtx mem;
391 value_mode = TYPE_MODE (integer_type_node);
393 if (setjmp_alias_set == -1)
394 setjmp_alias_set = new_alias_set ();
396 #ifdef POINTERS_EXTEND_UNSIGNED
397 buf_addr = convert_memory_address (Pmode, buf_addr);
398 #endif
400 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
402 if (target == 0 || GET_CODE (target) != REG
403 || REGNO (target) < FIRST_PSEUDO_REGISTER)
404 target = gen_reg_rtx (value_mode);
406 emit_queue ();
408 /* We store the frame pointer and the address of lab1 in the buffer
409 and use the rest of it for the stack save area, which is
410 machine-dependent. */
412 #ifndef BUILTIN_SETJMP_FRAME_VALUE
413 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
414 #endif
416 mem = gen_rtx_MEM (Pmode, buf_addr);
417 MEM_ALIAS_SET (mem) = setjmp_alias_set;
418 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
420 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
421 MEM_ALIAS_SET (mem) = setjmp_alias_set;
423 emit_move_insn (validize_mem (mem),
424 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
426 stack_save = gen_rtx_MEM (sa_mode,
427 plus_constant (buf_addr,
428 2 * GET_MODE_SIZE (Pmode)));
429 MEM_ALIAS_SET (stack_save) = setjmp_alias_set;
430 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
432 /* If there is further processing to do, do it. */
433 #ifdef HAVE_builtin_setjmp_setup
434 if (HAVE_builtin_setjmp_setup)
435 emit_insn (gen_builtin_setjmp_setup (buf_addr));
436 #endif
438 /* Set TARGET to zero and branch to the first-time-through label. */
439 emit_move_insn (target, const0_rtx);
440 emit_jump_insn (gen_jump (first_label));
441 emit_barrier ();
442 emit_label (lab1);
444 /* Tell flow about the strange goings on. Putting `lab1' on
445 `nonlocal_goto_handler_labels' to indicates that function
446 calls may traverse the arc back to this label. */
448 current_function_has_nonlocal_label = 1;
449 nonlocal_goto_handler_labels
450 = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
452 /* Clobber the FP when we get here, so we have to make sure it's
453 marked as used by this function. */
454 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
456 /* Mark the static chain as clobbered here so life information
457 doesn't get messed up for it. */
458 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
460 /* Now put in the code to restore the frame pointer, and argument
461 pointer, if needed. The code below is from expand_end_bindings
462 in stmt.c; see detailed documentation there. */
463 #ifdef HAVE_nonlocal_goto
464 if (! HAVE_nonlocal_goto)
465 #endif
466 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
468 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
469 if (fixed_regs[ARG_POINTER_REGNUM])
471 #ifdef ELIMINABLE_REGS
472 size_t i;
473 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
475 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
476 if (elim_regs[i].from == ARG_POINTER_REGNUM
477 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
478 break;
480 if (i == ARRAY_SIZE (elim_regs))
481 #endif
483 /* Now restore our arg pointer from the address at which it
484 was saved in our stack frame.
485 If there hasn't be space allocated for it yet, make
486 some now. */
487 if (arg_pointer_save_area == 0)
488 arg_pointer_save_area
489 = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
490 emit_move_insn (virtual_incoming_args_rtx,
491 copy_to_reg (arg_pointer_save_area));
494 #endif
496 #ifdef HAVE_builtin_setjmp_receiver
497 if (HAVE_builtin_setjmp_receiver)
498 emit_insn (gen_builtin_setjmp_receiver (lab1));
499 else
500 #endif
501 #ifdef HAVE_nonlocal_goto_receiver
502 if (HAVE_nonlocal_goto_receiver)
503 emit_insn (gen_nonlocal_goto_receiver ());
504 else
505 #endif
507 ; /* Nothing */
510 /* Set TARGET, and branch to the next-time-through label. */
511 emit_move_insn (target, const1_rtx);
512 emit_jump_insn (gen_jump (next_label));
513 emit_barrier ();
515 return target;
518 /* __builtin_longjmp is passed a pointer to an array of five words (not
519 all will be used on all machines). It operates similarly to the C
520 library function of the same name, but is more efficient. Much of
521 the code below is copied from the handling of non-local gotos.
523 NOTE: This is intended for use by GNAT and the exception handling
524 scheme in the compiler and will only work in the method used by
525 them. */
527 void
528 expand_builtin_longjmp (buf_addr, value)
529 rtx buf_addr, value;
531 rtx fp, lab, stack;
532 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
534 if (setjmp_alias_set == -1)
535 setjmp_alias_set = new_alias_set ();
537 #ifdef POINTERS_EXTEND_UNSIGNED
538 buf_addr = convert_memory_address (Pmode, buf_addr);
539 #endif
540 buf_addr = force_reg (Pmode, buf_addr);
542 /* We used to store value in static_chain_rtx, but that fails if pointers
543 are smaller than integers. We instead require that the user must pass
544 a second argument of 1, because that is what builtin_setjmp will
545 return. This also makes EH slightly more efficient, since we are no
546 longer copying around a value that we don't care about. */
547 if (value != const1_rtx)
548 abort ();
550 #ifdef HAVE_builtin_longjmp
551 if (HAVE_builtin_longjmp)
552 emit_insn (gen_builtin_longjmp (buf_addr));
553 else
554 #endif
556 fp = gen_rtx_MEM (Pmode, buf_addr);
557 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
558 GET_MODE_SIZE (Pmode)));
560 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
561 2 * GET_MODE_SIZE (Pmode)));
562 MEM_ALIAS_SET (fp) = MEM_ALIAS_SET (lab) = MEM_ALIAS_SET (stack)
563 = setjmp_alias_set;
565 /* Pick up FP, label, and SP from the block and jump. This code is
566 from expand_goto in stmt.c; see there for detailed comments. */
567 #if HAVE_nonlocal_goto
568 if (HAVE_nonlocal_goto)
569 /* We have to pass a value to the nonlocal_goto pattern that will
570 get copied into the static_chain pointer, but it does not matter
571 what that value is, because builtin_setjmp does not use it. */
572 emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
573 else
574 #endif
576 lab = copy_to_reg (lab);
578 emit_move_insn (hard_frame_pointer_rtx, fp);
579 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
581 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
582 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
583 emit_indirect_jump (lab);
588 /* Get a MEM rtx for expression EXP which is the address of an operand
589 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
591 static rtx
592 get_memory_rtx (exp)
593 tree exp;
595 rtx mem = gen_rtx_MEM (BLKmode,
596 memory_address (BLKmode,
597 expand_expr (exp, NULL_RTX,
598 ptr_mode, EXPAND_SUM)));
600 /* Get an expression we can use to find the attributes to assign to MEM.
601 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
602 we can. First remove any nops. */
603 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
604 || TREE_CODE (exp) == NON_LVALUE_EXPR)
605 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
606 exp = TREE_OPERAND (exp, 0);
608 if (TREE_CODE (exp) == ADDR_EXPR)
609 exp = TREE_OPERAND (exp, 0);
610 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
611 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
612 else
613 return mem;
615 set_mem_attributes (mem, exp, 0);
617 /* memcpy, memset and other builtin stringops can alias with anything. */
618 MEM_ALIAS_SET (mem) = 0;
619 return mem;
622 /* Built-in functions to perform an untyped call and return. */
624 /* For each register that may be used for calling a function, this
625 gives a mode used to copy the register's value. VOIDmode indicates
626 the register is not used for calling a function. If the machine
627 has register windows, this gives only the outbound registers.
628 INCOMING_REGNO gives the corresponding inbound register. */
629 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
631 /* For each register that may be used for returning values, this gives
632 a mode used to copy the register's value. VOIDmode indicates the
633 register is not used for returning values. If the machine has
634 register windows, this gives only the outbound registers.
635 INCOMING_REGNO gives the corresponding inbound register. */
636 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
638 /* For each register that may be used for calling a function, this
639 gives the offset of that register into the block returned by
640 __builtin_apply_args. 0 indicates that the register is not
641 used for calling a function. */
642 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
644 /* Return the offset of register REGNO into the block returned by
645 __builtin_apply_args. This is not declared static, since it is
646 needed in objc-act.c. */
648 int
649 apply_args_register_offset (regno)
650 int regno;
652 apply_args_size ();
654 /* Arguments are always put in outgoing registers (in the argument
655 block) if such make sense. */
656 #ifdef OUTGOING_REGNO
657 regno = OUTGOING_REGNO(regno);
658 #endif
659 return apply_args_reg_offset[regno];
662 /* Return the size required for the block returned by __builtin_apply_args,
663 and initialize apply_args_mode. */
665 static int
666 apply_args_size ()
668 static int size = -1;
669 int align, regno;
670 enum machine_mode mode;
672 /* The values computed by this function never change. */
673 if (size < 0)
675 /* The first value is the incoming arg-pointer. */
676 size = GET_MODE_SIZE (Pmode);
678 /* The second value is the structure value address unless this is
679 passed as an "invisible" first argument. */
680 if (struct_value_rtx)
681 size += GET_MODE_SIZE (Pmode);
683 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
684 if (FUNCTION_ARG_REGNO_P (regno))
686 /* Search for the proper mode for copying this register's
687 value. I'm not sure this is right, but it works so far. */
688 enum machine_mode best_mode = VOIDmode;
690 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
691 mode != VOIDmode;
692 mode = GET_MODE_WIDER_MODE (mode))
693 if (HARD_REGNO_MODE_OK (regno, mode)
694 && HARD_REGNO_NREGS (regno, mode) == 1)
695 best_mode = mode;
697 if (best_mode == VOIDmode)
698 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
699 mode != VOIDmode;
700 mode = GET_MODE_WIDER_MODE (mode))
701 if (HARD_REGNO_MODE_OK (regno, mode)
702 && (mov_optab->handlers[(int) mode].insn_code
703 != CODE_FOR_nothing))
704 best_mode = mode;
706 mode = best_mode;
707 if (mode == VOIDmode)
708 abort ();
710 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
711 if (size % align != 0)
712 size = CEIL (size, align) * align;
713 apply_args_reg_offset[regno] = size;
714 size += GET_MODE_SIZE (mode);
715 apply_args_mode[regno] = mode;
717 else
719 apply_args_mode[regno] = VOIDmode;
720 apply_args_reg_offset[regno] = 0;
723 return size;
726 /* Return the size required for the block returned by __builtin_apply,
727 and initialize apply_result_mode. */
729 static int
730 apply_result_size ()
732 static int size = -1;
733 int align, regno;
734 enum machine_mode mode;
736 /* The values computed by this function never change. */
737 if (size < 0)
739 size = 0;
741 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
742 if (FUNCTION_VALUE_REGNO_P (regno))
744 /* Search for the proper mode for copying this register's
745 value. I'm not sure this is right, but it works so far. */
746 enum machine_mode best_mode = VOIDmode;
748 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
749 mode != TImode;
750 mode = GET_MODE_WIDER_MODE (mode))
751 if (HARD_REGNO_MODE_OK (regno, mode))
752 best_mode = mode;
754 if (best_mode == VOIDmode)
755 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
756 mode != VOIDmode;
757 mode = GET_MODE_WIDER_MODE (mode))
758 if (HARD_REGNO_MODE_OK (regno, mode)
759 && (mov_optab->handlers[(int) mode].insn_code
760 != CODE_FOR_nothing))
761 best_mode = mode;
763 mode = best_mode;
764 if (mode == VOIDmode)
765 abort ();
767 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
768 if (size % align != 0)
769 size = CEIL (size, align) * align;
770 size += GET_MODE_SIZE (mode);
771 apply_result_mode[regno] = mode;
773 else
774 apply_result_mode[regno] = VOIDmode;
776 /* Allow targets that use untyped_call and untyped_return to override
777 the size so that machine-specific information can be stored here. */
778 #ifdef APPLY_RESULT_SIZE
779 size = APPLY_RESULT_SIZE;
780 #endif
782 return size;
785 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
786 /* Create a vector describing the result block RESULT. If SAVEP is true,
787 the result block is used to save the values; otherwise it is used to
788 restore the values. */
790 static rtx
791 result_vector (savep, result)
792 int savep;
793 rtx result;
795 int regno, size, align, nelts;
796 enum machine_mode mode;
797 rtx reg, mem;
798 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
800 size = nelts = 0;
801 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
802 if ((mode = apply_result_mode[regno]) != VOIDmode)
804 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
805 if (size % align != 0)
806 size = CEIL (size, align) * align;
807 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
808 mem = change_address (result, mode,
809 plus_constant (XEXP (result, 0), size));
810 savevec[nelts++] = (savep
811 ? gen_rtx_SET (VOIDmode, mem, reg)
812 : gen_rtx_SET (VOIDmode, reg, mem));
813 size += GET_MODE_SIZE (mode);
815 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
817 #endif /* HAVE_untyped_call or HAVE_untyped_return */
819 /* Save the state required to perform an untyped call with the same
820 arguments as were passed to the current function. */
822 static rtx
823 expand_builtin_apply_args_1 ()
825 rtx registers;
826 int size, align, regno;
827 enum machine_mode mode;
829 /* Create a block where the arg-pointer, structure value address,
830 and argument registers can be saved. */
831 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
833 /* Walk past the arg-pointer and structure value address. */
834 size = GET_MODE_SIZE (Pmode);
835 if (struct_value_rtx)
836 size += GET_MODE_SIZE (Pmode);
838 /* Save each register used in calling a function to the block. */
839 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
840 if ((mode = apply_args_mode[regno]) != VOIDmode)
842 rtx tem;
844 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
845 if (size % align != 0)
846 size = CEIL (size, align) * align;
848 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
850 emit_move_insn (change_address (registers, mode,
851 plus_constant (XEXP (registers, 0),
852 size)),
853 tem);
854 size += GET_MODE_SIZE (mode);
857 /* Save the arg pointer to the block. */
858 emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
859 copy_to_reg (virtual_incoming_args_rtx));
860 size = GET_MODE_SIZE (Pmode);
862 /* Save the structure value address unless this is passed as an
863 "invisible" first argument. */
864 if (struct_value_incoming_rtx)
866 emit_move_insn (change_address (registers, Pmode,
867 plus_constant (XEXP (registers, 0),
868 size)),
869 copy_to_reg (struct_value_incoming_rtx));
870 size += GET_MODE_SIZE (Pmode);
873 /* Return the address of the block. */
874 return copy_addr_to_reg (XEXP (registers, 0));
877 /* __builtin_apply_args returns block of memory allocated on
878 the stack into which is stored the arg pointer, structure
879 value address, static chain, and all the registers that might
880 possibly be used in performing a function call. The code is
881 moved to the start of the function so the incoming values are
882 saved. */
883 static rtx
884 expand_builtin_apply_args ()
886 /* Don't do __builtin_apply_args more than once in a function.
887 Save the result of the first call and reuse it. */
888 if (apply_args_value != 0)
889 return apply_args_value;
891 /* When this function is called, it means that registers must be
892 saved on entry to this function. So we migrate the
893 call to the first insn of this function. */
894 rtx temp;
895 rtx seq;
897 start_sequence ();
898 temp = expand_builtin_apply_args_1 ();
899 seq = get_insns ();
900 end_sequence ();
902 apply_args_value = temp;
904 /* Put the sequence after the NOTE that starts the function.
905 If this is inside a SEQUENCE, make the outer-level insn
906 chain current, so the code is placed at the start of the
907 function. */
908 push_topmost_sequence ();
909 emit_insns_before (seq, NEXT_INSN (get_insns ()));
910 pop_topmost_sequence ();
911 return temp;
915 /* Perform an untyped call and save the state required to perform an
916 untyped return of whatever value was returned by the given function. */
918 static rtx
919 expand_builtin_apply (function, arguments, argsize)
920 rtx function, arguments, argsize;
922 int size, align, regno;
923 enum machine_mode mode;
924 rtx incoming_args, result, reg, dest, call_insn;
925 rtx old_stack_level = 0;
926 rtx call_fusage = 0;
928 /* Create a block where the return registers can be saved. */
929 result = assign_stack_local (BLKmode, apply_result_size (), -1);
931 /* Fetch the arg pointer from the ARGUMENTS block. */
932 incoming_args = gen_reg_rtx (Pmode);
933 emit_move_insn (incoming_args,
934 gen_rtx_MEM (Pmode, arguments));
935 #ifndef STACK_GROWS_DOWNWARD
936 incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
937 incoming_args, 0, OPTAB_LIB_WIDEN);
938 #endif
940 /* Perform postincrements before actually calling the function. */
941 emit_queue ();
943 /* Push a new argument block and copy the arguments. Do not allow
944 the (potential) memcpy call below to interfere with our stack
945 manipulations. */
946 do_pending_stack_adjust ();
947 NO_DEFER_POP;
949 /* Save the stack with nonlocal if available */
950 #ifdef HAVE_save_stack_nonlocal
951 if (HAVE_save_stack_nonlocal)
952 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
953 else
954 #endif
955 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
957 /* Push a block of memory onto the stack to store the memory arguments.
958 Save the address in a register, and copy the memory arguments. ??? I
959 haven't figured out how the calling convention macros effect this,
960 but it's likely that the source and/or destination addresses in
961 the block copy will need updating in machine specific ways. */
962 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
963 emit_block_move (gen_rtx_MEM (BLKmode, dest),
964 gen_rtx_MEM (BLKmode, incoming_args),
965 argsize, PARM_BOUNDARY);
967 /* Refer to the argument block. */
968 apply_args_size ();
969 arguments = gen_rtx_MEM (BLKmode, arguments);
971 /* Walk past the arg-pointer and structure value address. */
972 size = GET_MODE_SIZE (Pmode);
973 if (struct_value_rtx)
974 size += GET_MODE_SIZE (Pmode);
976 /* Restore each of the registers previously saved. Make USE insns
977 for each of these registers for use in making the call. */
978 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
979 if ((mode = apply_args_mode[regno]) != VOIDmode)
981 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
982 if (size % align != 0)
983 size = CEIL (size, align) * align;
984 reg = gen_rtx_REG (mode, regno);
985 emit_move_insn (reg,
986 change_address (arguments, mode,
987 plus_constant (XEXP (arguments, 0),
988 size)));
990 use_reg (&call_fusage, reg);
991 size += GET_MODE_SIZE (mode);
994 /* Restore the structure value address unless this is passed as an
995 "invisible" first argument. */
996 size = GET_MODE_SIZE (Pmode);
997 if (struct_value_rtx)
999 rtx value = gen_reg_rtx (Pmode);
1000 emit_move_insn (value,
1001 change_address (arguments, Pmode,
1002 plus_constant (XEXP (arguments, 0),
1003 size)));
1004 emit_move_insn (struct_value_rtx, value);
1005 if (GET_CODE (struct_value_rtx) == REG)
1006 use_reg (&call_fusage, struct_value_rtx);
1007 size += GET_MODE_SIZE (Pmode);
1010 /* All arguments and registers used for the call are set up by now! */
1011 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
1013 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1014 and we don't want to load it into a register as an optimization,
1015 because prepare_call_address already did it if it should be done. */
1016 if (GET_CODE (function) != SYMBOL_REF)
1017 function = memory_address (FUNCTION_MODE, function);
1019 /* Generate the actual call instruction and save the return value. */
1020 #ifdef HAVE_untyped_call
1021 if (HAVE_untyped_call)
1022 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1023 result, result_vector (1, result)));
1024 else
1025 #endif
1026 #ifdef HAVE_call_value
1027 if (HAVE_call_value)
1029 rtx valreg = 0;
1031 /* Locate the unique return register. It is not possible to
1032 express a call that sets more than one return register using
1033 call_value; use untyped_call for that. In fact, untyped_call
1034 only needs to save the return registers in the given block. */
1035 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1036 if ((mode = apply_result_mode[regno]) != VOIDmode)
1038 if (valreg)
1039 abort (); /* HAVE_untyped_call required. */
1040 valreg = gen_rtx_REG (mode, regno);
1043 emit_call_insn (GEN_CALL_VALUE (valreg,
1044 gen_rtx_MEM (FUNCTION_MODE, function),
1045 const0_rtx, NULL_RTX, const0_rtx));
1047 emit_move_insn (change_address (result, GET_MODE (valreg),
1048 XEXP (result, 0)),
1049 valreg);
1051 else
1052 #endif
1053 abort ();
1055 /* Find the CALL insn we just emitted. */
1056 for (call_insn = get_last_insn ();
1057 call_insn && GET_CODE (call_insn) != CALL_INSN;
1058 call_insn = PREV_INSN (call_insn))
1061 if (! call_insn)
1062 abort ();
1064 /* Put the register usage information on the CALL. If there is already
1065 some usage information, put ours at the end. */
1066 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1068 rtx link;
1070 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1071 link = XEXP (link, 1))
1074 XEXP (link, 1) = call_fusage;
1076 else
1077 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1079 /* Restore the stack. */
1080 #ifdef HAVE_save_stack_nonlocal
1081 if (HAVE_save_stack_nonlocal)
1082 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1083 else
1084 #endif
1085 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1087 OK_DEFER_POP;
1089 /* Return the address of the result block. */
1090 return copy_addr_to_reg (XEXP (result, 0));
1093 /* Perform an untyped return. */
1095 static void
1096 expand_builtin_return (result)
1097 rtx result;
1099 int size, align, regno;
1100 enum machine_mode mode;
1101 rtx reg;
1102 rtx call_fusage = 0;
1104 apply_result_size ();
1105 result = gen_rtx_MEM (BLKmode, result);
1107 #ifdef HAVE_untyped_return
1108 if (HAVE_untyped_return)
1110 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1111 emit_barrier ();
1112 return;
1114 #endif
1116 /* Restore the return value and note that each value is used. */
1117 size = 0;
1118 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1119 if ((mode = apply_result_mode[regno]) != VOIDmode)
1121 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1122 if (size % align != 0)
1123 size = CEIL (size, align) * align;
1124 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1125 emit_move_insn (reg,
1126 change_address (result, mode,
1127 plus_constant (XEXP (result, 0),
1128 size)));
1130 push_to_sequence (call_fusage);
1131 emit_insn (gen_rtx_USE (VOIDmode, reg));
1132 call_fusage = get_insns ();
1133 end_sequence ();
1134 size += GET_MODE_SIZE (mode);
1137 /* Put the USE insns before the return. */
1138 emit_insns (call_fusage);
1140 /* Return whatever values was restored by jumping directly to the end
1141 of the function. */
1142 expand_null_return ();
1145 /* Expand a call to __builtin_classify_type with arguments found in
1146 ARGLIST. */
1147 static rtx
1148 expand_builtin_classify_type (arglist)
1149 tree arglist;
1151 if (arglist != 0)
1153 tree type = TREE_TYPE (TREE_VALUE (arglist));
1154 enum tree_code code = TREE_CODE (type);
1155 if (code == VOID_TYPE)
1156 return GEN_INT (void_type_class);
1157 if (code == INTEGER_TYPE)
1158 return GEN_INT (integer_type_class);
1159 if (code == CHAR_TYPE)
1160 return GEN_INT (char_type_class);
1161 if (code == ENUMERAL_TYPE)
1162 return GEN_INT (enumeral_type_class);
1163 if (code == BOOLEAN_TYPE)
1164 return GEN_INT (boolean_type_class);
1165 if (code == POINTER_TYPE)
1166 return GEN_INT (pointer_type_class);
1167 if (code == REFERENCE_TYPE)
1168 return GEN_INT (reference_type_class);
1169 if (code == OFFSET_TYPE)
1170 return GEN_INT (offset_type_class);
1171 if (code == REAL_TYPE)
1172 return GEN_INT (real_type_class);
1173 if (code == COMPLEX_TYPE)
1174 return GEN_INT (complex_type_class);
1175 if (code == FUNCTION_TYPE)
1176 return GEN_INT (function_type_class);
1177 if (code == METHOD_TYPE)
1178 return GEN_INT (method_type_class);
1179 if (code == RECORD_TYPE)
1180 return GEN_INT (record_type_class);
1181 if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
1182 return GEN_INT (union_type_class);
1183 if (code == ARRAY_TYPE)
1185 if (TYPE_STRING_FLAG (type))
1186 return GEN_INT (string_type_class);
1187 else
1188 return GEN_INT (array_type_class);
1190 if (code == SET_TYPE)
1191 return GEN_INT (set_type_class);
1192 if (code == FILE_TYPE)
1193 return GEN_INT (file_type_class);
1194 if (code == LANG_TYPE)
1195 return GEN_INT (lang_type_class);
1197 return GEN_INT (no_type_class);
1200 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1201 static rtx
1202 expand_builtin_constant_p (exp)
1203 tree exp;
1205 tree arglist = TREE_OPERAND (exp, 1);
1206 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1207 rtx tmp;
1209 if (arglist == 0)
1210 return const0_rtx;
1211 arglist = TREE_VALUE (arglist);
1213 /* We have taken care of the easy cases during constant folding. This
1214 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1215 chance to see if it can deduce whether ARGLIST is constant. */
1217 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1218 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1219 return tmp;
1222 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1223 Return 0 if a normal call should be emitted rather than expanding the
1224 function in-line. EXP is the expression that is a call to the builtin
1225 function; if convenient, the result should be placed in TARGET.
1226 SUBTARGET may be used as the target for computing one of EXP's operands. */
1227 static rtx
1228 expand_builtin_mathfn (exp, target, subtarget)
1229 tree exp;
1230 rtx target, subtarget;
1232 optab builtin_optab;
1233 rtx op0, insns;
1234 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1235 tree arglist = TREE_OPERAND (exp, 1);
1237 if (arglist == 0
1238 /* Arg could be wrong type if user redeclared this fcn wrong. */
1239 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
1240 return 0;
1242 /* Stabilize and compute the argument. */
1243 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1244 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1246 exp = copy_node (exp);
1247 TREE_OPERAND (exp, 1) = arglist;
1248 /* Wrap the computation of the argument in a SAVE_EXPR. That
1249 way, if we need to expand the argument again (as in the
1250 flag_errno_math case below where we cannot directly set
1251 errno), we will not perform side-effects more than once.
1252 Note that here we're mutating the original EXP as well as the
1253 copy; that's the right thing to do in case the original EXP
1254 is expanded later. */
1255 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1256 arglist = copy_node (arglist);
1258 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1260 /* Make a suitable register to place result in. */
1261 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1263 emit_queue ();
1264 start_sequence ();
1266 switch (DECL_FUNCTION_CODE (fndecl))
1268 case BUILT_IN_SIN:
1269 builtin_optab = sin_optab; break;
1270 case BUILT_IN_COS:
1271 builtin_optab = cos_optab; break;
1272 case BUILT_IN_FSQRT:
1273 builtin_optab = sqrt_optab; break;
1274 default:
1275 abort ();
1278 /* Compute into TARGET.
1279 Set TARGET to wherever the result comes back. */
1280 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1281 builtin_optab, op0, target, 0);
1283 /* If we were unable to expand via the builtin, stop the
1284 sequence (without outputting the insns) and return 0, causing
1285 a call to the library function. */
1286 if (target == 0)
1288 end_sequence ();
1289 return 0;
1292 /* Check the results by default. But if flag_fast_math is turned on,
1293 then assume sqrt will always be called with valid arguments. */
1295 if (flag_errno_math && ! flag_fast_math)
1297 rtx lab1;
1299 /* Don't define the builtin FP instructions
1300 if your machine is not IEEE. */
1301 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1302 abort ();
1304 lab1 = gen_label_rtx ();
1306 /* Test the result; if it is NaN, set errno=EDOM because
1307 the argument was not in the domain. */
1308 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1309 0, 0, lab1);
1311 #ifdef TARGET_EDOM
1313 #ifdef GEN_ERRNO_RTX
1314 rtx errno_rtx = GEN_ERRNO_RTX;
1315 #else
1316 rtx errno_rtx
1317 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1318 #endif
1320 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1322 #else
1323 /* We can't set errno=EDOM directly; let the library call do it.
1324 Pop the arguments right away in case the call gets deleted. */
1325 NO_DEFER_POP;
1326 expand_call (exp, target, 0);
1327 OK_DEFER_POP;
1328 #endif
1330 emit_label (lab1);
1333 /* Output the entire sequence. */
1334 insns = get_insns ();
1335 end_sequence ();
1336 emit_insns (insns);
1338 return target;
1341 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1342 if we failed the caller should emit a normal call, otherwise
1343 try to get the result in TARGET, if convenient. */
1345 static rtx
1346 expand_builtin_strlen (exp, target)
1347 tree exp;
1348 rtx target;
1350 tree arglist = TREE_OPERAND (exp, 1);
1351 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1353 if (arglist == 0
1354 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1355 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
1356 return 0;
1357 else
1359 rtx pat;
1360 tree src = TREE_VALUE (arglist);
1362 int align
1363 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1365 rtx result, src_reg, char_rtx, before_strlen;
1366 enum machine_mode insn_mode = value_mode, char_mode;
1367 enum insn_code icode = CODE_FOR_nothing;
1369 /* If SRC is not a pointer type, don't do this operation inline. */
1370 if (align == 0)
1371 return 0;
1373 /* Bail out if we can't compute strlen in the right mode. */
1374 while (insn_mode != VOIDmode)
1376 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1377 if (icode != CODE_FOR_nothing)
1378 break;
1380 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1382 if (insn_mode == VOIDmode)
1383 return 0;
1385 /* Make a place to write the result of the instruction. */
1386 result = target;
1387 if (! (result != 0
1388 && GET_CODE (result) == REG
1389 && GET_MODE (result) == insn_mode
1390 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1391 result = gen_reg_rtx (insn_mode);
1393 /* Make a place to hold the source address. We will not expand
1394 the actual source until we are sure that the expansion will
1395 not fail -- there are trees that cannot be expanded twice. */
1396 src_reg = gen_reg_rtx (Pmode);
1398 /* Mark the beginning of the strlen sequence so we can emit the
1399 source operand later. */
1400 before_strlen = get_last_insn();
1402 /* Check the string is readable and has an end. */
1403 if (current_function_check_memory_usage)
1404 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1405 VOIDmode, 2, src_reg, Pmode,
1406 GEN_INT (MEMORY_USE_RO),
1407 TYPE_MODE (integer_type_node));
1409 char_rtx = const0_rtx;
1410 char_mode = insn_data[(int) icode].operand[2].mode;
1411 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1412 char_mode))
1413 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1415 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1416 char_rtx, GEN_INT (align));
1417 if (! pat)
1418 return 0;
1419 emit_insn (pat);
1421 /* Now that we are assured of success, expand the source. */
1422 start_sequence ();
1423 pat = memory_address (BLKmode,
1424 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1425 if (pat != src_reg)
1426 emit_move_insn (src_reg, pat);
1427 pat = gen_sequence ();
1428 end_sequence ();
1430 if (before_strlen)
1431 emit_insn_after (pat, before_strlen);
1432 else
1433 emit_insn_before (pat, get_insns ());
1435 /* Return the value in the proper mode for this function. */
1436 if (GET_MODE (result) == value_mode)
1437 target = result;
1438 else if (target != 0)
1439 convert_move (target, result, 0);
1440 else
1441 target = convert_to_mode (value_mode, result, 0);
1443 return target;
1447 /* Expand a call to the strstr builtin. Return 0 if we failed the
1448 caller should emit a normal call, otherwise try to get the result
1449 in TARGET, if convenient (and in mode MODE if that's convenient). */
1451 static rtx
1452 expand_builtin_strstr (arglist, target, mode)
1453 tree arglist;
1454 rtx target;
1455 enum machine_mode mode;
1457 if (arglist == 0
1458 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1459 || TREE_CHAIN (arglist) == 0
1460 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1461 || current_function_check_memory_usage)
1462 return 0;
1463 else
1465 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1466 tree call_expr, fn;
1467 const char *p1, *p2;
1469 p2 = c_getstr (s2);
1470 if (p2 == NULL)
1471 return 0;
1473 p1 = c_getstr (s1);
1474 if (p1 != NULL)
1476 const char *r = strstr (p1, p2);
1478 if (r == NULL)
1479 return const0_rtx;
1481 /* Return an offset into the constant string argument. */
1482 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1483 s1, ssize_int (r - p1))),
1484 target, mode, EXPAND_NORMAL);
1487 if (p2[0] == '\0')
1488 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1490 if (p2[1] != '\0')
1491 return 0;
1493 fn = built_in_decls[BUILT_IN_STRCHR];
1494 if (!fn)
1495 return 0;
1497 /* New argument list transforming strstr(s1, s2) to
1498 strchr(s1, s2[0]). */
1499 arglist =
1500 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1501 arglist = tree_cons (NULL_TREE, s1, arglist);
1502 call_expr = build1 (ADDR_EXPR,
1503 build_pointer_type (TREE_TYPE (fn)), fn);
1504 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1505 call_expr, arglist, NULL_TREE);
1506 TREE_SIDE_EFFECTS (call_expr) = 1;
1507 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1511 /* Expand a call to the strchr builtin. Return 0 if we failed the
1512 caller should emit a normal call, otherwise try to get the result
1513 in TARGET, if convenient (and in mode MODE if that's convenient). */
1515 static rtx
1516 expand_builtin_strchr (arglist, target, mode)
1517 tree arglist;
1518 rtx target;
1519 enum machine_mode mode;
1521 if (arglist == 0
1522 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1523 || TREE_CHAIN (arglist) == 0
1524 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != INTEGER_TYPE
1525 || current_function_check_memory_usage)
1526 return 0;
1527 else
1529 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1530 const char *p1;
1532 if (TREE_CODE (s2) != INTEGER_CST)
1533 return 0;
1535 p1 = c_getstr (s1);
1536 if (p1 != NULL)
1538 const char *r = strchr (p1, (char) TREE_INT_CST_LOW (s2));
1540 if (r == NULL)
1541 return const0_rtx;
1543 /* Return an offset into the constant string argument. */
1544 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1545 s1, ssize_int (r - p1))),
1546 target, mode, EXPAND_NORMAL);
1549 /* FIXME: Should use here strchrM optab so that ports can optimize
1550 this. */
1551 return 0;
1555 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1556 caller should emit a normal call, otherwise try to get the result
1557 in TARGET, if convenient (and in mode MODE if that's convenient). */
1559 static rtx
1560 expand_builtin_strrchr (arglist, target, mode)
1561 tree arglist;
1562 rtx target;
1563 enum machine_mode mode;
1565 if (arglist == 0
1566 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1567 || TREE_CHAIN (arglist) == 0
1568 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != INTEGER_TYPE
1569 || current_function_check_memory_usage)
1570 return 0;
1571 else
1573 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1574 tree call_expr, fn;
1575 const char *p1;
1577 if (TREE_CODE (s2) != INTEGER_CST)
1578 return 0;
1580 p1 = c_getstr (s1);
1581 if (p1 != NULL)
1583 const char *r = strrchr (p1, (char) TREE_INT_CST_LOW (s2));
1585 if (r == NULL)
1586 return const0_rtx;
1588 /* Return an offset into the constant string argument. */
1589 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1590 s1, ssize_int (r - p1))),
1591 target, mode, EXPAND_NORMAL);
1594 if (! integer_zerop (s2))
1595 return 0;
1597 fn = built_in_decls[BUILT_IN_STRCHR];
1598 if (!fn)
1599 return 0;
1601 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1602 call_expr = build1 (ADDR_EXPR,
1603 build_pointer_type (TREE_TYPE (fn)), fn);
1604 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1605 call_expr, arglist, NULL_TREE);
1606 TREE_SIDE_EFFECTS (call_expr) = 1;
1607 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1611 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1612 caller should emit a normal call, otherwise try to get the result
1613 in TARGET, if convenient (and in mode MODE if that's convenient). */
1615 static rtx
1616 expand_builtin_strpbrk (arglist, target, mode)
1617 tree arglist;
1618 rtx target;
1619 enum machine_mode mode;
1621 if (arglist == 0
1622 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1623 || TREE_CHAIN (arglist) == 0
1624 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1625 || current_function_check_memory_usage)
1626 return 0;
1627 else
1629 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1630 tree call_expr, fn;
1631 const char *p1, *p2;
1633 p2 = c_getstr (s2);
1634 if (p2 == NULL)
1635 return 0;
1637 p1 = c_getstr (s1);
1638 if (p1 != NULL)
1640 const char *r = strpbrk (p1, p2);
1642 if (r == NULL)
1643 return const0_rtx;
1645 /* Return an offset into the constant string argument. */
1646 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1647 s1, ssize_int (r - p1))),
1648 target, mode, EXPAND_NORMAL);
1651 if (p2[0] == '\0')
1653 /* strpbrk(x, "") == NULL.
1654 Evaluate and ignore the arguments in case they had
1655 side-effects. */
1656 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1657 return const0_rtx;
1660 if (p2[1] != '\0')
1661 return 0; /* Really call strpbrk. */
1663 fn = built_in_decls[BUILT_IN_STRCHR];
1664 if (!fn)
1665 return 0;
1667 /* New argument list transforming strpbrk(s1, s2) to
1668 strchr(s1, s2[0]). */
1669 arglist =
1670 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1671 arglist = tree_cons (NULL_TREE, s1, arglist);
1672 call_expr = build1 (ADDR_EXPR,
1673 build_pointer_type (TREE_TYPE (fn)), fn);
1674 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1675 call_expr, arglist, NULL_TREE);
1676 TREE_SIDE_EFFECTS (call_expr) = 1;
1677 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1681 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1682 static rtx
1683 expand_builtin_memcpy (arglist)
1684 tree arglist;
1686 if (arglist == 0
1687 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1688 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1689 || TREE_CHAIN (arglist) == 0
1690 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1691 != POINTER_TYPE)
1692 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1693 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1694 (TREE_CHAIN (TREE_CHAIN (arglist)))))
1695 != INTEGER_TYPE))
1696 return 0;
1697 else
1699 tree dest = TREE_VALUE (arglist);
1700 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1701 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1703 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1704 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1705 rtx dest_mem, src_mem, dest_addr, len_rtx;
1707 /* If either SRC or DEST is not a pointer type, don't do
1708 this operation in-line. */
1709 if (src_align == 0 || dest_align == 0)
1710 return 0;
1712 dest_mem = get_memory_rtx (dest);
1713 src_mem = get_memory_rtx (src);
1714 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1716 /* Just copy the rights of SRC to the rights of DEST. */
1717 if (current_function_check_memory_usage)
1718 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1719 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1720 XEXP (src_mem, 0), Pmode,
1721 len_rtx, TYPE_MODE (sizetype));
1723 /* Copy word part most expediently. */
1724 dest_addr
1725 = emit_block_move (dest_mem, src_mem, len_rtx,
1726 MIN (src_align, dest_align));
1728 if (dest_addr == 0)
1729 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1731 return dest_addr;
1735 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1736 if we failed the caller should emit a normal call. */
1738 static rtx
1739 expand_builtin_strcpy (exp)
1740 tree exp;
1742 tree arglist = TREE_OPERAND (exp, 1);
1743 rtx result;
1745 if (arglist == 0
1746 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1747 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1748 || TREE_CHAIN (arglist) == 0
1749 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1750 != POINTER_TYPE))
1751 return 0;
1752 else
1754 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1756 if (len == 0)
1757 return 0;
1759 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1760 chainon (arglist, build_tree_list (NULL_TREE, len));
1763 result = expand_builtin_memcpy (arglist);
1765 if (! result)
1766 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1767 return result;
1770 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1771 if we failed the caller should emit a normal call. */
1773 static rtx
1774 expand_builtin_memset (exp)
1775 tree exp;
1777 tree arglist = TREE_OPERAND (exp, 1);
1779 if (arglist == 0
1780 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1781 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1782 || TREE_CHAIN (arglist) == 0
1783 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1784 != INTEGER_TYPE)
1785 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1786 || (INTEGER_TYPE
1787 != (TREE_CODE (TREE_TYPE
1788 (TREE_VALUE
1789 (TREE_CHAIN (TREE_CHAIN (arglist))))))))
1790 return 0;
1791 else
1793 tree dest = TREE_VALUE (arglist);
1794 tree val = TREE_VALUE (TREE_CHAIN (arglist));
1795 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1797 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1798 rtx dest_mem, dest_addr, len_rtx;
1800 /* If DEST is not a pointer type, don't do this
1801 operation in-line. */
1802 if (dest_align == 0)
1803 return 0;
1805 /* If the arguments have side-effects, then we can only evaluate
1806 them at most once. The following code evaluates them twice if
1807 they are not constants because we break out to expand_call
1808 in that case. They can't be constants if they have side-effects
1809 so we can check for that first. Alternatively, we could call
1810 save_expr to make multiple evaluation safe. */
1811 if (TREE_SIDE_EFFECTS (val) || TREE_SIDE_EFFECTS (len))
1812 return 0;
1814 /* If VAL is not 0, don't do this operation in-line. */
1815 if (expand_expr (val, NULL_RTX, VOIDmode, 0) != const0_rtx)
1816 return 0;
1818 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1820 dest_mem = get_memory_rtx (dest);
1822 /* Just check DST is writable and mark it as readable. */
1823 if (current_function_check_memory_usage)
1824 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
1825 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1826 len_rtx, TYPE_MODE (sizetype),
1827 GEN_INT (MEMORY_USE_WO),
1828 TYPE_MODE (integer_type_node));
1831 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
1833 if (dest_addr == 0)
1834 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1836 return dest_addr;
1840 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
1841 if we failed the caller should emit a normal call. */
1842 static rtx
1843 expand_builtin_bzero (exp)
1844 tree exp;
1846 tree arglist = TREE_OPERAND (exp, 1);
1847 tree dest, size, newarglist;
1848 rtx result;
1850 if (arglist == 0
1851 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1852 || TREE_CODE (TREE_TYPE (dest = TREE_VALUE (arglist))) != POINTER_TYPE
1853 || TREE_CHAIN (arglist) == 0
1854 || (TREE_CODE (TREE_TYPE (size = TREE_VALUE (TREE_CHAIN (arglist))))
1855 != INTEGER_TYPE))
1856 return NULL_RTX;
1858 /* New argument list transforming bzero(ptr x, int y) to
1859 memset(ptr x, int 0, size_t y). */
1861 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
1862 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
1863 newarglist = tree_cons (NULL_TREE, dest, newarglist);
1865 TREE_OPERAND (exp, 1) = newarglist;
1866 result = expand_builtin_memset(exp);
1868 /* Always restore the original arguments. */
1869 TREE_OPERAND (exp, 1) = arglist;
1871 return result;
1874 #ifdef HAVE_cmpstrsi
1875 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
1876 ARGLIST is the argument list for this call. Return 0 if we failed and the
1877 caller should emit a normal call, otherwise try to get the result in
1878 TARGET, if convenient. */
1879 static rtx
1880 expand_builtin_memcmp (exp, arglist, target)
1881 tree exp;
1882 tree arglist;
1883 rtx target;
1885 /* If we need to check memory accesses, call the library function. */
1886 if (current_function_check_memory_usage)
1887 return 0;
1889 if (arglist == 0
1890 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1891 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1892 || TREE_CHAIN (arglist) == 0
1893 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1894 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1895 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
1896 return 0;
1899 enum machine_mode mode;
1900 tree arg1 = TREE_VALUE (arglist);
1901 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1902 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1903 rtx arg1_rtx, arg2_rtx, arg3_rtx;
1904 rtx result;
1905 rtx insn;
1907 int arg1_align
1908 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1909 int arg2_align
1910 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1911 enum machine_mode insn_mode
1912 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
1914 /* If we don't have POINTER_TYPE, call the function. */
1915 if (arg1_align == 0 || arg2_align == 0)
1916 return 0;
1918 /* Make a place to write the result of the instruction. */
1919 result = target;
1920 if (! (result != 0
1921 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
1922 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1923 result = gen_reg_rtx (insn_mode);
1925 arg1_rtx = get_memory_rtx (arg1);
1926 arg2_rtx = get_memory_rtx (arg2);
1927 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1928 if (!HAVE_cmpstrsi)
1929 insn = NULL_RTX;
1930 else
1931 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
1932 GEN_INT (MIN (arg1_align, arg2_align)));
1934 if (insn)
1935 emit_insn (insn);
1936 else
1937 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
1938 TYPE_MODE (integer_type_node), 3,
1939 XEXP (arg1_rtx, 0), Pmode,
1940 XEXP (arg2_rtx, 0), Pmode,
1941 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
1942 TREE_UNSIGNED (sizetype)),
1943 TYPE_MODE (sizetype));
1945 /* Return the value in the proper mode for this function. */
1946 mode = TYPE_MODE (TREE_TYPE (exp));
1947 if (GET_MODE (result) == mode)
1948 return result;
1949 else if (target != 0)
1951 convert_move (target, result, 0);
1952 return target;
1954 else
1955 return convert_to_mode (mode, result, 0);
1958 #endif
1960 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
1961 if we failed the caller should emit a normal call, otherwise try to get
1962 the result in TARGET, if convenient. */
1964 static rtx
1965 expand_builtin_strcmp (exp, target, mode)
1966 tree exp;
1967 rtx target;
1968 enum machine_mode mode;
1970 tree arglist = TREE_OPERAND (exp, 1);
1971 tree arg1, arg2;
1972 const char *p1, *p2;
1974 /* If we need to check memory accesses, call the library function. */
1975 if (current_function_check_memory_usage)
1976 return 0;
1978 if (arglist == 0
1979 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1980 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1981 || TREE_CHAIN (arglist) == 0
1982 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1983 != POINTER_TYPE))
1984 return 0;
1986 arg1 = TREE_VALUE (arglist);
1987 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1989 p1 = c_getstr (arg1);
1990 p2 = c_getstr (arg2);
1992 if (p1 && p2)
1994 int i = strcmp (p1, p2);
1996 return expand_expr (i < 0 ? build_int_2 (-1, -1)
1997 : i == 0 ? integer_zero_node
1998 : integer_one_node,
1999 target, mode, EXPAND_NORMAL);
2002 #ifdef HAVE_cmpstrsi
2003 if (! HAVE_cmpstrsi)
2004 return 0;
2007 tree len = c_strlen (arg1);
2008 tree len2 = c_strlen (arg2);
2009 rtx result;
2011 if (len)
2012 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2014 if (len2)
2015 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2017 /* If we don't have a constant length for the first, use the length
2018 of the second, if we know it. We don't require a constant for
2019 this case; some cost analysis could be done if both are available
2020 but neither is constant. For now, assume they're equally cheap.
2022 If both strings have constant lengths, use the smaller. This
2023 could arise if optimization results in strcpy being called with
2024 two fixed strings, or if the code was machine-generated. We should
2025 add some code to the `memcmp' handler below to deal with such
2026 situations, someday. */
2028 if (!len || TREE_CODE (len) != INTEGER_CST)
2030 if (len2)
2031 len = len2;
2032 else if (len == 0)
2033 return 0;
2035 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2036 && tree_int_cst_lt (len2, len))
2037 len = len2;
2039 chainon (arglist, build_tree_list (NULL_TREE, len));
2040 result = expand_builtin_memcmp (exp, arglist, target);
2041 if (! result)
2042 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2044 return result;
2046 #else
2047 return 0;
2048 #endif
2051 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2052 if that's convenient. */
2055 expand_builtin_saveregs ()
2057 rtx val, seq;
2059 /* Don't do __builtin_saveregs more than once in a function.
2060 Save the result of the first call and reuse it. */
2061 if (saveregs_value != 0)
2062 return saveregs_value;
2064 /* When this function is called, it means that registers must be
2065 saved on entry to this function. So we migrate the call to the
2066 first insn of this function. */
2068 start_sequence ();
2070 #ifdef EXPAND_BUILTIN_SAVEREGS
2071 /* Do whatever the machine needs done in this case. */
2072 val = EXPAND_BUILTIN_SAVEREGS ();
2073 #else
2074 /* ??? We used to try and build up a call to the out of line function,
2075 guessing about what registers needed saving etc. This became much
2076 harder with __builtin_va_start, since we don't have a tree for a
2077 call to __builtin_saveregs to fall back on. There was exactly one
2078 port (i860) that used this code, and I'm unconvinced it could actually
2079 handle the general case. So we no longer try to handle anything
2080 weird and make the backend absorb the evil. */
2082 error ("__builtin_saveregs not supported by this target");
2083 val = const0_rtx;
2084 #endif
2086 seq = get_insns ();
2087 end_sequence ();
2089 saveregs_value = val;
2091 /* Put the sequence after the NOTE that starts the function. If this
2092 is inside a SEQUENCE, make the outer-level insn chain current, so
2093 the code is placed at the start of the function. */
2094 push_topmost_sequence ();
2095 emit_insns_after (seq, get_insns ());
2096 pop_topmost_sequence ();
2098 return val;
2101 /* __builtin_args_info (N) returns word N of the arg space info
2102 for the current function. The number and meanings of words
2103 is controlled by the definition of CUMULATIVE_ARGS. */
2105 static rtx
2106 expand_builtin_args_info (exp)
2107 tree exp;
2109 tree arglist = TREE_OPERAND (exp, 1);
2110 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2111 int *word_ptr = (int *) &current_function_args_info;
2112 #if 0
2113 /* These are used by the code below that is if 0'ed away */
2114 int i;
2115 tree type, elts, result;
2116 #endif
2118 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2119 abort ();
2121 if (arglist != 0)
2123 tree arg = TREE_VALUE (arglist);
2124 if (TREE_CODE (arg) != INTEGER_CST)
2125 error ("argument of `__builtin_args_info' must be constant");
2126 else
2128 int wordnum = TREE_INT_CST_LOW (arg);
2130 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
2131 error ("argument of `__builtin_args_info' out of range");
2132 else
2133 return GEN_INT (word_ptr[wordnum]);
2136 else
2137 error ("missing argument in `__builtin_args_info'");
2139 return const0_rtx;
2141 #if 0
2142 for (i = 0; i < nwords; i++)
2143 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2145 type = build_array_type (integer_type_node,
2146 build_index_type (build_int_2 (nwords, 0)));
2147 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2148 TREE_CONSTANT (result) = 1;
2149 TREE_STATIC (result) = 1;
2150 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2151 TREE_CONSTANT (result) = 1;
2152 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2153 #endif
2156 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2157 static rtx
2158 expand_builtin_next_arg (arglist)
2159 tree arglist;
2161 tree fntype = TREE_TYPE (current_function_decl);
2163 if ((TYPE_ARG_TYPES (fntype) == 0
2164 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2165 == void_type_node))
2166 && ! current_function_varargs)
2168 error ("`va_start' used in function with fixed args");
2169 return const0_rtx;
2172 if (arglist)
2174 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2175 tree arg = TREE_VALUE (arglist);
2177 /* Strip off all nops for the sake of the comparison. This
2178 is not quite the same as STRIP_NOPS. It does more.
2179 We must also strip off INDIRECT_EXPR for C++ reference
2180 parameters. */
2181 while (TREE_CODE (arg) == NOP_EXPR
2182 || TREE_CODE (arg) == CONVERT_EXPR
2183 || TREE_CODE (arg) == NON_LVALUE_EXPR
2184 || TREE_CODE (arg) == INDIRECT_REF)
2185 arg = TREE_OPERAND (arg, 0);
2186 if (arg != last_parm)
2187 warning ("second parameter of `va_start' not last named argument");
2189 else if (! current_function_varargs)
2190 /* Evidently an out of date version of <stdarg.h>; can't validate
2191 va_start's second argument, but can still work as intended. */
2192 warning ("`__builtin_next_arg' called without an argument");
2194 return expand_binop (Pmode, add_optab,
2195 current_function_internal_arg_pointer,
2196 current_function_arg_offset_rtx,
2197 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2200 /* Make it easier for the backends by protecting the valist argument
2201 from multiple evaluations. */
2203 static tree
2204 stabilize_va_list (valist, needs_lvalue)
2205 tree valist;
2206 int needs_lvalue;
2208 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2210 if (TREE_SIDE_EFFECTS (valist))
2211 valist = save_expr (valist);
2213 /* For this case, the backends will be expecting a pointer to
2214 TREE_TYPE (va_list_type_node), but it's possible we've
2215 actually been given an array (an actual va_list_type_node).
2216 So fix it. */
2217 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2219 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2220 tree p2 = build_pointer_type (va_list_type_node);
2222 valist = build1 (ADDR_EXPR, p2, valist);
2223 valist = fold (build1 (NOP_EXPR, p1, valist));
2226 else
2228 tree pt;
2230 if (! needs_lvalue)
2232 if (! TREE_SIDE_EFFECTS (valist))
2233 return valist;
2235 pt = build_pointer_type (va_list_type_node);
2236 valist = fold (build1 (ADDR_EXPR, pt, valist));
2237 TREE_SIDE_EFFECTS (valist) = 1;
2240 if (TREE_SIDE_EFFECTS (valist))
2241 valist = save_expr (valist);
2242 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2243 valist));
2246 return valist;
2249 /* The "standard" implementation of va_start: just assign `nextarg' to
2250 the variable. */
2251 void
2252 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2253 int stdarg_p ATTRIBUTE_UNUSED;
2254 tree valist;
2255 rtx nextarg;
2257 tree t;
2259 if (!stdarg_p)
2260 nextarg = plus_constant (nextarg, -UNITS_PER_WORD);
2262 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2263 make_tree (ptr_type_node, nextarg));
2264 TREE_SIDE_EFFECTS (t) = 1;
2266 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2269 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2270 __builtin_varargs_va_start, depending on STDARG_P. */
2271 static rtx
2272 expand_builtin_va_start (stdarg_p, arglist)
2273 int stdarg_p;
2274 tree arglist;
2276 rtx nextarg;
2277 tree chain = arglist, valist;
2279 if (stdarg_p)
2280 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2281 else
2282 nextarg = expand_builtin_next_arg (NULL_TREE);
2284 if (TREE_CHAIN (chain))
2285 error ("too many arguments to function `va_start'");
2287 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2289 #ifdef EXPAND_BUILTIN_VA_START
2290 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2291 #else
2292 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2293 #endif
2295 return const0_rtx;
2298 /* The "standard" implementation of va_arg: read the value from the
2299 current (padded) address and increment by the (padded) size. */
2302 std_expand_builtin_va_arg (valist, type)
2303 tree valist, type;
2305 tree addr_tree, t;
2306 HOST_WIDE_INT align;
2307 HOST_WIDE_INT rounded_size;
2308 rtx addr;
2310 /* Compute the rounded size of the type. */
2311 align = PARM_BOUNDARY / BITS_PER_UNIT;
2312 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2314 /* Get AP. */
2315 addr_tree = valist;
2316 if (PAD_VARARGS_DOWN)
2318 /* Small args are padded downward. */
2320 HOST_WIDE_INT adj;
2321 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
2322 if (rounded_size > align)
2323 adj = rounded_size;
2325 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2326 build_int_2 (rounded_size - adj, 0));
2329 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2330 addr = copy_to_reg (addr);
2332 /* Compute new value for AP. */
2333 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2334 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2335 build_int_2 (rounded_size, 0)));
2336 TREE_SIDE_EFFECTS (t) = 1;
2337 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2339 return addr;
2342 /* Expand __builtin_va_arg, which is not really a builtin function, but
2343 a very special sort of operator. */
2346 expand_builtin_va_arg (valist, type)
2347 tree valist, type;
2349 rtx addr, result;
2350 tree promoted_type, want_va_type, have_va_type;
2352 /* Verify that valist is of the proper type. */
2354 want_va_type = va_list_type_node;
2355 have_va_type = TREE_TYPE (valist);
2356 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2358 /* If va_list is an array type, the argument may have decayed
2359 to a pointer type, e.g. by being passed to another function.
2360 In that case, unwrap both types so that we can compare the
2361 underlying records. */
2362 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2363 || TREE_CODE (have_va_type) == POINTER_TYPE)
2365 want_va_type = TREE_TYPE (want_va_type);
2366 have_va_type = TREE_TYPE (have_va_type);
2369 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2371 error ("first argument to `va_arg' not of type `va_list'");
2372 addr = const0_rtx;
2375 /* Generate a diagnostic for requesting data of a type that cannot
2376 be passed through `...' due to type promotion at the call site. */
2377 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2379 const char *name = "<anonymous type>", *pname = 0;
2380 static int gave_help;
2382 if (TYPE_NAME (type))
2384 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2385 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2386 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2387 && DECL_NAME (TYPE_NAME (type)))
2388 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2390 if (TYPE_NAME (promoted_type))
2392 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2393 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2394 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2395 && DECL_NAME (TYPE_NAME (promoted_type)))
2396 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2399 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2400 if (! gave_help)
2402 gave_help = 1;
2403 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2406 addr = const0_rtx;
2408 else
2410 /* Make it easier for the backends by protecting the valist argument
2411 from multiple evaluations. */
2412 valist = stabilize_va_list (valist, 0);
2414 #ifdef EXPAND_BUILTIN_VA_ARG
2415 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2416 #else
2417 addr = std_expand_builtin_va_arg (valist, type);
2418 #endif
2421 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2422 MEM_ALIAS_SET (result) = get_varargs_alias_set ();
2424 return result;
2427 /* Expand ARGLIST, from a call to __builtin_va_end. */
2429 static rtx
2430 expand_builtin_va_end (arglist)
2431 tree arglist;
2433 tree valist = TREE_VALUE (arglist);
2435 #ifdef EXPAND_BUILTIN_VA_END
2436 valist = stabilize_va_list (valist, 0);
2437 EXPAND_BUILTIN_VA_END(arglist);
2438 #else
2439 /* Evaluate for side effects, if needed. I hate macros that don't
2440 do that. */
2441 if (TREE_SIDE_EFFECTS (valist))
2442 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2443 #endif
2445 return const0_rtx;
2448 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2449 builtin rather than just as an assignment in stdarg.h because of the
2450 nastiness of array-type va_list types. */
2452 static rtx
2453 expand_builtin_va_copy (arglist)
2454 tree arglist;
2456 tree dst, src, t;
2458 dst = TREE_VALUE (arglist);
2459 src = TREE_VALUE (TREE_CHAIN (arglist));
2461 dst = stabilize_va_list (dst, 1);
2462 src = stabilize_va_list (src, 0);
2464 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2466 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
2467 TREE_SIDE_EFFECTS (t) = 1;
2468 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2470 else
2472 rtx dstb, srcb, size;
2474 /* Evaluate to pointers. */
2475 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
2476 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
2477 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
2478 VOIDmode, EXPAND_NORMAL);
2480 /* "Dereference" to BLKmode memories. */
2481 dstb = gen_rtx_MEM (BLKmode, dstb);
2482 MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
2483 srcb = gen_rtx_MEM (BLKmode, srcb);
2484 MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
2486 /* Copy. */
2487 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
2490 return const0_rtx;
2493 /* Expand a call to one of the builtin functions __builtin_frame_address or
2494 __builtin_return_address. */
2495 static rtx
2496 expand_builtin_frame_address (exp)
2497 tree exp;
2499 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2500 tree arglist = TREE_OPERAND (exp, 1);
2502 /* The argument must be a nonnegative integer constant.
2503 It counts the number of frames to scan up the stack.
2504 The value is the return address saved in that frame. */
2505 if (arglist == 0)
2506 /* Warning about missing arg was already issued. */
2507 return const0_rtx;
2508 else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST
2509 || tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
2511 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2512 error ("invalid arg to `__builtin_frame_address'");
2513 else
2514 error ("invalid arg to `__builtin_return_address'");
2515 return const0_rtx;
2517 else
2519 rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
2520 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
2521 hard_frame_pointer_rtx);
2523 /* Some ports cannot access arbitrary stack frames. */
2524 if (tem == NULL)
2526 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2527 warning ("unsupported arg to `__builtin_frame_address'");
2528 else
2529 warning ("unsupported arg to `__builtin_return_address'");
2530 return const0_rtx;
2533 /* For __builtin_frame_address, return what we've got. */
2534 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2535 return tem;
2537 if (GET_CODE (tem) != REG
2538 && ! CONSTANT_P (tem))
2539 tem = copy_to_mode_reg (Pmode, tem);
2540 return tem;
2544 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
2545 we failed and the caller should emit a normal call, otherwise try to get
2546 the result in TARGET, if convenient. */
2547 static rtx
2548 expand_builtin_alloca (arglist, target)
2549 tree arglist;
2550 rtx target;
2552 rtx op0;
2554 if (arglist == 0
2555 /* Arg could be non-integer if user redeclared this fcn wrong. */
2556 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2557 return 0;
2559 /* Compute the argument. */
2560 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
2562 /* Allocate the desired space. */
2563 return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
2566 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
2567 Return 0 if a normal call should be emitted rather than expanding the
2568 function in-line. If convenient, the result should be placed in TARGET.
2569 SUBTARGET may be used as the target for computing one of EXP's operands. */
2570 static rtx
2571 expand_builtin_ffs (arglist, target, subtarget)
2572 tree arglist;
2573 rtx target, subtarget;
2575 rtx op0;
2576 if (arglist == 0
2577 /* Arg could be non-integer if user redeclared this fcn wrong. */
2578 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2579 return 0;
2581 /* Compute the argument. */
2582 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
2583 /* Compute ffs, into TARGET if possible.
2584 Set TARGET to wherever the result comes back. */
2585 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
2586 ffs_optab, op0, target, 1);
2587 if (target == 0)
2588 abort ();
2589 return target;
2592 /* If the string passed to fputs is a constant and is one character
2593 long, we attempt to transform this call into __builtin_fputc(). */
2594 static rtx
2595 expand_builtin_fputs (arglist, ignore)
2596 tree arglist;
2597 int ignore;
2599 tree call_expr, len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
2600 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
2602 /* If the return value is used, or the replacement _DECL isn't
2603 initialized, don't do the transformation. */
2604 if (!ignore || !fn_fputc || !fn_fwrite)
2605 return 0;
2607 /* Verify the arguments in the original call. */
2608 if (arglist == 0
2609 || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2610 || TREE_CHAIN (arglist) == 0
2611 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
2612 != POINTER_TYPE)
2613 || current_function_check_memory_usage)
2614 return 0;
2616 /* Get the length of the string passed to fputs. If the length
2617 can't be determined, punt. */
2618 if (!(len = c_strlen (TREE_VALUE (arglist))))
2619 return 0;
2621 switch (compare_tree_int (len, 1))
2623 case -1: /* length is 0, delete the call entirely . */
2625 /* Evaluate and ignore the argument in case it has
2626 side-effects. */
2627 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2628 VOIDmode, EXPAND_NORMAL);
2629 return const0_rtx;
2631 case 0: /* length is 1, call fputc. */
2633 const char *p = c_getstr (TREE_VALUE (arglist));
2635 if (p != NULL)
2637 /* New argument list transforming fputs(string, stream) to
2638 fputc(string[0], stream). */
2639 arglist =
2640 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
2641 arglist =
2642 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
2643 fn = fn_fputc;
2644 break;
2647 /* FALLTHROUGH */
2648 case 1: /* length is greater than 1, call fwrite. */
2650 tree string_arg = TREE_VALUE (arglist);
2652 /* New argument list transforming fputs(string, stream) to
2653 fwrite(string, 1, len, stream). */
2654 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
2655 arglist = tree_cons (NULL_TREE, len, arglist);
2656 arglist = tree_cons (NULL_TREE, integer_one_node, arglist);
2657 arglist = tree_cons (NULL_TREE, string_arg, arglist);
2658 fn = fn_fwrite;
2659 break;
2661 default:
2662 abort();
2665 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2666 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
2667 call_expr, arglist, NULL_TREE);
2668 TREE_SIDE_EFFECTS (call_expr) = 1;
2669 return expand_expr (call_expr, (ignore ? const0_rtx : NULL_RTX),
2670 VOIDmode, EXPAND_NORMAL);
2673 /* Expand a call to __builtin_expect. We return our argument and
2674 emit a NOTE_INSN_EXPECTED_VALUE note. */
2676 static rtx
2677 expand_builtin_expect (arglist, target)
2678 tree arglist;
2679 rtx target;
2681 tree exp, c;
2682 rtx note, rtx_c;
2684 if (arglist == NULL_TREE
2685 || TREE_CHAIN (arglist) == NULL_TREE)
2686 return const0_rtx;
2687 exp = TREE_VALUE (arglist);
2688 c = TREE_VALUE (TREE_CHAIN (arglist));
2690 if (TREE_CODE (c) != INTEGER_CST)
2692 error ("second arg to `__builtin_expect' must be a constant");
2693 c = integer_zero_node;
2696 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
2698 /* Don't bother with expected value notes for integral constants. */
2699 if (GET_CODE (target) != CONST_INT)
2701 /* We do need to force this into a register so that we can be
2702 moderately sure to be able to correctly interpret the branch
2703 condition later. */
2704 target = force_reg (GET_MODE (target), target);
2706 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
2708 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2709 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
2712 return target;
2715 /* Expand an expression EXP that calls a built-in function,
2716 with result going to TARGET if that's convenient
2717 (and in mode MODE if that's convenient).
2718 SUBTARGET may be used as the target for computing one of EXP's operands.
2719 IGNORE is nonzero if the value is to be ignored. */
2722 expand_builtin (exp, target, subtarget, mode, ignore)
2723 tree exp;
2724 rtx target;
2725 rtx subtarget;
2726 enum machine_mode mode;
2727 int ignore;
2729 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2730 tree arglist = TREE_OPERAND (exp, 1);
2731 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
2733 #ifdef MD_EXPAND_BUILTIN
2734 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
2735 return MD_EXPAND_BUILTIN (exp, target, subtarget, mode, ignore);
2736 #endif
2738 /* When not optimizing, generate calls to library functions for a certain
2739 set of builtins. */
2740 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
2741 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
2742 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_MEMSET
2743 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
2744 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
2745 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
2746 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
2747 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
2748 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
2749 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
2750 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
2751 return expand_call (exp, target, ignore);
2753 switch (fcode)
2755 case BUILT_IN_ABS:
2756 case BUILT_IN_LABS:
2757 case BUILT_IN_LLABS:
2758 case BUILT_IN_FABS:
2759 /* build_function_call changes these into ABS_EXPR. */
2760 abort ();
2762 case BUILT_IN_SIN:
2763 case BUILT_IN_COS:
2764 /* Treat these like sqrt, but only if the user asks for them. */
2765 if (! flag_fast_math)
2766 break;
2767 case BUILT_IN_FSQRT:
2768 target = expand_builtin_mathfn (exp, target, subtarget);
2769 if (target)
2770 return target;
2771 break;
2773 case BUILT_IN_FMOD:
2774 break;
2776 case BUILT_IN_APPLY_ARGS:
2777 return expand_builtin_apply_args ();
2779 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
2780 FUNCTION with a copy of the parameters described by
2781 ARGUMENTS, and ARGSIZE. It returns a block of memory
2782 allocated on the stack into which is stored all the registers
2783 that might possibly be used for returning the result of a
2784 function. ARGUMENTS is the value returned by
2785 __builtin_apply_args. ARGSIZE is the number of bytes of
2786 arguments that must be copied. ??? How should this value be
2787 computed? We'll also need a safe worst case value for varargs
2788 functions. */
2789 case BUILT_IN_APPLY:
2790 if (arglist == 0
2791 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2792 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
2793 || TREE_CHAIN (arglist) == 0
2794 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
2795 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
2796 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
2797 return const0_rtx;
2798 else
2800 int i;
2801 tree t;
2802 rtx ops[3];
2804 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
2805 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
2807 return expand_builtin_apply (ops[0], ops[1], ops[2]);
2810 /* __builtin_return (RESULT) causes the function to return the
2811 value described by RESULT. RESULT is address of the block of
2812 memory returned by __builtin_apply. */
2813 case BUILT_IN_RETURN:
2814 if (arglist
2815 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2816 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
2817 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
2818 NULL_RTX, VOIDmode, 0));
2819 return const0_rtx;
2821 case BUILT_IN_SAVEREGS:
2822 return expand_builtin_saveregs ();
2824 case BUILT_IN_ARGS_INFO:
2825 return expand_builtin_args_info (exp);
2827 /* Return the address of the first anonymous stack arg. */
2828 case BUILT_IN_NEXT_ARG:
2829 return expand_builtin_next_arg (arglist);
2831 case BUILT_IN_CLASSIFY_TYPE:
2832 return expand_builtin_classify_type (arglist);
2834 case BUILT_IN_CONSTANT_P:
2835 return expand_builtin_constant_p (exp);
2837 case BUILT_IN_FRAME_ADDRESS:
2838 case BUILT_IN_RETURN_ADDRESS:
2839 return expand_builtin_frame_address (exp);
2841 /* Returns the address of the area where the structure is returned.
2842 0 otherwise. */
2843 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
2844 if (arglist != 0
2845 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
2846 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
2847 return const0_rtx;
2848 else
2849 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
2851 case BUILT_IN_ALLOCA:
2852 target = expand_builtin_alloca (arglist, target);
2853 if (target)
2854 return target;
2855 break;
2857 case BUILT_IN_FFS:
2858 target = expand_builtin_ffs (arglist, target, subtarget);
2859 if (target)
2860 return target;
2861 break;
2863 case BUILT_IN_STRLEN:
2864 target = expand_builtin_strlen (exp, target);
2865 if (target)
2866 return target;
2867 break;
2869 case BUILT_IN_STRCPY:
2870 target = expand_builtin_strcpy (exp);
2871 if (target)
2872 return target;
2873 break;
2875 case BUILT_IN_STRSTR:
2876 target = expand_builtin_strstr (arglist, target, mode);
2877 if (target)
2878 return target;
2879 break;
2881 case BUILT_IN_STRPBRK:
2882 target = expand_builtin_strpbrk (arglist, target, mode);
2883 if (target)
2884 return target;
2885 break;
2887 case BUILT_IN_STRCHR:
2888 target = expand_builtin_strchr (arglist, target, mode);
2889 if (target)
2890 return target;
2891 break;
2893 case BUILT_IN_STRRCHR:
2894 target = expand_builtin_strrchr (arglist, target, mode);
2895 if (target)
2896 return target;
2897 break;
2899 case BUILT_IN_MEMCPY:
2900 target = expand_builtin_memcpy (arglist);
2901 if (target)
2902 return target;
2903 break;
2905 case BUILT_IN_MEMSET:
2906 target = expand_builtin_memset (exp);
2907 if (target)
2908 return target;
2909 break;
2911 case BUILT_IN_BZERO:
2912 target = expand_builtin_bzero (exp);
2913 if (target)
2914 return target;
2915 break;
2917 case BUILT_IN_STRCMP:
2918 target = expand_builtin_strcmp (exp, target, mode);
2919 if (target)
2920 return target;
2921 break;
2923 /* These comparison functions need an instruction that returns an actual
2924 index. An ordinary compare that just sets the condition codes
2925 is not enough. */
2926 #ifdef HAVE_cmpstrsi
2927 case BUILT_IN_BCMP:
2928 case BUILT_IN_MEMCMP:
2929 target = expand_builtin_memcmp (exp, arglist, target);
2930 if (target)
2931 return target;
2932 break;
2933 #else
2934 case BUILT_IN_BCMP:
2935 case BUILT_IN_MEMCMP:
2936 break;
2937 #endif
2939 case BUILT_IN_SETJMP:
2940 if (arglist == 0
2941 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2942 break;
2943 else
2945 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2946 VOIDmode, 0);
2947 rtx lab = gen_label_rtx ();
2948 rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
2949 emit_label (lab);
2950 return ret;
2953 /* __builtin_longjmp is passed a pointer to an array of five words.
2954 It's similar to the C library longjmp function but works with
2955 __builtin_setjmp above. */
2956 case BUILT_IN_LONGJMP:
2957 if (arglist == 0 || TREE_CHAIN (arglist) == 0
2958 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2959 break;
2960 else
2962 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2963 VOIDmode, 0);
2964 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
2965 NULL_RTX, VOIDmode, 0);
2967 if (value != const1_rtx)
2969 error ("__builtin_longjmp second argument must be 1");
2970 return const0_rtx;
2973 expand_builtin_longjmp (buf_addr, value);
2974 return const0_rtx;
2977 case BUILT_IN_TRAP:
2978 #ifdef HAVE_trap
2979 if (HAVE_trap)
2980 emit_insn (gen_trap ());
2981 else
2982 #endif
2983 error ("__builtin_trap not supported by this target");
2984 emit_barrier ();
2985 return const0_rtx;
2987 case BUILT_IN_PUTCHAR:
2988 case BUILT_IN_PUTS:
2989 case BUILT_IN_FPUTC:
2990 case BUILT_IN_FWRITE:
2991 break;
2992 case BUILT_IN_FPUTS:
2993 target = expand_builtin_fputs (arglist, ignore);
2994 if (target)
2995 return target;
2996 break;
2998 /* Various hooks for the DWARF 2 __throw routine. */
2999 case BUILT_IN_UNWIND_INIT:
3000 expand_builtin_unwind_init ();
3001 return const0_rtx;
3002 case BUILT_IN_DWARF_CFA:
3003 return virtual_cfa_rtx;
3004 #ifdef DWARF2_UNWIND_INFO
3005 case BUILT_IN_DWARF_FP_REGNUM:
3006 return expand_builtin_dwarf_fp_regnum ();
3007 case BUILT_IN_INIT_DWARF_REG_SIZES:
3008 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3009 return const0_rtx;
3010 #endif
3011 case BUILT_IN_FROB_RETURN_ADDR:
3012 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3013 case BUILT_IN_EXTRACT_RETURN_ADDR:
3014 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3015 case BUILT_IN_EH_RETURN:
3016 expand_builtin_eh_return (TREE_VALUE (arglist),
3017 TREE_VALUE (TREE_CHAIN (arglist)),
3018 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
3019 return const0_rtx;
3020 case BUILT_IN_VARARGS_START:
3021 return expand_builtin_va_start (0, arglist);
3022 case BUILT_IN_STDARG_START:
3023 return expand_builtin_va_start (1, arglist);
3024 case BUILT_IN_VA_END:
3025 return expand_builtin_va_end (arglist);
3026 case BUILT_IN_VA_COPY:
3027 return expand_builtin_va_copy (arglist);
3028 case BUILT_IN_EXPECT:
3029 return expand_builtin_expect (arglist, target);
3031 default: /* just do library call, if unknown builtin */
3032 error ("built-in function `%s' not currently supported",
3033 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3036 /* The switch statement above can drop through to cause the function
3037 to be called normally. */
3038 return expand_call (exp, target, ignore);
3041 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3042 constant. ARGLIST is the argument list of the call. */
3044 static tree
3045 fold_builtin_constant_p (arglist)
3046 tree arglist;
3048 if (arglist == 0)
3049 return 0;
3051 arglist = TREE_VALUE (arglist);
3053 /* We return 1 for a numeric type that's known to be a constant
3054 value at compile-time or for an aggregate type that's a
3055 literal constant. */
3056 STRIP_NOPS (arglist);
3058 /* If we know this is a constant, emit the constant of one. */
3059 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3060 || (TREE_CODE (arglist) == CONSTRUCTOR
3061 && TREE_CONSTANT (arglist))
3062 || (TREE_CODE (arglist) == ADDR_EXPR
3063 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3064 return integer_one_node;
3066 /* If we aren't going to be running CSE or this expression
3067 has side effects, show we don't know it to be a constant.
3068 Likewise if it's a pointer or aggregate type since in those
3069 case we only want literals, since those are only optimized
3070 when generating RTL, not later. */
3071 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3072 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3073 || POINTER_TYPE_P (TREE_TYPE (arglist)))
3074 return integer_zero_node;
3076 return 0;
3079 /* Used by constant folding to eliminate some builtin calls early. EXP is
3080 the CALL_EXPR of a call to a builtin function. */
3082 tree
3083 fold_builtin (exp)
3084 tree exp;
3086 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3087 tree arglist = TREE_OPERAND (exp, 1);
3088 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3090 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3091 return 0;
3093 switch (fcode)
3095 case BUILT_IN_CONSTANT_P:
3096 return fold_builtin_constant_p (arglist);
3098 case BUILT_IN_STRLEN:
3099 if (arglist != 0
3100 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3101 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
3103 tree len = c_strlen (TREE_VALUE (arglist));
3104 if (len != 0)
3105 return len;
3107 break;
3109 default:
3110 break;
3113 return 0;