acconfig.h: _GLIBCPP_USING_THREADS and some workaround types added.
[gcc.git] / gcc / builtins.c
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
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.
11
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.
16
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. */
21
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"
43
44 #define CALLED_AS_BUILT_IN(NODE) \
45 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
46
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
54
55 #ifndef PAD_VARARGS_DOWN
56 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
57 #endif
58
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"};
62
63 #define DEF_BUILTIN(x) STRINGIFY(x),
64 const char *const built_in_names[(int) END_BUILTINS] =
65 {
66 #include "builtins.def"
67 };
68 #undef DEF_BUILTIN
69
70 tree (*lang_type_promotes_to) PARAMS ((tree));
71
72 static int get_pointer_alignment PARAMS ((tree, unsigned));
73 static tree c_strlen PARAMS ((tree));
74 static rtx get_memory_rtx PARAMS ((tree));
75 static int apply_args_size PARAMS ((void));
76 static int apply_result_size PARAMS ((void));
77 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
78 static rtx result_vector PARAMS ((int, rtx));
79 #endif
80 static rtx expand_builtin_apply_args PARAMS ((void));
81 static rtx expand_builtin_apply_args_1 PARAMS ((void));
82 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
83 static void expand_builtin_return PARAMS ((rtx));
84 static rtx expand_builtin_classify_type PARAMS ((tree));
85 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
86 static rtx expand_builtin_constant_p PARAMS ((tree));
87 static rtx expand_builtin_args_info PARAMS ((tree));
88 static rtx expand_builtin_next_arg PARAMS ((tree));
89 static rtx expand_builtin_va_start PARAMS ((int, tree));
90 static rtx expand_builtin_va_end PARAMS ((tree));
91 static rtx expand_builtin_va_copy PARAMS ((tree));
92 #ifdef HAVE_cmpstrsi
93 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
94 static rtx expand_builtin_strcmp PARAMS ((tree, rtx));
95 #endif
96 static rtx expand_builtin_memcpy PARAMS ((tree));
97 static rtx expand_builtin_strcpy PARAMS ((tree));
98 static rtx expand_builtin_memset PARAMS ((tree));
99 static rtx expand_builtin_bzero PARAMS ((tree));
100 static rtx expand_builtin_strlen PARAMS ((tree, rtx,
101 enum machine_mode));
102 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
103 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
104 static rtx expand_builtin_frame_address PARAMS ((tree));
105 static tree stabilize_va_list PARAMS ((tree, int));
106 static rtx expand_builtin_expect PARAMS ((tree, rtx));
107
108 /* Return the alignment in bits of EXP, a pointer valued expression.
109 But don't return more than MAX_ALIGN no matter what.
110 The alignment returned is, by default, the alignment of the thing that
111 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
112
113 Otherwise, look at the expression to see if we can do better, i.e., if the
114 expression is actually pointing at an object whose alignment is tighter. */
115
116 static int
117 get_pointer_alignment (exp, max_align)
118 tree exp;
119 unsigned max_align;
120 {
121 unsigned align, inner;
122
123 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
124 return 0;
125
126 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
127 align = MIN (align, max_align);
128
129 while (1)
130 {
131 switch (TREE_CODE (exp))
132 {
133 case NOP_EXPR:
134 case CONVERT_EXPR:
135 case NON_LVALUE_EXPR:
136 exp = TREE_OPERAND (exp, 0);
137 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
138 return align;
139
140 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
141 align = MIN (inner, max_align);
142 break;
143
144 case PLUS_EXPR:
145 /* If sum of pointer + int, restrict our maximum alignment to that
146 imposed by the integer. If not, we can't do any better than
147 ALIGN. */
148 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
149 return align;
150
151 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1) * BITS_PER_UNIT)
152 & (max_align - 1))
153 != 0)
154 max_align >>= 1;
155
156 exp = TREE_OPERAND (exp, 0);
157 break;
158
159 case ADDR_EXPR:
160 /* See what we are pointing at and look at its alignment. */
161 exp = TREE_OPERAND (exp, 0);
162 if (TREE_CODE (exp) == FUNCTION_DECL)
163 align = FUNCTION_BOUNDARY;
164 else if (DECL_P (exp))
165 align = DECL_ALIGN (exp);
166 #ifdef CONSTANT_ALIGNMENT
167 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
168 align = CONSTANT_ALIGNMENT (exp, align);
169 #endif
170 return MIN (align, max_align);
171
172 default:
173 return align;
174 }
175 }
176 }
177
178 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
179 way, because it could contain a zero byte in the middle.
180 TREE_STRING_LENGTH is the size of the character array, not the string.
181
182 The value returned is of type `ssizetype'.
183
184 Unfortunately, string_constant can't access the values of const char
185 arrays with initializers, so neither can we do so here. */
186
187 static tree
188 c_strlen (src)
189 tree src;
190 {
191 tree offset_node;
192 int offset, max;
193 char *ptr;
194
195 src = string_constant (src, &offset_node);
196 if (src == 0)
197 return 0;
198
199 max = TREE_STRING_LENGTH (src);
200 ptr = TREE_STRING_POINTER (src);
201
202 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
203 {
204 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
205 compute the offset to the following null if we don't know where to
206 start searching for it. */
207 int i;
208
209 for (i = 0; i < max; i++)
210 if (ptr[i] == 0)
211 return 0;
212
213 /* We don't know the starting offset, but we do know that the string
214 has no internal zero bytes. We can assume that the offset falls
215 within the bounds of the string; otherwise, the programmer deserves
216 what he gets. Subtract the offset from the length of the string,
217 and return that. This would perhaps not be valid if we were dealing
218 with named arrays in addition to literal string constants. */
219
220 return size_diffop (size_int (max), offset_node);
221 }
222
223 /* We have a known offset into the string. Start searching there for
224 a null character. */
225 if (offset_node == 0)
226 offset = 0;
227 else
228 {
229 /* Did we get a long long offset? If so, punt. */
230 if (TREE_INT_CST_HIGH (offset_node) != 0)
231 return 0;
232 offset = TREE_INT_CST_LOW (offset_node);
233 }
234
235 /* If the offset is known to be out of bounds, warn, and call strlen at
236 runtime. */
237 if (offset < 0 || offset > max)
238 {
239 warning ("offset outside bounds of constant string");
240 return 0;
241 }
242
243 /* Use strlen to search for the first zero byte. Since any strings
244 constructed with build_string will have nulls appended, we win even
245 if we get handed something like (char[4])"abcd".
246
247 Since OFFSET is our starting index into the string, no further
248 calculation is needed. */
249 return ssize_int (strlen (ptr + offset));
250 }
251
252 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
253 times to get the address of either a higher stack frame, or a return
254 address located within it (depending on FNDECL_CODE). */
255
256 rtx
257 expand_builtin_return_addr (fndecl_code, count, tem)
258 enum built_in_function fndecl_code;
259 int count;
260 rtx tem;
261 {
262 int i;
263
264 /* Some machines need special handling before we can access
265 arbitrary frames. For example, on the sparc, we must first flush
266 all register windows to the stack. */
267 #ifdef SETUP_FRAME_ADDRESSES
268 if (count > 0)
269 SETUP_FRAME_ADDRESSES ();
270 #endif
271
272 /* On the sparc, the return address is not in the frame, it is in a
273 register. There is no way to access it off of the current frame
274 pointer, but it can be accessed off the previous frame pointer by
275 reading the value from the register window save area. */
276 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
277 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
278 count--;
279 #endif
280
281 /* Scan back COUNT frames to the specified frame. */
282 for (i = 0; i < count; i++)
283 {
284 /* Assume the dynamic chain pointer is in the word that the
285 frame address points to, unless otherwise specified. */
286 #ifdef DYNAMIC_CHAIN_ADDRESS
287 tem = DYNAMIC_CHAIN_ADDRESS (tem);
288 #endif
289 tem = memory_address (Pmode, tem);
290 tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
291 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
292 }
293
294 /* For __builtin_frame_address, return what we've got. */
295 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
296 return tem;
297
298 /* For __builtin_return_address, Get the return address from that
299 frame. */
300 #ifdef RETURN_ADDR_RTX
301 tem = RETURN_ADDR_RTX (count, tem);
302 #else
303 tem = memory_address (Pmode,
304 plus_constant (tem, GET_MODE_SIZE (Pmode)));
305 tem = gen_rtx_MEM (Pmode, tem);
306 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
307 #endif
308 return tem;
309 }
310
311 /* Alias set used for setjmp buffer. */
312 static HOST_WIDE_INT setjmp_alias_set = -1;
313
314 /* __builtin_setjmp is passed a pointer to an array of five words (not
315 all will be used on all machines). It operates similarly to the C
316 library function of the same name, but is more efficient. Much of
317 the code below (and for longjmp) is copied from the handling of
318 non-local gotos.
319
320 NOTE: This is intended for use by GNAT and the exception handling
321 scheme in the compiler and will only work in the method used by
322 them. */
323
324 rtx
325 expand_builtin_setjmp (buf_addr, target, first_label, next_label)
326 rtx buf_addr;
327 rtx target;
328 rtx first_label, next_label;
329 {
330 rtx lab1 = gen_label_rtx ();
331 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
332 enum machine_mode value_mode;
333 rtx stack_save;
334 rtx mem;
335
336 value_mode = TYPE_MODE (integer_type_node);
337
338 if (setjmp_alias_set == -1)
339 setjmp_alias_set = new_alias_set ();
340
341 #ifdef POINTERS_EXTEND_UNSIGNED
342 buf_addr = convert_memory_address (Pmode, buf_addr);
343 #endif
344
345 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
346
347 if (target == 0 || GET_CODE (target) != REG
348 || REGNO (target) < FIRST_PSEUDO_REGISTER)
349 target = gen_reg_rtx (value_mode);
350
351 emit_queue ();
352
353 /* We store the frame pointer and the address of lab1 in the buffer
354 and use the rest of it for the stack save area, which is
355 machine-dependent. */
356
357 #ifndef BUILTIN_SETJMP_FRAME_VALUE
358 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
359 #endif
360
361 mem = gen_rtx_MEM (Pmode, buf_addr);
362 MEM_ALIAS_SET (mem) = setjmp_alias_set;
363 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
364
365 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
366 MEM_ALIAS_SET (mem) = setjmp_alias_set;
367
368 emit_move_insn (validize_mem (mem),
369 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
370
371 stack_save = gen_rtx_MEM (sa_mode,
372 plus_constant (buf_addr,
373 2 * GET_MODE_SIZE (Pmode)));
374 MEM_ALIAS_SET (stack_save) = setjmp_alias_set;
375 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
376
377 /* If there is further processing to do, do it. */
378 #ifdef HAVE_builtin_setjmp_setup
379 if (HAVE_builtin_setjmp_setup)
380 emit_insn (gen_builtin_setjmp_setup (buf_addr));
381 #endif
382
383 /* Set TARGET to zero and branch to the first-time-through label. */
384 emit_move_insn (target, const0_rtx);
385 emit_jump_insn (gen_jump (first_label));
386 emit_barrier ();
387 emit_label (lab1);
388
389 /* Tell flow about the strange goings on. Putting `lab1' on
390 `nonlocal_goto_handler_labels' to indicates that function
391 calls may traverse the arc back to this label. */
392
393 current_function_has_nonlocal_label = 1;
394 nonlocal_goto_handler_labels
395 = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
396
397 /* Clobber the FP when we get here, so we have to make sure it's
398 marked as used by this function. */
399 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
400
401 /* Mark the static chain as clobbered here so life information
402 doesn't get messed up for it. */
403 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
404
405 /* Now put in the code to restore the frame pointer, and argument
406 pointer, if needed. The code below is from expand_end_bindings
407 in stmt.c; see detailed documentation there. */
408 #ifdef HAVE_nonlocal_goto
409 if (! HAVE_nonlocal_goto)
410 #endif
411 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
412
413 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
414 if (fixed_regs[ARG_POINTER_REGNUM])
415 {
416 #ifdef ELIMINABLE_REGS
417 size_t i;
418 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
419
420 for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
421 if (elim_regs[i].from == ARG_POINTER_REGNUM
422 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
423 break;
424
425 if (i == sizeof elim_regs / sizeof elim_regs [0])
426 #endif
427 {
428 /* Now restore our arg pointer from the address at which it
429 was saved in our stack frame.
430 If there hasn't be space allocated for it yet, make
431 some now. */
432 if (arg_pointer_save_area == 0)
433 arg_pointer_save_area
434 = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
435 emit_move_insn (virtual_incoming_args_rtx,
436 copy_to_reg (arg_pointer_save_area));
437 }
438 }
439 #endif
440
441 #ifdef HAVE_builtin_setjmp_receiver
442 if (HAVE_builtin_setjmp_receiver)
443 emit_insn (gen_builtin_setjmp_receiver (lab1));
444 else
445 #endif
446 #ifdef HAVE_nonlocal_goto_receiver
447 if (HAVE_nonlocal_goto_receiver)
448 emit_insn (gen_nonlocal_goto_receiver ());
449 else
450 #endif
451 {
452 ; /* Nothing */
453 }
454
455 /* Set TARGET, and branch to the next-time-through label. */
456 emit_move_insn (target, const1_rtx);
457 emit_jump_insn (gen_jump (next_label));
458 emit_barrier ();
459
460 return target;
461 }
462
463 /* __builtin_longjmp is passed a pointer to an array of five words (not
464 all will be used on all machines). It operates similarly to the C
465 library function of the same name, but is more efficient. Much of
466 the code below is copied from the handling of non-local gotos.
467
468 NOTE: This is intended for use by GNAT and the exception handling
469 scheme in the compiler and will only work in the method used by
470 them. */
471
472 void
473 expand_builtin_longjmp (buf_addr, value)
474 rtx buf_addr, value;
475 {
476 rtx fp, lab, stack;
477 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
478
479 if (setjmp_alias_set == -1)
480 setjmp_alias_set = new_alias_set ();
481
482 #ifdef POINTERS_EXTEND_UNSIGNED
483 buf_addr = convert_memory_address (Pmode, buf_addr);
484 #endif
485 buf_addr = force_reg (Pmode, buf_addr);
486
487 /* We used to store value in static_chain_rtx, but that fails if pointers
488 are smaller than integers. We instead require that the user must pass
489 a second argument of 1, because that is what builtin_setjmp will
490 return. This also makes EH slightly more efficient, since we are no
491 longer copying around a value that we don't care about. */
492 if (value != const1_rtx)
493 abort ();
494
495 #ifdef HAVE_builtin_longjmp
496 if (HAVE_builtin_longjmp)
497 emit_insn (gen_builtin_longjmp (buf_addr));
498 else
499 #endif
500 {
501 fp = gen_rtx_MEM (Pmode, buf_addr);
502 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
503 GET_MODE_SIZE (Pmode)));
504
505 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
506 2 * GET_MODE_SIZE (Pmode)));
507 MEM_ALIAS_SET (fp) = MEM_ALIAS_SET (lab) = MEM_ALIAS_SET (stack)
508 = setjmp_alias_set;
509
510 /* Pick up FP, label, and SP from the block and jump. This code is
511 from expand_goto in stmt.c; see there for detailed comments. */
512 #if HAVE_nonlocal_goto
513 if (HAVE_nonlocal_goto)
514 /* We have to pass a value to the nonlocal_goto pattern that will
515 get copied into the static_chain pointer, but it does not matter
516 what that value is, because builtin_setjmp does not use it. */
517 emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
518 else
519 #endif
520 {
521 lab = copy_to_reg (lab);
522
523 emit_move_insn (hard_frame_pointer_rtx, fp);
524 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
525
526 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
527 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
528 emit_indirect_jump (lab);
529 }
530 }
531 }
532
533 /* Get a MEM rtx for expression EXP which is the address of an operand
534 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
535
536 static rtx
537 get_memory_rtx (exp)
538 tree exp;
539 {
540 rtx mem = gen_rtx_MEM (BLKmode,
541 memory_address (BLKmode,
542 expand_expr (exp, NULL_RTX,
543 ptr_mode, EXPAND_SUM)));
544
545 /* Get an expression we can use to find the attributes to assign to MEM.
546 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
547 we can. First remove any nops. */
548 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
549 || TREE_CODE (exp) == NON_LVALUE_EXPR)
550 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
551 exp = TREE_OPERAND (exp, 0);
552
553 if (TREE_CODE (exp) == ADDR_EXPR)
554 exp = TREE_OPERAND (exp, 0);
555 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
556 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
557 else
558 return mem;
559
560 set_mem_attributes (mem, exp, 0);
561
562 /* memcpy, memset and other builtin stringops can alias with anything. */
563 MEM_ALIAS_SET (mem) = 0;
564 return mem;
565 }
566 \f
567 /* Built-in functions to perform an untyped call and return. */
568
569 /* For each register that may be used for calling a function, this
570 gives a mode used to copy the register's value. VOIDmode indicates
571 the register is not used for calling a function. If the machine
572 has register windows, this gives only the outbound registers.
573 INCOMING_REGNO gives the corresponding inbound register. */
574 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
575
576 /* For each register that may be used for returning values, this gives
577 a mode used to copy the register's value. VOIDmode indicates the
578 register is not used for returning values. If the machine has
579 register windows, this gives only the outbound registers.
580 INCOMING_REGNO gives the corresponding inbound register. */
581 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
582
583 /* For each register that may be used for calling a function, this
584 gives the offset of that register into the block returned by
585 __builtin_apply_args. 0 indicates that the register is not
586 used for calling a function. */
587 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
588
589 /* Return the offset of register REGNO into the block returned by
590 __builtin_apply_args. This is not declared static, since it is
591 needed in objc-act.c. */
592
593 int
594 apply_args_register_offset (regno)
595 int regno;
596 {
597 apply_args_size ();
598
599 /* Arguments are always put in outgoing registers (in the argument
600 block) if such make sense. */
601 #ifdef OUTGOING_REGNO
602 regno = OUTGOING_REGNO(regno);
603 #endif
604 return apply_args_reg_offset[regno];
605 }
606
607 /* Return the size required for the block returned by __builtin_apply_args,
608 and initialize apply_args_mode. */
609
610 static int
611 apply_args_size ()
612 {
613 static int size = -1;
614 int align, regno;
615 enum machine_mode mode;
616
617 /* The values computed by this function never change. */
618 if (size < 0)
619 {
620 /* The first value is the incoming arg-pointer. */
621 size = GET_MODE_SIZE (Pmode);
622
623 /* The second value is the structure value address unless this is
624 passed as an "invisible" first argument. */
625 if (struct_value_rtx)
626 size += GET_MODE_SIZE (Pmode);
627
628 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
629 if (FUNCTION_ARG_REGNO_P (regno))
630 {
631 /* Search for the proper mode for copying this register's
632 value. I'm not sure this is right, but it works so far. */
633 enum machine_mode best_mode = VOIDmode;
634
635 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
636 mode != VOIDmode;
637 mode = GET_MODE_WIDER_MODE (mode))
638 if (HARD_REGNO_MODE_OK (regno, mode)
639 && HARD_REGNO_NREGS (regno, mode) == 1)
640 best_mode = mode;
641
642 if (best_mode == VOIDmode)
643 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
644 mode != VOIDmode;
645 mode = GET_MODE_WIDER_MODE (mode))
646 if (HARD_REGNO_MODE_OK (regno, mode)
647 && (mov_optab->handlers[(int) mode].insn_code
648 != CODE_FOR_nothing))
649 best_mode = mode;
650
651 mode = best_mode;
652 if (mode == VOIDmode)
653 abort ();
654
655 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
656 if (size % align != 0)
657 size = CEIL (size, align) * align;
658 apply_args_reg_offset[regno] = size;
659 size += GET_MODE_SIZE (mode);
660 apply_args_mode[regno] = mode;
661 }
662 else
663 {
664 apply_args_mode[regno] = VOIDmode;
665 apply_args_reg_offset[regno] = 0;
666 }
667 }
668 return size;
669 }
670
671 /* Return the size required for the block returned by __builtin_apply,
672 and initialize apply_result_mode. */
673
674 static int
675 apply_result_size ()
676 {
677 static int size = -1;
678 int align, regno;
679 enum machine_mode mode;
680
681 /* The values computed by this function never change. */
682 if (size < 0)
683 {
684 size = 0;
685
686 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
687 if (FUNCTION_VALUE_REGNO_P (regno))
688 {
689 /* Search for the proper mode for copying this register's
690 value. I'm not sure this is right, but it works so far. */
691 enum machine_mode best_mode = VOIDmode;
692
693 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
694 mode != TImode;
695 mode = GET_MODE_WIDER_MODE (mode))
696 if (HARD_REGNO_MODE_OK (regno, mode))
697 best_mode = mode;
698
699 if (best_mode == VOIDmode)
700 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
701 mode != VOIDmode;
702 mode = GET_MODE_WIDER_MODE (mode))
703 if (HARD_REGNO_MODE_OK (regno, mode)
704 && (mov_optab->handlers[(int) mode].insn_code
705 != CODE_FOR_nothing))
706 best_mode = mode;
707
708 mode = best_mode;
709 if (mode == VOIDmode)
710 abort ();
711
712 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
713 if (size % align != 0)
714 size = CEIL (size, align) * align;
715 size += GET_MODE_SIZE (mode);
716 apply_result_mode[regno] = mode;
717 }
718 else
719 apply_result_mode[regno] = VOIDmode;
720
721 /* Allow targets that use untyped_call and untyped_return to override
722 the size so that machine-specific information can be stored here. */
723 #ifdef APPLY_RESULT_SIZE
724 size = APPLY_RESULT_SIZE;
725 #endif
726 }
727 return size;
728 }
729
730 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
731 /* Create a vector describing the result block RESULT. If SAVEP is true,
732 the result block is used to save the values; otherwise it is used to
733 restore the values. */
734
735 static rtx
736 result_vector (savep, result)
737 int savep;
738 rtx result;
739 {
740 int regno, size, align, nelts;
741 enum machine_mode mode;
742 rtx reg, mem;
743 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
744
745 size = nelts = 0;
746 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
747 if ((mode = apply_result_mode[regno]) != VOIDmode)
748 {
749 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
750 if (size % align != 0)
751 size = CEIL (size, align) * align;
752 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
753 mem = change_address (result, mode,
754 plus_constant (XEXP (result, 0), size));
755 savevec[nelts++] = (savep
756 ? gen_rtx_SET (VOIDmode, mem, reg)
757 : gen_rtx_SET (VOIDmode, reg, mem));
758 size += GET_MODE_SIZE (mode);
759 }
760 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
761 }
762 #endif /* HAVE_untyped_call or HAVE_untyped_return */
763
764 /* Save the state required to perform an untyped call with the same
765 arguments as were passed to the current function. */
766
767 static rtx
768 expand_builtin_apply_args_1 ()
769 {
770 rtx registers;
771 int size, align, regno;
772 enum machine_mode mode;
773
774 /* Create a block where the arg-pointer, structure value address,
775 and argument registers can be saved. */
776 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
777
778 /* Walk past the arg-pointer and structure value address. */
779 size = GET_MODE_SIZE (Pmode);
780 if (struct_value_rtx)
781 size += GET_MODE_SIZE (Pmode);
782
783 /* Save each register used in calling a function to the block. */
784 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
785 if ((mode = apply_args_mode[regno]) != VOIDmode)
786 {
787 rtx tem;
788
789 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
790 if (size % align != 0)
791 size = CEIL (size, align) * align;
792
793 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
794
795 emit_move_insn (change_address (registers, mode,
796 plus_constant (XEXP (registers, 0),
797 size)),
798 tem);
799 size += GET_MODE_SIZE (mode);
800 }
801
802 /* Save the arg pointer to the block. */
803 emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
804 copy_to_reg (virtual_incoming_args_rtx));
805 size = GET_MODE_SIZE (Pmode);
806
807 /* Save the structure value address unless this is passed as an
808 "invisible" first argument. */
809 if (struct_value_incoming_rtx)
810 {
811 emit_move_insn (change_address (registers, Pmode,
812 plus_constant (XEXP (registers, 0),
813 size)),
814 copy_to_reg (struct_value_incoming_rtx));
815 size += GET_MODE_SIZE (Pmode);
816 }
817
818 /* Return the address of the block. */
819 return copy_addr_to_reg (XEXP (registers, 0));
820 }
821
822 /* __builtin_apply_args returns block of memory allocated on
823 the stack into which is stored the arg pointer, structure
824 value address, static chain, and all the registers that might
825 possibly be used in performing a function call. The code is
826 moved to the start of the function so the incoming values are
827 saved. */
828 static rtx
829 expand_builtin_apply_args ()
830 {
831 /* Don't do __builtin_apply_args more than once in a function.
832 Save the result of the first call and reuse it. */
833 if (apply_args_value != 0)
834 return apply_args_value;
835 {
836 /* When this function is called, it means that registers must be
837 saved on entry to this function. So we migrate the
838 call to the first insn of this function. */
839 rtx temp;
840 rtx seq;
841
842 start_sequence ();
843 temp = expand_builtin_apply_args_1 ();
844 seq = get_insns ();
845 end_sequence ();
846
847 apply_args_value = temp;
848
849 /* Put the sequence after the NOTE that starts the function.
850 If this is inside a SEQUENCE, make the outer-level insn
851 chain current, so the code is placed at the start of the
852 function. */
853 push_topmost_sequence ();
854 emit_insns_before (seq, NEXT_INSN (get_insns ()));
855 pop_topmost_sequence ();
856 return temp;
857 }
858 }
859
860 /* Perform an untyped call and save the state required to perform an
861 untyped return of whatever value was returned by the given function. */
862
863 static rtx
864 expand_builtin_apply (function, arguments, argsize)
865 rtx function, arguments, argsize;
866 {
867 int size, align, regno;
868 enum machine_mode mode;
869 rtx incoming_args, result, reg, dest, call_insn;
870 rtx old_stack_level = 0;
871 rtx call_fusage = 0;
872
873 /* Create a block where the return registers can be saved. */
874 result = assign_stack_local (BLKmode, apply_result_size (), -1);
875
876 /* Fetch the arg pointer from the ARGUMENTS block. */
877 incoming_args = gen_reg_rtx (Pmode);
878 emit_move_insn (incoming_args,
879 gen_rtx_MEM (Pmode, arguments));
880 #ifndef STACK_GROWS_DOWNWARD
881 incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
882 incoming_args, 0, OPTAB_LIB_WIDEN);
883 #endif
884
885 /* Perform postincrements before actually calling the function. */
886 emit_queue ();
887
888 /* Push a new argument block and copy the arguments. Do not allow
889 the (potential) memcpy call below to interfere with our stack
890 manipulations. */
891 do_pending_stack_adjust ();
892 NO_DEFER_POP;
893
894 /* Save the stack with nonlocal if available */
895 #ifdef HAVE_save_stack_nonlocal
896 if (HAVE_save_stack_nonlocal)
897 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
898 else
899 #endif
900 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
901
902 /* Push a block of memory onto the stack to store the memory arguments.
903 Save the address in a register, and copy the memory arguments. ??? I
904 haven't figured out how the calling convention macros effect this,
905 but it's likely that the source and/or destination addresses in
906 the block copy will need updating in machine specific ways. */
907 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
908 emit_block_move (gen_rtx_MEM (BLKmode, dest),
909 gen_rtx_MEM (BLKmode, incoming_args),
910 argsize, PARM_BOUNDARY);
911
912 /* Refer to the argument block. */
913 apply_args_size ();
914 arguments = gen_rtx_MEM (BLKmode, arguments);
915
916 /* Walk past the arg-pointer and structure value address. */
917 size = GET_MODE_SIZE (Pmode);
918 if (struct_value_rtx)
919 size += GET_MODE_SIZE (Pmode);
920
921 /* Restore each of the registers previously saved. Make USE insns
922 for each of these registers for use in making the call. */
923 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
924 if ((mode = apply_args_mode[regno]) != VOIDmode)
925 {
926 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
927 if (size % align != 0)
928 size = CEIL (size, align) * align;
929 reg = gen_rtx_REG (mode, regno);
930 emit_move_insn (reg,
931 change_address (arguments, mode,
932 plus_constant (XEXP (arguments, 0),
933 size)));
934
935 use_reg (&call_fusage, reg);
936 size += GET_MODE_SIZE (mode);
937 }
938
939 /* Restore the structure value address unless this is passed as an
940 "invisible" first argument. */
941 size = GET_MODE_SIZE (Pmode);
942 if (struct_value_rtx)
943 {
944 rtx value = gen_reg_rtx (Pmode);
945 emit_move_insn (value,
946 change_address (arguments, Pmode,
947 plus_constant (XEXP (arguments, 0),
948 size)));
949 emit_move_insn (struct_value_rtx, value);
950 if (GET_CODE (struct_value_rtx) == REG)
951 use_reg (&call_fusage, struct_value_rtx);
952 size += GET_MODE_SIZE (Pmode);
953 }
954
955 /* All arguments and registers used for the call are set up by now! */
956 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
957
958 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
959 and we don't want to load it into a register as an optimization,
960 because prepare_call_address already did it if it should be done. */
961 if (GET_CODE (function) != SYMBOL_REF)
962 function = memory_address (FUNCTION_MODE, function);
963
964 /* Generate the actual call instruction and save the return value. */
965 #ifdef HAVE_untyped_call
966 if (HAVE_untyped_call)
967 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
968 result, result_vector (1, result)));
969 else
970 #endif
971 #ifdef HAVE_call_value
972 if (HAVE_call_value)
973 {
974 rtx valreg = 0;
975
976 /* Locate the unique return register. It is not possible to
977 express a call that sets more than one return register using
978 call_value; use untyped_call for that. In fact, untyped_call
979 only needs to save the return registers in the given block. */
980 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
981 if ((mode = apply_result_mode[regno]) != VOIDmode)
982 {
983 if (valreg)
984 abort (); /* HAVE_untyped_call required. */
985 valreg = gen_rtx_REG (mode, regno);
986 }
987
988 emit_call_insn (GEN_CALL_VALUE (valreg,
989 gen_rtx_MEM (FUNCTION_MODE, function),
990 const0_rtx, NULL_RTX, const0_rtx));
991
992 emit_move_insn (change_address (result, GET_MODE (valreg),
993 XEXP (result, 0)),
994 valreg);
995 }
996 else
997 #endif
998 abort ();
999
1000 /* Find the CALL insn we just emitted. */
1001 for (call_insn = get_last_insn ();
1002 call_insn && GET_CODE (call_insn) != CALL_INSN;
1003 call_insn = PREV_INSN (call_insn))
1004 ;
1005
1006 if (! call_insn)
1007 abort ();
1008
1009 /* Put the register usage information on the CALL. If there is already
1010 some usage information, put ours at the end. */
1011 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1012 {
1013 rtx link;
1014
1015 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1016 link = XEXP (link, 1))
1017 ;
1018
1019 XEXP (link, 1) = call_fusage;
1020 }
1021 else
1022 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1023
1024 /* Restore the stack. */
1025 #ifdef HAVE_save_stack_nonlocal
1026 if (HAVE_save_stack_nonlocal)
1027 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1028 else
1029 #endif
1030 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1031
1032 OK_DEFER_POP;
1033
1034 /* Return the address of the result block. */
1035 return copy_addr_to_reg (XEXP (result, 0));
1036 }
1037
1038 /* Perform an untyped return. */
1039
1040 static void
1041 expand_builtin_return (result)
1042 rtx result;
1043 {
1044 int size, align, regno;
1045 enum machine_mode mode;
1046 rtx reg;
1047 rtx call_fusage = 0;
1048
1049 apply_result_size ();
1050 result = gen_rtx_MEM (BLKmode, result);
1051
1052 #ifdef HAVE_untyped_return
1053 if (HAVE_untyped_return)
1054 {
1055 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1056 emit_barrier ();
1057 return;
1058 }
1059 #endif
1060
1061 /* Restore the return value and note that each value is used. */
1062 size = 0;
1063 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1064 if ((mode = apply_result_mode[regno]) != VOIDmode)
1065 {
1066 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1067 if (size % align != 0)
1068 size = CEIL (size, align) * align;
1069 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1070 emit_move_insn (reg,
1071 change_address (result, mode,
1072 plus_constant (XEXP (result, 0),
1073 size)));
1074
1075 push_to_sequence (call_fusage);
1076 emit_insn (gen_rtx_USE (VOIDmode, reg));
1077 call_fusage = get_insns ();
1078 end_sequence ();
1079 size += GET_MODE_SIZE (mode);
1080 }
1081
1082 /* Put the USE insns before the return. */
1083 emit_insns (call_fusage);
1084
1085 /* Return whatever values was restored by jumping directly to the end
1086 of the function. */
1087 expand_null_return ();
1088 }
1089
1090 /* Expand a call to __builtin_classify_type with arguments found in
1091 ARGLIST. */
1092 static rtx
1093 expand_builtin_classify_type (arglist)
1094 tree arglist;
1095 {
1096 if (arglist != 0)
1097 {
1098 tree type = TREE_TYPE (TREE_VALUE (arglist));
1099 enum tree_code code = TREE_CODE (type);
1100 if (code == VOID_TYPE)
1101 return GEN_INT (void_type_class);
1102 if (code == INTEGER_TYPE)
1103 return GEN_INT (integer_type_class);
1104 if (code == CHAR_TYPE)
1105 return GEN_INT (char_type_class);
1106 if (code == ENUMERAL_TYPE)
1107 return GEN_INT (enumeral_type_class);
1108 if (code == BOOLEAN_TYPE)
1109 return GEN_INT (boolean_type_class);
1110 if (code == POINTER_TYPE)
1111 return GEN_INT (pointer_type_class);
1112 if (code == REFERENCE_TYPE)
1113 return GEN_INT (reference_type_class);
1114 if (code == OFFSET_TYPE)
1115 return GEN_INT (offset_type_class);
1116 if (code == REAL_TYPE)
1117 return GEN_INT (real_type_class);
1118 if (code == COMPLEX_TYPE)
1119 return GEN_INT (complex_type_class);
1120 if (code == FUNCTION_TYPE)
1121 return GEN_INT (function_type_class);
1122 if (code == METHOD_TYPE)
1123 return GEN_INT (method_type_class);
1124 if (code == RECORD_TYPE)
1125 return GEN_INT (record_type_class);
1126 if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
1127 return GEN_INT (union_type_class);
1128 if (code == ARRAY_TYPE)
1129 {
1130 if (TYPE_STRING_FLAG (type))
1131 return GEN_INT (string_type_class);
1132 else
1133 return GEN_INT (array_type_class);
1134 }
1135 if (code == SET_TYPE)
1136 return GEN_INT (set_type_class);
1137 if (code == FILE_TYPE)
1138 return GEN_INT (file_type_class);
1139 if (code == LANG_TYPE)
1140 return GEN_INT (lang_type_class);
1141 }
1142 return GEN_INT (no_type_class);
1143 }
1144
1145 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1146 static rtx
1147 expand_builtin_constant_p (exp)
1148 tree exp;
1149 {
1150 tree arglist = TREE_OPERAND (exp, 1);
1151 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1152
1153 if (arglist == 0)
1154 return const0_rtx;
1155 else
1156 {
1157 tree arg = TREE_VALUE (arglist);
1158 rtx tmp;
1159
1160 /* We return 1 for a numeric type that's known to be a constant
1161 value at compile-time or for an aggregate type that's a
1162 literal constant. */
1163 STRIP_NOPS (arg);
1164
1165 /* If we know this is a constant, emit the constant of one. */
1166 if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'c'
1167 || (TREE_CODE (arg) == CONSTRUCTOR
1168 && TREE_CONSTANT (arg))
1169 || (TREE_CODE (arg) == ADDR_EXPR
1170 && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
1171 return const1_rtx;
1172
1173 /* If we aren't going to be running CSE or this expression
1174 has side effects, show we don't know it to be a constant.
1175 Likewise if it's a pointer or aggregate type since in those
1176 case we only want literals, since those are only optimized
1177 when generating RTL, not later. */
1178 if (TREE_SIDE_EFFECTS (arg) || cse_not_expected
1179 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
1180 || POINTER_TYPE_P (TREE_TYPE (arg)))
1181 return const0_rtx;
1182
1183 /* Otherwise, emit (constant_p_rtx (ARG)) and let CSE get a
1184 chance to see if it can deduce whether ARG is constant. */
1185
1186 tmp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
1187 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1188 return tmp;
1189 }
1190 }
1191
1192 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1193 Return 0 if a normal call should be emitted rather than expanding the
1194 function in-line. EXP is the expression that is a call to the builtin
1195 function; if convenient, the result should be placed in TARGET.
1196 SUBTARGET may be used as the target for computing one of EXP's operands. */
1197 static rtx
1198 expand_builtin_mathfn (exp, target, subtarget)
1199 tree exp;
1200 rtx target, subtarget;
1201 {
1202 optab builtin_optab;
1203 rtx op0, insns;
1204 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1205 tree arglist = TREE_OPERAND (exp, 1);
1206
1207 if (arglist == 0
1208 /* Arg could be wrong type if user redeclared this fcn wrong. */
1209 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
1210 return 0;
1211
1212 /* Stabilize and compute the argument. */
1213 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1214 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1215 {
1216 exp = copy_node (exp);
1217 TREE_OPERAND (exp, 1) = arglist;
1218 /* Wrap the computation of the argument in a SAVE_EXPR. That
1219 way, if we need to expand the argument again (as in the
1220 flag_errno_math case below where we cannot directly set
1221 errno), we will not perform side-effects more than once.
1222 Note that here we're mutating the original EXP as well as the
1223 copy; that's the right thing to do in case the original EXP
1224 is expanded later. */
1225 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1226 arglist = copy_node (arglist);
1227 }
1228 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1229
1230 /* Make a suitable register to place result in. */
1231 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1232
1233 emit_queue ();
1234 start_sequence ();
1235
1236 switch (DECL_FUNCTION_CODE (fndecl))
1237 {
1238 case BUILT_IN_SIN:
1239 builtin_optab = sin_optab; break;
1240 case BUILT_IN_COS:
1241 builtin_optab = cos_optab; break;
1242 case BUILT_IN_FSQRT:
1243 builtin_optab = sqrt_optab; break;
1244 default:
1245 abort ();
1246 }
1247
1248 /* Compute into TARGET.
1249 Set TARGET to wherever the result comes back. */
1250 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1251 builtin_optab, op0, target, 0);
1252
1253 /* If we were unable to expand via the builtin, stop the
1254 sequence (without outputting the insns) and return 0, causing
1255 a call to the library function. */
1256 if (target == 0)
1257 {
1258 end_sequence ();
1259 return 0;
1260 }
1261
1262 /* Check the results by default. But if flag_fast_math is turned on,
1263 then assume sqrt will always be called with valid arguments. */
1264
1265 if (flag_errno_math && ! flag_fast_math)
1266 {
1267 rtx lab1;
1268
1269 /* Don't define the builtin FP instructions
1270 if your machine is not IEEE. */
1271 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1272 abort ();
1273
1274 lab1 = gen_label_rtx ();
1275
1276 /* Test the result; if it is NaN, set errno=EDOM because
1277 the argument was not in the domain. */
1278 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1279 0, 0, lab1);
1280
1281 #ifdef TARGET_EDOM
1282 {
1283 #ifdef GEN_ERRNO_RTX
1284 rtx errno_rtx = GEN_ERRNO_RTX;
1285 #else
1286 rtx errno_rtx
1287 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1288 #endif
1289
1290 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1291 }
1292 #else
1293 /* We can't set errno=EDOM directly; let the library call do it.
1294 Pop the arguments right away in case the call gets deleted. */
1295 NO_DEFER_POP;
1296 expand_call (exp, target, 0);
1297 OK_DEFER_POP;
1298 #endif
1299
1300 emit_label (lab1);
1301 }
1302
1303 /* Output the entire sequence. */
1304 insns = get_insns ();
1305 end_sequence ();
1306 emit_insns (insns);
1307
1308 return target;
1309 }
1310
1311 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1312 if we failed the caller should emit a normal call, otherwise
1313 try to get the result in TARGET, if convenient (and in mode MODE if that's
1314 convenient). */
1315
1316 static rtx
1317 expand_builtin_strlen (exp, target, mode)
1318 tree exp;
1319 rtx target;
1320 enum machine_mode mode;
1321 {
1322 tree arglist = TREE_OPERAND (exp, 1);
1323 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1324
1325 if (arglist == 0
1326 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1327 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
1328 return 0;
1329 else
1330 {
1331 rtx pat;
1332 tree src = TREE_VALUE (arglist);
1333 tree len = c_strlen (src);
1334
1335 int align
1336 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1337
1338 rtx result, src_reg, char_rtx, before_strlen;
1339 enum machine_mode insn_mode = value_mode, char_mode;
1340 enum insn_code icode = CODE_FOR_nothing;
1341
1342 /* If the length is known, just return it. */
1343 if (len != 0)
1344 return expand_expr (len, target, mode, EXPAND_MEMORY_USE_BAD);
1345
1346 /* If SRC is not a pointer type, don't do this operation inline. */
1347 if (align == 0)
1348 return 0;
1349
1350 /* Bail out if we can't compute strlen in the right mode. */
1351 while (insn_mode != VOIDmode)
1352 {
1353 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1354 if (icode != CODE_FOR_nothing)
1355 break;
1356
1357 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1358 }
1359 if (insn_mode == VOIDmode)
1360 return 0;
1361
1362 /* Make a place to write the result of the instruction. */
1363 result = target;
1364 if (! (result != 0
1365 && GET_CODE (result) == REG
1366 && GET_MODE (result) == insn_mode
1367 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1368 result = gen_reg_rtx (insn_mode);
1369
1370 /* Make a place to hold the source address. We will not expand
1371 the actual source until we are sure that the expansion will
1372 not fail -- there are trees that cannot be expanded twice. */
1373 src_reg = gen_reg_rtx (Pmode);
1374
1375 /* Mark the beginning of the strlen sequence so we can emit the
1376 source operand later. */
1377 before_strlen = get_last_insn();
1378
1379 /* Check the string is readable and has an end. */
1380 if (current_function_check_memory_usage)
1381 emit_library_call (chkr_check_str_libfunc, 1, VOIDmode, 2,
1382 src_reg, Pmode,
1383 GEN_INT (MEMORY_USE_RO),
1384 TYPE_MODE (integer_type_node));
1385
1386 char_rtx = const0_rtx;
1387 char_mode = insn_data[(int) icode].operand[2].mode;
1388 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1389 char_mode))
1390 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1391
1392 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1393 char_rtx, GEN_INT (align));
1394 if (! pat)
1395 return 0;
1396 emit_insn (pat);
1397
1398 /* Now that we are assured of success, expand the source. */
1399 start_sequence ();
1400 pat = memory_address (BLKmode,
1401 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1402 if (pat != src_reg)
1403 emit_move_insn (src_reg, pat);
1404 pat = gen_sequence ();
1405 end_sequence ();
1406
1407 if (before_strlen)
1408 emit_insn_after (pat, before_strlen);
1409 else
1410 emit_insn_before (pat, get_insns ());
1411
1412 /* Return the value in the proper mode for this function. */
1413 if (GET_MODE (result) == value_mode)
1414 target = result;
1415 else if (target != 0)
1416 convert_move (target, result, 0);
1417 else
1418 target = convert_to_mode (value_mode, result, 0);
1419
1420 return target;
1421 }
1422 }
1423
1424 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1425 static rtx
1426 expand_builtin_memcpy (arglist)
1427 tree arglist;
1428 {
1429 if (arglist == 0
1430 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1431 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1432 || TREE_CHAIN (arglist) == 0
1433 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1434 != POINTER_TYPE)
1435 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1436 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1437 (TREE_CHAIN (TREE_CHAIN (arglist)))))
1438 != INTEGER_TYPE))
1439 return 0;
1440 else
1441 {
1442 tree dest = TREE_VALUE (arglist);
1443 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1444 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1445
1446 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1447 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1448 rtx dest_mem, src_mem, dest_addr, len_rtx;
1449
1450 /* If either SRC or DEST is not a pointer type, don't do
1451 this operation in-line. */
1452 if (src_align == 0 || dest_align == 0)
1453 return 0;
1454
1455 dest_mem = get_memory_rtx (dest);
1456 src_mem = get_memory_rtx (src);
1457 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1458
1459 /* Just copy the rights of SRC to the rights of DEST. */
1460 if (current_function_check_memory_usage)
1461 emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
1462 XEXP (dest_mem, 0), Pmode,
1463 XEXP (src_mem, 0), Pmode,
1464 len_rtx, TYPE_MODE (sizetype));
1465
1466 /* Copy word part most expediently. */
1467 dest_addr
1468 = emit_block_move (dest_mem, src_mem, len_rtx,
1469 MIN (src_align, dest_align));
1470
1471 if (dest_addr == 0)
1472 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1473
1474 return dest_addr;
1475 }
1476 }
1477
1478 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1479 if we failed the caller should emit a normal call. */
1480
1481 static rtx
1482 expand_builtin_strcpy (exp)
1483 tree exp;
1484 {
1485 tree arglist = TREE_OPERAND (exp, 1);
1486 rtx result;
1487
1488 if (arglist == 0
1489 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1490 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1491 || TREE_CHAIN (arglist) == 0
1492 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1493 != POINTER_TYPE))
1494 return 0;
1495 else
1496 {
1497 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1498
1499 if (len == 0)
1500 return 0;
1501
1502 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1503 chainon (arglist, build_tree_list (NULL_TREE, len));
1504 }
1505
1506 result = expand_builtin_memcpy (arglist);
1507
1508 if (! result)
1509 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1510 return result;
1511 }
1512
1513 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1514 if we failed the caller should emit a normal call. */
1515
1516 static rtx
1517 expand_builtin_memset (exp)
1518 tree exp;
1519 {
1520 tree arglist = TREE_OPERAND (exp, 1);
1521
1522 if (arglist == 0
1523 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1524 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1525 || TREE_CHAIN (arglist) == 0
1526 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1527 != INTEGER_TYPE)
1528 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1529 || (INTEGER_TYPE
1530 != (TREE_CODE (TREE_TYPE
1531 (TREE_VALUE
1532 (TREE_CHAIN (TREE_CHAIN (arglist))))))))
1533 return 0;
1534 else
1535 {
1536 tree dest = TREE_VALUE (arglist);
1537 tree val = TREE_VALUE (TREE_CHAIN (arglist));
1538 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1539
1540 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1541 rtx dest_mem, dest_addr, len_rtx;
1542
1543 /* If DEST is not a pointer type, don't do this
1544 operation in-line. */
1545 if (dest_align == 0)
1546 return 0;
1547
1548 /* If the arguments have side-effects, then we can only evaluate
1549 them at most once. The following code evaluates them twice if
1550 they are not constants because we break out to expand_call
1551 in that case. They can't be constants if they have side-effects
1552 so we can check for that first. Alternatively, we could call
1553 save_expr to make multiple evaluation safe. */
1554 if (TREE_SIDE_EFFECTS (val) || TREE_SIDE_EFFECTS (len))
1555 return 0;
1556
1557 /* If VAL is not 0, don't do this operation in-line. */
1558 if (expand_expr (val, NULL_RTX, VOIDmode, 0) != const0_rtx)
1559 return 0;
1560
1561 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1562
1563 dest_mem = get_memory_rtx (dest);
1564
1565 /* Just check DST is writable and mark it as readable. */
1566 if (current_function_check_memory_usage)
1567 emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
1568 XEXP (dest_mem, 0), Pmode,
1569 len_rtx, TYPE_MODE (sizetype),
1570 GEN_INT (MEMORY_USE_WO),
1571 TYPE_MODE (integer_type_node));
1572
1573
1574 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
1575
1576 if (dest_addr == 0)
1577 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1578
1579 return dest_addr;
1580 }
1581 }
1582
1583 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
1584 if we failed the caller should emit a normal call. */
1585 static rtx
1586 expand_builtin_bzero (exp)
1587 tree exp;
1588 {
1589 tree arglist = TREE_OPERAND (exp, 1);
1590 tree dest, size, newarglist;
1591 rtx result;
1592
1593 if (arglist == 0
1594 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1595 || TREE_CODE (TREE_TYPE (dest = TREE_VALUE (arglist))) != POINTER_TYPE
1596 || TREE_CHAIN (arglist) == 0
1597 || (TREE_CODE (TREE_TYPE (size = TREE_VALUE (TREE_CHAIN (arglist))))
1598 != INTEGER_TYPE))
1599 return NULL_RTX;
1600
1601 /* New argument list transforming bzero(ptr x, int y) to
1602 memset(ptr x, int 0, size_t y). */
1603
1604 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
1605 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
1606 newarglist = tree_cons (NULL_TREE, dest, newarglist);
1607
1608 TREE_OPERAND (exp, 1) = newarglist;
1609 result = expand_builtin_memset(exp);
1610
1611 /* Always restore the original arguments. */
1612 TREE_OPERAND (exp, 1) = arglist;
1613
1614 return result;
1615 }
1616
1617 #ifdef HAVE_cmpstrsi
1618 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
1619 ARGLIST is the argument list for this call. Return 0 if we failed and the
1620 caller should emit a normal call, otherwise try to get the result in
1621 TARGET, if convenient. */
1622 static rtx
1623 expand_builtin_memcmp (exp, arglist, target)
1624 tree exp;
1625 tree arglist;
1626 rtx target;
1627 {
1628 /* If we need to check memory accesses, call the library function. */
1629 if (current_function_check_memory_usage)
1630 return 0;
1631
1632 if (arglist == 0
1633 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1634 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1635 || TREE_CHAIN (arglist) == 0
1636 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1637 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1638 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
1639 return 0;
1640
1641 {
1642 enum machine_mode mode;
1643 tree arg1 = TREE_VALUE (arglist);
1644 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1645 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1646 rtx arg1_rtx, arg2_rtx, arg3_rtx;
1647 rtx result;
1648 rtx insn;
1649
1650 int arg1_align
1651 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1652 int arg2_align
1653 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1654 enum machine_mode insn_mode
1655 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
1656
1657 /* If we don't have POINTER_TYPE, call the function. */
1658 if (arg1_align == 0 || arg2_align == 0)
1659 return 0;
1660
1661 /* Make a place to write the result of the instruction. */
1662 result = target;
1663 if (! (result != 0
1664 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
1665 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1666 result = gen_reg_rtx (insn_mode);
1667
1668 arg1_rtx = get_memory_rtx (arg1);
1669 arg2_rtx = get_memory_rtx (arg2);
1670 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1671 if (!HAVE_cmpstrsi)
1672 insn = NULL_RTX;
1673 else
1674 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
1675 GEN_INT (MIN (arg1_align, arg2_align)));
1676
1677 if (insn)
1678 emit_insn (insn);
1679 else
1680 emit_library_call_value (memcmp_libfunc, result, 2,
1681 TYPE_MODE (integer_type_node), 3,
1682 XEXP (arg1_rtx, 0), Pmode,
1683 XEXP (arg2_rtx, 0), Pmode,
1684 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
1685 TREE_UNSIGNED (sizetype)),
1686 TYPE_MODE (sizetype));
1687
1688 /* Return the value in the proper mode for this function. */
1689 mode = TYPE_MODE (TREE_TYPE (exp));
1690 if (GET_MODE (result) == mode)
1691 return result;
1692 else if (target != 0)
1693 {
1694 convert_move (target, result, 0);
1695 return target;
1696 }
1697 else
1698 return convert_to_mode (mode, result, 0);
1699 }
1700 }
1701
1702 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
1703 if we failed the caller should emit a normal call, otherwise try to get
1704 the result in TARGET, if convenient. */
1705
1706 static rtx
1707 expand_builtin_strcmp (exp, target)
1708 tree exp;
1709 rtx target;
1710 {
1711 tree arglist = TREE_OPERAND (exp, 1);
1712
1713 /* If we need to check memory accesses, call the library function. */
1714 if (current_function_check_memory_usage)
1715 return 0;
1716
1717 if (arglist == 0
1718 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1719 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1720 || TREE_CHAIN (arglist) == 0
1721 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1722 != POINTER_TYPE))
1723 return 0;
1724
1725 else if (! HAVE_cmpstrsi)
1726 return 0;
1727 {
1728 tree arg1 = TREE_VALUE (arglist);
1729 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1730 tree len = c_strlen (arg1);
1731 tree len2 = c_strlen (arg2);
1732 rtx result;
1733
1734 if (len)
1735 len = size_binop (PLUS_EXPR, ssize_int (1), len);
1736
1737 if (len2)
1738 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
1739
1740 /* If we don't have a constant length for the first, use the length
1741 of the second, if we know it. We don't require a constant for
1742 this case; some cost analysis could be done if both are available
1743 but neither is constant. For now, assume they're equally cheap.
1744
1745 If both strings have constant lengths, use the smaller. This
1746 could arise if optimization results in strcpy being called with
1747 two fixed strings, or if the code was machine-generated. We should
1748 add some code to the `memcmp' handler below to deal with such
1749 situations, someday. */
1750
1751 if (!len || TREE_CODE (len) != INTEGER_CST)
1752 {
1753 if (len2)
1754 len = len2;
1755 else if (len == 0)
1756 return 0;
1757 }
1758 else if (len2 && TREE_CODE (len2) == INTEGER_CST
1759 && tree_int_cst_lt (len2, len))
1760 len = len2;
1761
1762 chainon (arglist, build_tree_list (NULL_TREE, len));
1763 result = expand_builtin_memcmp (exp, arglist, target);
1764 if (! result)
1765 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1766
1767 return result;
1768 }
1769 }
1770 #endif
1771
1772 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
1773 if that's convenient. */
1774
1775 rtx
1776 expand_builtin_saveregs ()
1777 {
1778 rtx val, seq;
1779
1780 /* Don't do __builtin_saveregs more than once in a function.
1781 Save the result of the first call and reuse it. */
1782 if (saveregs_value != 0)
1783 return saveregs_value;
1784
1785 /* When this function is called, it means that registers must be
1786 saved on entry to this function. So we migrate the call to the
1787 first insn of this function. */
1788
1789 start_sequence ();
1790
1791 #ifdef EXPAND_BUILTIN_SAVEREGS
1792 /* Do whatever the machine needs done in this case. */
1793 val = EXPAND_BUILTIN_SAVEREGS ();
1794 #else
1795 /* ??? We used to try and build up a call to the out of line function,
1796 guessing about what registers needed saving etc. This became much
1797 harder with __builtin_va_start, since we don't have a tree for a
1798 call to __builtin_saveregs to fall back on. There was exactly one
1799 port (i860) that used this code, and I'm unconvinced it could actually
1800 handle the general case. So we no longer try to handle anything
1801 weird and make the backend absorb the evil. */
1802
1803 error ("__builtin_saveregs not supported by this target");
1804 val = const0_rtx;
1805 #endif
1806
1807 seq = get_insns ();
1808 end_sequence ();
1809
1810 saveregs_value = val;
1811
1812 /* Put the sequence after the NOTE that starts the function. If this
1813 is inside a SEQUENCE, make the outer-level insn chain current, so
1814 the code is placed at the start of the function. */
1815 push_topmost_sequence ();
1816 emit_insns_after (seq, get_insns ());
1817 pop_topmost_sequence ();
1818
1819 return val;
1820 }
1821
1822 /* __builtin_args_info (N) returns word N of the arg space info
1823 for the current function. The number and meanings of words
1824 is controlled by the definition of CUMULATIVE_ARGS. */
1825
1826 static rtx
1827 expand_builtin_args_info (exp)
1828 tree exp;
1829 {
1830 tree arglist = TREE_OPERAND (exp, 1);
1831 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
1832 int *word_ptr = (int *) &current_function_args_info;
1833 #if 0
1834 /* These are used by the code below that is if 0'ed away */
1835 int i;
1836 tree type, elts, result;
1837 #endif
1838
1839 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
1840 abort ();
1841
1842 if (arglist != 0)
1843 {
1844 tree arg = TREE_VALUE (arglist);
1845 if (TREE_CODE (arg) != INTEGER_CST)
1846 error ("argument of `__builtin_args_info' must be constant");
1847 else
1848 {
1849 int wordnum = TREE_INT_CST_LOW (arg);
1850
1851 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
1852 error ("argument of `__builtin_args_info' out of range");
1853 else
1854 return GEN_INT (word_ptr[wordnum]);
1855 }
1856 }
1857 else
1858 error ("missing argument in `__builtin_args_info'");
1859
1860 return const0_rtx;
1861
1862 #if 0
1863 for (i = 0; i < nwords; i++)
1864 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
1865
1866 type = build_array_type (integer_type_node,
1867 build_index_type (build_int_2 (nwords, 0)));
1868 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
1869 TREE_CONSTANT (result) = 1;
1870 TREE_STATIC (result) = 1;
1871 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
1872 TREE_CONSTANT (result) = 1;
1873 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
1874 #endif
1875 }
1876
1877 /* Expand ARGLIST, from a call to __builtin_next_arg. */
1878 static rtx
1879 expand_builtin_next_arg (arglist)
1880 tree arglist;
1881 {
1882 tree fntype = TREE_TYPE (current_function_decl);
1883
1884 if ((TYPE_ARG_TYPES (fntype) == 0
1885 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1886 == void_type_node))
1887 && ! current_function_varargs)
1888 {
1889 error ("`va_start' used in function with fixed args");
1890 return const0_rtx;
1891 }
1892
1893 if (arglist)
1894 {
1895 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
1896 tree arg = TREE_VALUE (arglist);
1897
1898 /* Strip off all nops for the sake of the comparison. This
1899 is not quite the same as STRIP_NOPS. It does more.
1900 We must also strip off INDIRECT_EXPR for C++ reference
1901 parameters. */
1902 while (TREE_CODE (arg) == NOP_EXPR
1903 || TREE_CODE (arg) == CONVERT_EXPR
1904 || TREE_CODE (arg) == NON_LVALUE_EXPR
1905 || TREE_CODE (arg) == INDIRECT_REF)
1906 arg = TREE_OPERAND (arg, 0);
1907 if (arg != last_parm)
1908 warning ("second parameter of `va_start' not last named argument");
1909 }
1910 else if (! current_function_varargs)
1911 /* Evidently an out of date version of <stdarg.h>; can't validate
1912 va_start's second argument, but can still work as intended. */
1913 warning ("`__builtin_next_arg' called without an argument");
1914
1915 return expand_binop (Pmode, add_optab,
1916 current_function_internal_arg_pointer,
1917 current_function_arg_offset_rtx,
1918 NULL_RTX, 0, OPTAB_LIB_WIDEN);
1919 }
1920
1921 /* Make it easier for the backends by protecting the valist argument
1922 from multiple evaluations. */
1923
1924 static tree
1925 stabilize_va_list (valist, needs_lvalue)
1926 tree valist;
1927 int needs_lvalue;
1928 {
1929 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
1930 {
1931 if (TREE_SIDE_EFFECTS (valist))
1932 valist = save_expr (valist);
1933
1934 /* For this case, the backends will be expecting a pointer to
1935 TREE_TYPE (va_list_type_node), but it's possible we've
1936 actually been given an array (an actual va_list_type_node).
1937 So fix it. */
1938 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
1939 {
1940 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
1941 tree p2 = build_pointer_type (va_list_type_node);
1942
1943 valist = build1 (ADDR_EXPR, p2, valist);
1944 valist = fold (build1 (NOP_EXPR, p1, valist));
1945 }
1946 }
1947 else
1948 {
1949 tree pt;
1950
1951 if (! needs_lvalue)
1952 {
1953 if (! TREE_SIDE_EFFECTS (valist))
1954 return valist;
1955
1956 pt = build_pointer_type (va_list_type_node);
1957 valist = fold (build1 (ADDR_EXPR, pt, valist));
1958 TREE_SIDE_EFFECTS (valist) = 1;
1959 }
1960
1961 if (TREE_SIDE_EFFECTS (valist))
1962 valist = save_expr (valist);
1963 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
1964 valist));
1965 }
1966
1967 return valist;
1968 }
1969
1970 /* The "standard" implementation of va_start: just assign `nextarg' to
1971 the variable. */
1972 void
1973 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
1974 int stdarg_p ATTRIBUTE_UNUSED;
1975 tree valist;
1976 rtx nextarg;
1977 {
1978 tree t;
1979
1980 if (!stdarg_p)
1981 nextarg = plus_constant (nextarg, -UNITS_PER_WORD);
1982
1983 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
1984 make_tree (ptr_type_node, nextarg));
1985 TREE_SIDE_EFFECTS (t) = 1;
1986
1987 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1988 }
1989
1990 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
1991 __builtin_varargs_va_start, depending on STDARG_P. */
1992 static rtx
1993 expand_builtin_va_start (stdarg_p, arglist)
1994 int stdarg_p;
1995 tree arglist;
1996 {
1997 rtx nextarg;
1998 tree chain = arglist, valist;
1999
2000 if (stdarg_p)
2001 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2002 else
2003 nextarg = expand_builtin_next_arg (NULL_TREE);
2004
2005 if (TREE_CHAIN (chain))
2006 error ("too many arguments to function `va_start'");
2007
2008 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2009
2010 #ifdef EXPAND_BUILTIN_VA_START
2011 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2012 #else
2013 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2014 #endif
2015
2016 return const0_rtx;
2017 }
2018
2019 /* The "standard" implementation of va_arg: read the value from the
2020 current (padded) address and increment by the (padded) size. */
2021
2022 rtx
2023 std_expand_builtin_va_arg (valist, type)
2024 tree valist, type;
2025 {
2026 tree addr_tree, t;
2027 HOST_WIDE_INT align;
2028 HOST_WIDE_INT rounded_size;
2029 rtx addr;
2030
2031 /* Compute the rounded size of the type. */
2032 align = PARM_BOUNDARY / BITS_PER_UNIT;
2033 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2034
2035 /* Get AP. */
2036 addr_tree = valist;
2037 if (PAD_VARARGS_DOWN)
2038 {
2039 /* Small args are padded downward. */
2040
2041 HOST_WIDE_INT adj;
2042 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
2043 if (rounded_size > align)
2044 adj = rounded_size;
2045
2046 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2047 build_int_2 (rounded_size - adj, 0));
2048 }
2049
2050 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2051 addr = copy_to_reg (addr);
2052
2053 /* Compute new value for AP. */
2054 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2055 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2056 build_int_2 (rounded_size, 0)));
2057 TREE_SIDE_EFFECTS (t) = 1;
2058 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2059
2060 return addr;
2061 }
2062
2063 /* Expand __builtin_va_arg, which is not really a builtin function, but
2064 a very special sort of operator. */
2065
2066 rtx
2067 expand_builtin_va_arg (valist, type)
2068 tree valist, type;
2069 {
2070 rtx addr, result;
2071 tree promoted_type, want_va_type, have_va_type;
2072
2073 /* Verify that valist is of the proper type. */
2074
2075 want_va_type = va_list_type_node;
2076 have_va_type = TREE_TYPE (valist);
2077 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2078 {
2079 /* If va_list is an array type, the argument may have decayed
2080 to a pointer type, e.g. by being passed to another function.
2081 In that case, unwrap both types so that we can compare the
2082 underlying records. */
2083 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2084 || TREE_CODE (have_va_type) == POINTER_TYPE)
2085 {
2086 want_va_type = TREE_TYPE (want_va_type);
2087 have_va_type = TREE_TYPE (have_va_type);
2088 }
2089 }
2090 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2091 {
2092 error ("first argument to `va_arg' not of type `va_list'");
2093 addr = const0_rtx;
2094 }
2095
2096 /* Generate a diagnostic for requesting data of a type that cannot
2097 be passed through `...' due to type promotion at the call site. */
2098 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2099 {
2100 const char *name = "<anonymous type>", *pname = 0;
2101 static int gave_help;
2102
2103 if (TYPE_NAME (type))
2104 {
2105 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2106 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2107 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2108 && DECL_NAME (TYPE_NAME (type)))
2109 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2110 }
2111 if (TYPE_NAME (promoted_type))
2112 {
2113 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2114 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2115 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2116 && DECL_NAME (TYPE_NAME (promoted_type)))
2117 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2118 }
2119
2120 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2121 if (! gave_help)
2122 {
2123 gave_help = 1;
2124 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2125 }
2126
2127 addr = const0_rtx;
2128 }
2129 else
2130 {
2131 /* Make it easier for the backends by protecting the valist argument
2132 from multiple evaluations. */
2133 valist = stabilize_va_list (valist, 0);
2134
2135 #ifdef EXPAND_BUILTIN_VA_ARG
2136 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2137 #else
2138 addr = std_expand_builtin_va_arg (valist, type);
2139 #endif
2140 }
2141
2142 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2143 MEM_ALIAS_SET (result) = get_varargs_alias_set ();
2144
2145 return result;
2146 }
2147
2148 /* Expand ARGLIST, from a call to __builtin_va_end. */
2149
2150 static rtx
2151 expand_builtin_va_end (arglist)
2152 tree arglist;
2153 {
2154 tree valist = TREE_VALUE (arglist);
2155
2156 #ifdef EXPAND_BUILTIN_VA_END
2157 valist = stabilize_va_list (valist, 0);
2158 EXPAND_BUILTIN_VA_END(arglist);
2159 #else
2160 /* Evaluate for side effects, if needed. I hate macros that don't
2161 do that. */
2162 if (TREE_SIDE_EFFECTS (valist))
2163 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2164 #endif
2165
2166 return const0_rtx;
2167 }
2168
2169 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2170 builtin rather than just as an assignment in stdarg.h because of the
2171 nastiness of array-type va_list types. */
2172
2173 static rtx
2174 expand_builtin_va_copy (arglist)
2175 tree arglist;
2176 {
2177 tree dst, src, t;
2178
2179 dst = TREE_VALUE (arglist);
2180 src = TREE_VALUE (TREE_CHAIN (arglist));
2181
2182 dst = stabilize_va_list (dst, 1);
2183 src = stabilize_va_list (src, 0);
2184
2185 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2186 {
2187 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
2188 TREE_SIDE_EFFECTS (t) = 1;
2189 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2190 }
2191 else
2192 {
2193 rtx dstb, srcb, size;
2194
2195 /* Evaluate to pointers. */
2196 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
2197 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
2198 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
2199 VOIDmode, EXPAND_NORMAL);
2200
2201 /* "Dereference" to BLKmode memories. */
2202 dstb = gen_rtx_MEM (BLKmode, dstb);
2203 MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
2204 srcb = gen_rtx_MEM (BLKmode, srcb);
2205 MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
2206
2207 /* Copy. */
2208 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
2209 }
2210
2211 return const0_rtx;
2212 }
2213
2214 /* Expand a call to one of the builtin functions __builtin_frame_address or
2215 __builtin_return_address. */
2216 static rtx
2217 expand_builtin_frame_address (exp)
2218 tree exp;
2219 {
2220 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2221 tree arglist = TREE_OPERAND (exp, 1);
2222
2223 /* The argument must be a nonnegative integer constant.
2224 It counts the number of frames to scan up the stack.
2225 The value is the return address saved in that frame. */
2226 if (arglist == 0)
2227 /* Warning about missing arg was already issued. */
2228 return const0_rtx;
2229 else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST
2230 || tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
2231 {
2232 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2233 error ("invalid arg to `__builtin_frame_address'");
2234 else
2235 error ("invalid arg to `__builtin_return_address'");
2236 return const0_rtx;
2237 }
2238 else
2239 {
2240 rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
2241 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
2242 hard_frame_pointer_rtx);
2243
2244 /* Some ports cannot access arbitrary stack frames. */
2245 if (tem == NULL)
2246 {
2247 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2248 warning ("unsupported arg to `__builtin_frame_address'");
2249 else
2250 warning ("unsupported arg to `__builtin_return_address'");
2251 return const0_rtx;
2252 }
2253
2254 /* For __builtin_frame_address, return what we've got. */
2255 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2256 return tem;
2257
2258 if (GET_CODE (tem) != REG
2259 && ! CONSTANT_P (tem))
2260 tem = copy_to_mode_reg (Pmode, tem);
2261 return tem;
2262 }
2263 }
2264
2265 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
2266 we failed and the caller should emit a normal call, otherwise try to get
2267 the result in TARGET, if convenient. */
2268 static rtx
2269 expand_builtin_alloca (arglist, target)
2270 tree arglist;
2271 rtx target;
2272 {
2273 rtx op0;
2274
2275 if (arglist == 0
2276 /* Arg could be non-integer if user redeclared this fcn wrong. */
2277 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2278 return 0;
2279
2280 /* Compute the argument. */
2281 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
2282
2283 /* Allocate the desired space. */
2284 return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
2285 }
2286
2287 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
2288 Return 0 if a normal call should be emitted rather than expanding the
2289 function in-line. If convenient, the result should be placed in TARGET.
2290 SUBTARGET may be used as the target for computing one of EXP's operands. */
2291 static rtx
2292 expand_builtin_ffs (arglist, target, subtarget)
2293 tree arglist;
2294 rtx target, subtarget;
2295 {
2296 rtx op0;
2297 if (arglist == 0
2298 /* Arg could be non-integer if user redeclared this fcn wrong. */
2299 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2300 return 0;
2301
2302 /* Compute the argument. */
2303 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
2304 /* Compute ffs, into TARGET if possible.
2305 Set TARGET to wherever the result comes back. */
2306 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
2307 ffs_optab, op0, target, 1);
2308 if (target == 0)
2309 abort ();
2310 return target;
2311 }
2312
2313 /* Expand a call to __builtin_expect. We return our argument and
2314 emit a NOTE_INSN_EXPECTED_VALUE note. */
2315
2316 static rtx
2317 expand_builtin_expect (arglist, target)
2318 tree arglist;
2319 rtx target;
2320 {
2321 tree exp, c;
2322 rtx note, rtx_c;
2323
2324 if (arglist == NULL_TREE
2325 || TREE_CHAIN (arglist) == NULL_TREE)
2326 return const0_rtx;
2327 exp = TREE_VALUE (arglist);
2328 c = TREE_VALUE (TREE_CHAIN (arglist));
2329
2330 if (TREE_CODE (c) != INTEGER_CST)
2331 {
2332 error ("second arg to `__builtin_expect' must be a constant");
2333 c = integer_zero_node;
2334 }
2335
2336 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
2337
2338 /* Don't bother with expected value notes for integral constants. */
2339 if (GET_CODE (target) != CONST_INT)
2340 {
2341 /* We do need to force this into a register so that we can be
2342 moderately sure to be able to correctly interpret the branch
2343 condition later. */
2344 target = force_reg (GET_MODE (target), target);
2345
2346 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
2347
2348 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2349 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
2350 }
2351
2352 return target;
2353 }
2354 \f
2355 /* Expand an expression EXP that calls a built-in function,
2356 with result going to TARGET if that's convenient
2357 (and in mode MODE if that's convenient).
2358 SUBTARGET may be used as the target for computing one of EXP's operands.
2359 IGNORE is nonzero if the value is to be ignored. */
2360
2361 rtx
2362 expand_builtin (exp, target, subtarget, mode, ignore)
2363 tree exp;
2364 rtx target;
2365 rtx subtarget;
2366 enum machine_mode mode;
2367 int ignore;
2368 {
2369 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2370 tree arglist = TREE_OPERAND (exp, 1);
2371 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
2372
2373 #ifdef MD_EXPAND_BUILTIN
2374 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
2375 return MD_EXPAND_BUILTIN (exp, target, subtarget, mode, ignore);
2376 #endif
2377
2378 /* When not optimizing, generate calls to library functions for a certain
2379 set of builtins. */
2380 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
2381 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
2382 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_MEMSET
2383 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
2384 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
2385 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
2386 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS))
2387 return expand_call (exp, target, ignore);
2388
2389 switch (fcode)
2390 {
2391 case BUILT_IN_ABS:
2392 case BUILT_IN_LABS:
2393 case BUILT_IN_FABS:
2394 /* build_function_call changes these into ABS_EXPR. */
2395 abort ();
2396
2397 case BUILT_IN_SIN:
2398 case BUILT_IN_COS:
2399 /* Treat these like sqrt, but only if the user asks for them. */
2400 if (! flag_fast_math)
2401 break;
2402 case BUILT_IN_FSQRT:
2403 target = expand_builtin_mathfn (exp, target, subtarget);
2404 if (target)
2405 return target;
2406 break;
2407
2408 case BUILT_IN_FMOD:
2409 break;
2410
2411 case BUILT_IN_APPLY_ARGS:
2412 return expand_builtin_apply_args ();
2413
2414 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
2415 FUNCTION with a copy of the parameters described by
2416 ARGUMENTS, and ARGSIZE. It returns a block of memory
2417 allocated on the stack into which is stored all the registers
2418 that might possibly be used for returning the result of a
2419 function. ARGUMENTS is the value returned by
2420 __builtin_apply_args. ARGSIZE is the number of bytes of
2421 arguments that must be copied. ??? How should this value be
2422 computed? We'll also need a safe worst case value for varargs
2423 functions. */
2424 case BUILT_IN_APPLY:
2425 if (arglist == 0
2426 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2427 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
2428 || TREE_CHAIN (arglist) == 0
2429 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
2430 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
2431 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
2432 return const0_rtx;
2433 else
2434 {
2435 int i;
2436 tree t;
2437 rtx ops[3];
2438
2439 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
2440 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
2441
2442 return expand_builtin_apply (ops[0], ops[1], ops[2]);
2443 }
2444
2445 /* __builtin_return (RESULT) causes the function to return the
2446 value described by RESULT. RESULT is address of the block of
2447 memory returned by __builtin_apply. */
2448 case BUILT_IN_RETURN:
2449 if (arglist
2450 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2451 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
2452 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
2453 NULL_RTX, VOIDmode, 0));
2454 return const0_rtx;
2455
2456 case BUILT_IN_SAVEREGS:
2457 return expand_builtin_saveregs ();
2458
2459 case BUILT_IN_ARGS_INFO:
2460 return expand_builtin_args_info (exp);
2461
2462 /* Return the address of the first anonymous stack arg. */
2463 case BUILT_IN_NEXT_ARG:
2464 return expand_builtin_next_arg (arglist);
2465
2466 case BUILT_IN_CLASSIFY_TYPE:
2467 return expand_builtin_classify_type (arglist);
2468
2469 case BUILT_IN_CONSTANT_P:
2470 return expand_builtin_constant_p (exp);
2471
2472 case BUILT_IN_FRAME_ADDRESS:
2473 case BUILT_IN_RETURN_ADDRESS:
2474 return expand_builtin_frame_address (exp);
2475
2476 /* Returns the address of the area where the structure is returned.
2477 0 otherwise. */
2478 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
2479 if (arglist != 0
2480 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
2481 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
2482 return const0_rtx;
2483 else
2484 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
2485
2486 case BUILT_IN_ALLOCA:
2487 target = expand_builtin_alloca (arglist, target);
2488 if (target)
2489 return target;
2490 break;
2491
2492 case BUILT_IN_FFS:
2493 target = expand_builtin_ffs (arglist, target, subtarget);
2494 if (target)
2495 return target;
2496 break;
2497
2498 case BUILT_IN_STRLEN:
2499 target = expand_builtin_strlen (exp, target, mode);
2500 if (target)
2501 return target;
2502 break;
2503
2504 case BUILT_IN_STRCPY:
2505 target = expand_builtin_strcpy (exp);
2506 if (target)
2507 return target;
2508 break;
2509
2510 case BUILT_IN_MEMCPY:
2511 target = expand_builtin_memcpy (arglist);
2512 if (target)
2513 return target;
2514 break;
2515
2516 case BUILT_IN_MEMSET:
2517 target = expand_builtin_memset (exp);
2518 if (target)
2519 return target;
2520 break;
2521
2522 case BUILT_IN_BZERO:
2523 target = expand_builtin_bzero (exp);
2524 if (target)
2525 return target;
2526 break;
2527
2528 /* These comparison functions need an instruction that returns an actual
2529 index. An ordinary compare that just sets the condition codes
2530 is not enough. */
2531 #ifdef HAVE_cmpstrsi
2532 case BUILT_IN_STRCMP:
2533 target = expand_builtin_strcmp (exp, target);
2534 if (target)
2535 return target;
2536 break;
2537
2538 case BUILT_IN_BCMP:
2539 case BUILT_IN_MEMCMP:
2540 target = expand_builtin_memcmp (exp, arglist, target);
2541 if (target)
2542 return target;
2543 break;
2544 #else
2545 case BUILT_IN_STRCMP:
2546 case BUILT_IN_BCMP:
2547 case BUILT_IN_MEMCMP:
2548 break;
2549 #endif
2550
2551 case BUILT_IN_SETJMP:
2552 if (arglist == 0
2553 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2554 break;
2555 else
2556 {
2557 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2558 VOIDmode, 0);
2559 rtx lab = gen_label_rtx ();
2560 rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
2561 emit_label (lab);
2562 return ret;
2563 }
2564
2565 /* __builtin_longjmp is passed a pointer to an array of five words.
2566 It's similar to the C library longjmp function but works with
2567 __builtin_setjmp above. */
2568 case BUILT_IN_LONGJMP:
2569 if (arglist == 0 || TREE_CHAIN (arglist) == 0
2570 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2571 break;
2572 else
2573 {
2574 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2575 VOIDmode, 0);
2576 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
2577 NULL_RTX, VOIDmode, 0);
2578
2579 if (value != const1_rtx)
2580 {
2581 error ("__builtin_longjmp second argument must be 1");
2582 return const0_rtx;
2583 }
2584
2585 expand_builtin_longjmp (buf_addr, value);
2586 return const0_rtx;
2587 }
2588
2589 case BUILT_IN_TRAP:
2590 #ifdef HAVE_trap
2591 if (HAVE_trap)
2592 emit_insn (gen_trap ());
2593 else
2594 #endif
2595 error ("__builtin_trap not supported by this target");
2596 emit_barrier ();
2597 return const0_rtx;
2598
2599 /* Various hooks for the DWARF 2 __throw routine. */
2600 case BUILT_IN_UNWIND_INIT:
2601 expand_builtin_unwind_init ();
2602 return const0_rtx;
2603 case BUILT_IN_DWARF_CFA:
2604 return virtual_cfa_rtx;
2605 #ifdef DWARF2_UNWIND_INFO
2606 case BUILT_IN_DWARF_FP_REGNUM:
2607 return expand_builtin_dwarf_fp_regnum ();
2608 case BUILT_IN_INIT_DWARF_REG_SIZES:
2609 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
2610 return const0_rtx;
2611 #endif
2612 case BUILT_IN_FROB_RETURN_ADDR:
2613 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
2614 case BUILT_IN_EXTRACT_RETURN_ADDR:
2615 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
2616 case BUILT_IN_EH_RETURN:
2617 expand_builtin_eh_return (TREE_VALUE (arglist),
2618 TREE_VALUE (TREE_CHAIN (arglist)),
2619 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
2620 return const0_rtx;
2621 case BUILT_IN_VARARGS_START:
2622 return expand_builtin_va_start (0, arglist);
2623 case BUILT_IN_STDARG_START:
2624 return expand_builtin_va_start (1, arglist);
2625 case BUILT_IN_VA_END:
2626 return expand_builtin_va_end (arglist);
2627 case BUILT_IN_VA_COPY:
2628 return expand_builtin_va_copy (arglist);
2629 case BUILT_IN_EXPECT:
2630 return expand_builtin_expect (arglist, target);
2631
2632 default: /* just do library call, if unknown builtin */
2633 error ("built-in function `%s' not currently supported",
2634 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
2635 }
2636
2637 /* The switch statement above can drop through to cause the function
2638 to be called normally. */
2639 return expand_call (exp, target, ignore);
2640 }