]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/builtins.c
gcc_release (announce_snapshot): Use changedir instead of plain cd.
[thirdparty/gcc.git] / gcc / builtins.c
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
47
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
50
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
54
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
58
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
60 const char *const built_in_names[(int) END_BUILTINS] =
61 {
62 #include "builtins.def"
63 };
64 #undef DEF_BUILTIN
65
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases. */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
73
74 static int get_pointer_alignment (tree, unsigned int);
75 static tree c_strlen (tree, int);
76 static const char *c_getstr (tree);
77 static rtx c_readstr (const char *, enum machine_mode);
78 static int target_char_cast (tree, char *);
79 static rtx get_memory_rtx (tree);
80 static tree build_string_literal (int, const char *);
81 static int apply_args_size (void);
82 static int apply_result_size (void);
83 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
84 static rtx result_vector (int, rtx);
85 #endif
86 static rtx expand_builtin_setjmp (tree, rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_constant_p (tree, enum machine_mode);
98 static rtx expand_builtin_args_info (tree);
99 static rtx expand_builtin_next_arg (tree);
100 static rtx expand_builtin_va_start (tree);
101 static rtx expand_builtin_va_end (tree);
102 static rtx expand_builtin_va_copy (tree);
103 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
104 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
106 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
107 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
113 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_bcopy (tree);
115 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
117 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
118 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
119 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_bzero (tree);
123 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, rtx);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static rtx expand_builtin_fputs (tree, rtx, bool);
132 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135 static tree stabilize_va_list (tree, int);
136 static rtx expand_builtin_expect (tree, rtx);
137 static tree fold_builtin_constant_p (tree);
138 static tree fold_builtin_classify_type (tree);
139 static tree fold_builtin_inf (tree, int);
140 static tree fold_builtin_nan (tree, tree, int);
141 static int validate_arglist (tree, ...);
142 static bool integer_valued_real_p (tree);
143 static tree fold_trunc_transparent_mathfn (tree);
144 static bool readonly_data_expr (tree);
145 static rtx expand_builtin_fabs (tree, rtx, rtx);
146 static rtx expand_builtin_cabs (tree, rtx);
147 static rtx expand_builtin_signbit (tree, rtx);
148 static tree fold_builtin_cabs (tree, tree, tree);
149 static tree fold_builtin_trunc (tree);
150 static tree fold_builtin_floor (tree);
151 static tree fold_builtin_ceil (tree);
152 static tree fold_builtin_round (tree);
153 static tree fold_builtin_bitop (tree);
154 static tree fold_builtin_memcpy (tree);
155 static tree fold_builtin_mempcpy (tree);
156 static tree fold_builtin_memmove (tree);
157 static tree fold_builtin_strcpy (tree);
158 static tree fold_builtin_strncpy (tree);
159 static tree fold_builtin_memcmp (tree);
160 static tree fold_builtin_strcmp (tree);
161 static tree fold_builtin_strncmp (tree);
162 static tree fold_builtin_signbit (tree);
163
164 /* Return the alignment in bits of EXP, a pointer valued expression.
165 But don't return more than MAX_ALIGN no matter what.
166 The alignment returned is, by default, the alignment of the thing that
167 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
168
169 Otherwise, look at the expression to see if we can do better, i.e., if the
170 expression is actually pointing at an object whose alignment is tighter. */
171
172 static int
173 get_pointer_alignment (tree exp, unsigned int max_align)
174 {
175 unsigned int align, inner;
176
177 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
178 return 0;
179
180 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
181 align = MIN (align, max_align);
182
183 while (1)
184 {
185 switch (TREE_CODE (exp))
186 {
187 case NOP_EXPR:
188 case CONVERT_EXPR:
189 case NON_LVALUE_EXPR:
190 exp = TREE_OPERAND (exp, 0);
191 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
192 return align;
193
194 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
195 align = MIN (inner, max_align);
196 break;
197
198 case PLUS_EXPR:
199 /* If sum of pointer + int, restrict our maximum alignment to that
200 imposed by the integer. If not, we can't do any better than
201 ALIGN. */
202 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
203 return align;
204
205 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
206 & (max_align / BITS_PER_UNIT - 1))
207 != 0)
208 max_align >>= 1;
209
210 exp = TREE_OPERAND (exp, 0);
211 break;
212
213 case ADDR_EXPR:
214 /* See what we are pointing at and look at its alignment. */
215 exp = TREE_OPERAND (exp, 0);
216 if (TREE_CODE (exp) == FUNCTION_DECL)
217 align = FUNCTION_BOUNDARY;
218 else if (DECL_P (exp))
219 align = DECL_ALIGN (exp);
220 #ifdef CONSTANT_ALIGNMENT
221 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
222 align = CONSTANT_ALIGNMENT (exp, align);
223 #endif
224 return MIN (align, max_align);
225
226 default:
227 return align;
228 }
229 }
230 }
231
232 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
233 way, because it could contain a zero byte in the middle.
234 TREE_STRING_LENGTH is the size of the character array, not the string.
235
236 ONLY_VALUE should be nonzero if the result is not going to be emitted
237 into the instruction stream and zero if it is going to be expanded.
238 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
239 is returned, otherwise NULL, since
240 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
241 evaluate the side-effects.
242
243 The value returned is of type `ssizetype'.
244
245 Unfortunately, string_constant can't access the values of const char
246 arrays with initializers, so neither can we do so here. */
247
248 static tree
249 c_strlen (tree src, int only_value)
250 {
251 tree offset_node;
252 HOST_WIDE_INT offset;
253 int max;
254 const char *ptr;
255
256 STRIP_NOPS (src);
257 if (TREE_CODE (src) == COND_EXPR
258 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
259 {
260 tree len1, len2;
261
262 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
263 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
264 if (tree_int_cst_equal (len1, len2))
265 return len1;
266 }
267
268 if (TREE_CODE (src) == COMPOUND_EXPR
269 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
270 return c_strlen (TREE_OPERAND (src, 1), only_value);
271
272 src = string_constant (src, &offset_node);
273 if (src == 0)
274 return 0;
275
276 max = TREE_STRING_LENGTH (src) - 1;
277 ptr = TREE_STRING_POINTER (src);
278
279 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
280 {
281 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
282 compute the offset to the following null if we don't know where to
283 start searching for it. */
284 int i;
285
286 for (i = 0; i < max; i++)
287 if (ptr[i] == 0)
288 return 0;
289
290 /* We don't know the starting offset, but we do know that the string
291 has no internal zero bytes. We can assume that the offset falls
292 within the bounds of the string; otherwise, the programmer deserves
293 what he gets. Subtract the offset from the length of the string,
294 and return that. This would perhaps not be valid if we were dealing
295 with named arrays in addition to literal string constants. */
296
297 return size_diffop (size_int (max), offset_node);
298 }
299
300 /* We have a known offset into the string. Start searching there for
301 a null character if we can represent it as a single HOST_WIDE_INT. */
302 if (offset_node == 0)
303 offset = 0;
304 else if (! host_integerp (offset_node, 0))
305 offset = -1;
306 else
307 offset = tree_low_cst (offset_node, 0);
308
309 /* If the offset is known to be out of bounds, warn, and call strlen at
310 runtime. */
311 if (offset < 0 || offset > max)
312 {
313 warning ("offset outside bounds of constant string");
314 return 0;
315 }
316
317 /* Use strlen to search for the first zero byte. Since any strings
318 constructed with build_string will have nulls appended, we win even
319 if we get handed something like (char[4])"abcd".
320
321 Since OFFSET is our starting index into the string, no further
322 calculation is needed. */
323 return ssize_int (strlen (ptr + offset));
324 }
325
326 /* Return a char pointer for a C string if it is a string constant
327 or sum of string constant and integer constant. */
328
329 static const char *
330 c_getstr (tree src)
331 {
332 tree offset_node;
333
334 src = string_constant (src, &offset_node);
335 if (src == 0)
336 return 0;
337
338 if (offset_node == 0)
339 return TREE_STRING_POINTER (src);
340 else if (!host_integerp (offset_node, 1)
341 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
342 return 0;
343
344 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
345 }
346
347 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
348 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
349
350 static rtx
351 c_readstr (const char *str, enum machine_mode mode)
352 {
353 HOST_WIDE_INT c[2];
354 HOST_WIDE_INT ch;
355 unsigned int i, j;
356
357 if (GET_MODE_CLASS (mode) != MODE_INT)
358 abort ();
359 c[0] = 0;
360 c[1] = 0;
361 ch = 1;
362 for (i = 0; i < GET_MODE_SIZE (mode); i++)
363 {
364 j = i;
365 if (WORDS_BIG_ENDIAN)
366 j = GET_MODE_SIZE (mode) - i - 1;
367 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
368 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
369 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
370 j *= BITS_PER_UNIT;
371 if (j > 2 * HOST_BITS_PER_WIDE_INT)
372 abort ();
373 if (ch)
374 ch = (unsigned char) str[i];
375 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
376 }
377 return immed_double_const (c[0], c[1], mode);
378 }
379
380 /* Cast a target constant CST to target CHAR and if that value fits into
381 host char type, return zero and put that value into variable pointed by
382 P. */
383
384 static int
385 target_char_cast (tree cst, char *p)
386 {
387 unsigned HOST_WIDE_INT val, hostval;
388
389 if (!host_integerp (cst, 1)
390 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
391 return 1;
392
393 val = tree_low_cst (cst, 1);
394 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
395 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
396
397 hostval = val;
398 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
399 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
400
401 if (val != hostval)
402 return 1;
403
404 *p = hostval;
405 return 0;
406 }
407
408 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
409 times to get the address of either a higher stack frame, or a return
410 address located within it (depending on FNDECL_CODE). */
411
412 rtx
413 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
414 rtx tem)
415 {
416 int i;
417
418 /* Some machines need special handling before we can access
419 arbitrary frames. For example, on the sparc, we must first flush
420 all register windows to the stack. */
421 #ifdef SETUP_FRAME_ADDRESSES
422 if (count > 0)
423 SETUP_FRAME_ADDRESSES ();
424 #endif
425
426 /* On the sparc, the return address is not in the frame, it is in a
427 register. There is no way to access it off of the current frame
428 pointer, but it can be accessed off the previous frame pointer by
429 reading the value from the register window save area. */
430 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
431 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
432 count--;
433 #endif
434
435 /* Scan back COUNT frames to the specified frame. */
436 for (i = 0; i < count; i++)
437 {
438 /* Assume the dynamic chain pointer is in the word that the
439 frame address points to, unless otherwise specified. */
440 #ifdef DYNAMIC_CHAIN_ADDRESS
441 tem = DYNAMIC_CHAIN_ADDRESS (tem);
442 #endif
443 tem = memory_address (Pmode, tem);
444 tem = gen_rtx_MEM (Pmode, tem);
445 set_mem_alias_set (tem, get_frame_alias_set ());
446 tem = copy_to_reg (tem);
447 }
448
449 /* For __builtin_frame_address, return what we've got. */
450 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
451 return tem;
452
453 /* For __builtin_return_address, Get the return address from that
454 frame. */
455 #ifdef RETURN_ADDR_RTX
456 tem = RETURN_ADDR_RTX (count, tem);
457 #else
458 tem = memory_address (Pmode,
459 plus_constant (tem, GET_MODE_SIZE (Pmode)));
460 tem = gen_rtx_MEM (Pmode, tem);
461 set_mem_alias_set (tem, get_frame_alias_set ());
462 #endif
463 return tem;
464 }
465
466 /* Alias set used for setjmp buffer. */
467 static HOST_WIDE_INT setjmp_alias_set = -1;
468
469 /* Construct the leading half of a __builtin_setjmp call. Control will
470 return to RECEIVER_LABEL. This is used directly by sjlj exception
471 handling code. */
472
473 void
474 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
475 {
476 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
477 rtx stack_save;
478 rtx mem;
479
480 if (setjmp_alias_set == -1)
481 setjmp_alias_set = new_alias_set ();
482
483 buf_addr = convert_memory_address (Pmode, buf_addr);
484
485 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
486
487 emit_queue ();
488
489 /* We store the frame pointer and the address of receiver_label in
490 the buffer and use the rest of it for the stack save area, which
491 is machine-dependent. */
492
493 mem = gen_rtx_MEM (Pmode, buf_addr);
494 set_mem_alias_set (mem, setjmp_alias_set);
495 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
496
497 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
498 set_mem_alias_set (mem, setjmp_alias_set);
499
500 emit_move_insn (validize_mem (mem),
501 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
502
503 stack_save = gen_rtx_MEM (sa_mode,
504 plus_constant (buf_addr,
505 2 * GET_MODE_SIZE (Pmode)));
506 set_mem_alias_set (stack_save, setjmp_alias_set);
507 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
508
509 /* If there is further processing to do, do it. */
510 #ifdef HAVE_builtin_setjmp_setup
511 if (HAVE_builtin_setjmp_setup)
512 emit_insn (gen_builtin_setjmp_setup (buf_addr));
513 #endif
514
515 /* Tell optimize_save_area_alloca that extra work is going to
516 need to go on during alloca. */
517 current_function_calls_setjmp = 1;
518
519 /* Set this so all the registers get saved in our frame; we need to be
520 able to copy the saved values for any registers from frames we unwind. */
521 current_function_has_nonlocal_label = 1;
522 }
523
524 /* Construct the trailing part of a __builtin_setjmp call.
525 This is used directly by sjlj exception handling code. */
526
527 void
528 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
529 {
530 /* Clobber the FP when we get here, so we have to make sure it's
531 marked as used by this function. */
532 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
533
534 /* Mark the static chain as clobbered here so life information
535 doesn't get messed up for it. */
536 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
537
538 /* Now put in the code to restore the frame pointer, and argument
539 pointer, if needed. The code below is from expand_end_bindings
540 in stmt.c; see detailed documentation there. */
541 #ifdef HAVE_nonlocal_goto
542 if (! HAVE_nonlocal_goto)
543 #endif
544 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
545
546 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
547 if (fixed_regs[ARG_POINTER_REGNUM])
548 {
549 #ifdef ELIMINABLE_REGS
550 size_t i;
551 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
552
553 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
554 if (elim_regs[i].from == ARG_POINTER_REGNUM
555 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
556 break;
557
558 if (i == ARRAY_SIZE (elim_regs))
559 #endif
560 {
561 /* Now restore our arg pointer from the address at which it
562 was saved in our stack frame. */
563 emit_move_insn (virtual_incoming_args_rtx,
564 copy_to_reg (get_arg_pointer_save_area (cfun)));
565 }
566 }
567 #endif
568
569 #ifdef HAVE_builtin_setjmp_receiver
570 if (HAVE_builtin_setjmp_receiver)
571 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
572 else
573 #endif
574 #ifdef HAVE_nonlocal_goto_receiver
575 if (HAVE_nonlocal_goto_receiver)
576 emit_insn (gen_nonlocal_goto_receiver ());
577 else
578 #endif
579 { /* Nothing */ }
580
581 /* @@@ This is a kludge. Not all machine descriptions define a blockage
582 insn, but we must not allow the code we just generated to be reordered
583 by scheduling. Specifically, the update of the frame pointer must
584 happen immediately, not later. So emit an ASM_INPUT to act as blockage
585 insn. */
586 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
587 }
588
589 /* __builtin_setjmp is passed a pointer to an array of five words (not
590 all will be used on all machines). It operates similarly to the C
591 library function of the same name, but is more efficient. Much of
592 the code below (and for longjmp) is copied from the handling of
593 non-local gotos.
594
595 NOTE: This is intended for use by GNAT and the exception handling
596 scheme in the compiler and will only work in the method used by
597 them. */
598
599 static rtx
600 expand_builtin_setjmp (tree arglist, rtx target)
601 {
602 rtx buf_addr, next_lab, cont_lab;
603
604 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
605 return NULL_RTX;
606
607 if (target == 0 || GET_CODE (target) != REG
608 || REGNO (target) < FIRST_PSEUDO_REGISTER)
609 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
610
611 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
612
613 next_lab = gen_label_rtx ();
614 cont_lab = gen_label_rtx ();
615
616 expand_builtin_setjmp_setup (buf_addr, next_lab);
617
618 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
619 ensure that pending stack adjustments are flushed. */
620 emit_move_insn (target, const0_rtx);
621 emit_jump (cont_lab);
622
623 emit_label (next_lab);
624
625 expand_builtin_setjmp_receiver (next_lab);
626
627 /* Set TARGET to one. */
628 emit_move_insn (target, const1_rtx);
629 emit_label (cont_lab);
630
631 /* Tell flow about the strange goings on. Putting `next_lab' on
632 `nonlocal_goto_handler_labels' to indicates that function
633 calls may traverse the arc back to this label. */
634
635 current_function_has_nonlocal_label = 1;
636 nonlocal_goto_handler_labels
637 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
638
639 return target;
640 }
641
642 /* __builtin_longjmp is passed a pointer to an array of five words (not
643 all will be used on all machines). It operates similarly to the C
644 library function of the same name, but is more efficient. Much of
645 the code below is copied from the handling of non-local gotos.
646
647 NOTE: This is intended for use by GNAT and the exception handling
648 scheme in the compiler and will only work in the method used by
649 them. */
650
651 void
652 expand_builtin_longjmp (rtx buf_addr, rtx value)
653 {
654 rtx fp, lab, stack, insn, last;
655 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
656
657 if (setjmp_alias_set == -1)
658 setjmp_alias_set = new_alias_set ();
659
660 buf_addr = convert_memory_address (Pmode, buf_addr);
661
662 buf_addr = force_reg (Pmode, buf_addr);
663
664 /* We used to store value in static_chain_rtx, but that fails if pointers
665 are smaller than integers. We instead require that the user must pass
666 a second argument of 1, because that is what builtin_setjmp will
667 return. This also makes EH slightly more efficient, since we are no
668 longer copying around a value that we don't care about. */
669 if (value != const1_rtx)
670 abort ();
671
672 current_function_calls_longjmp = 1;
673
674 last = get_last_insn ();
675 #ifdef HAVE_builtin_longjmp
676 if (HAVE_builtin_longjmp)
677 emit_insn (gen_builtin_longjmp (buf_addr));
678 else
679 #endif
680 {
681 fp = gen_rtx_MEM (Pmode, buf_addr);
682 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
683 GET_MODE_SIZE (Pmode)));
684
685 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
686 2 * GET_MODE_SIZE (Pmode)));
687 set_mem_alias_set (fp, setjmp_alias_set);
688 set_mem_alias_set (lab, setjmp_alias_set);
689 set_mem_alias_set (stack, setjmp_alias_set);
690
691 /* Pick up FP, label, and SP from the block and jump. This code is
692 from expand_goto in stmt.c; see there for detailed comments. */
693 #if HAVE_nonlocal_goto
694 if (HAVE_nonlocal_goto)
695 /* We have to pass a value to the nonlocal_goto pattern that will
696 get copied into the static_chain pointer, but it does not matter
697 what that value is, because builtin_setjmp does not use it. */
698 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
699 else
700 #endif
701 {
702 lab = copy_to_reg (lab);
703
704 emit_insn (gen_rtx_CLOBBER (VOIDmode,
705 gen_rtx_MEM (BLKmode,
706 gen_rtx_SCRATCH (VOIDmode))));
707 emit_insn (gen_rtx_CLOBBER (VOIDmode,
708 gen_rtx_MEM (BLKmode,
709 hard_frame_pointer_rtx)));
710
711 emit_move_insn (hard_frame_pointer_rtx, fp);
712 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
713
714 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
715 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
716 emit_indirect_jump (lab);
717 }
718 }
719
720 /* Search backwards and mark the jump insn as a non-local goto.
721 Note that this precludes the use of __builtin_longjmp to a
722 __builtin_setjmp target in the same function. However, we've
723 already cautioned the user that these functions are for
724 internal exception handling use only. */
725 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
726 {
727 if (insn == last)
728 abort ();
729 if (GET_CODE (insn) == JUMP_INSN)
730 {
731 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
732 REG_NOTES (insn));
733 break;
734 }
735 else if (GET_CODE (insn) == CALL_INSN)
736 break;
737 }
738 }
739
740 /* Expand a call to __builtin_prefetch. For a target that does not support
741 data prefetch, evaluate the memory address argument in case it has side
742 effects. */
743
744 static void
745 expand_builtin_prefetch (tree arglist)
746 {
747 tree arg0, arg1, arg2;
748 rtx op0, op1, op2;
749
750 if (!validate_arglist (arglist, POINTER_TYPE, 0))
751 return;
752
753 arg0 = TREE_VALUE (arglist);
754 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
755 zero (read) and argument 2 (locality) defaults to 3 (high degree of
756 locality). */
757 if (TREE_CHAIN (arglist))
758 {
759 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
760 if (TREE_CHAIN (TREE_CHAIN (arglist)))
761 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
762 else
763 arg2 = build_int_2 (3, 0);
764 }
765 else
766 {
767 arg1 = integer_zero_node;
768 arg2 = build_int_2 (3, 0);
769 }
770
771 /* Argument 0 is an address. */
772 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
773
774 /* Argument 1 (read/write flag) must be a compile-time constant int. */
775 if (TREE_CODE (arg1) != INTEGER_CST)
776 {
777 error ("second arg to `__builtin_prefetch' must be a constant");
778 arg1 = integer_zero_node;
779 }
780 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
781 /* Argument 1 must be either zero or one. */
782 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
783 {
784 warning ("invalid second arg to __builtin_prefetch; using zero");
785 op1 = const0_rtx;
786 }
787
788 /* Argument 2 (locality) must be a compile-time constant int. */
789 if (TREE_CODE (arg2) != INTEGER_CST)
790 {
791 error ("third arg to `__builtin_prefetch' must be a constant");
792 arg2 = integer_zero_node;
793 }
794 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
795 /* Argument 2 must be 0, 1, 2, or 3. */
796 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
797 {
798 warning ("invalid third arg to __builtin_prefetch; using zero");
799 op2 = const0_rtx;
800 }
801
802 #ifdef HAVE_prefetch
803 if (HAVE_prefetch)
804 {
805 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
806 (op0,
807 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
808 || (GET_MODE (op0) != Pmode))
809 {
810 op0 = convert_memory_address (Pmode, op0);
811 op0 = force_reg (Pmode, op0);
812 }
813 emit_insn (gen_prefetch (op0, op1, op2));
814 }
815 else
816 #endif
817 op0 = protect_from_queue (op0, 0);
818 /* Don't do anything with direct references to volatile memory, but
819 generate code to handle other side effects. */
820 if (GET_CODE (op0) != MEM && side_effects_p (op0))
821 emit_insn (op0);
822 }
823
824 /* Get a MEM rtx for expression EXP which is the address of an operand
825 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
826
827 static rtx
828 get_memory_rtx (tree exp)
829 {
830 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
831 rtx mem;
832
833 addr = convert_memory_address (Pmode, addr);
834
835 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
836
837 /* Get an expression we can use to find the attributes to assign to MEM.
838 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
839 we can. First remove any nops. */
840 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
841 || TREE_CODE (exp) == NON_LVALUE_EXPR)
842 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
843 exp = TREE_OPERAND (exp, 0);
844
845 if (TREE_CODE (exp) == ADDR_EXPR)
846 {
847 exp = TREE_OPERAND (exp, 0);
848 set_mem_attributes (mem, exp, 0);
849 }
850 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
851 {
852 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
853 /* memcpy, memset and other builtin stringops can alias with anything. */
854 set_mem_alias_set (mem, 0);
855 }
856
857 return mem;
858 }
859 \f
860 /* Built-in functions to perform an untyped call and return. */
861
862 /* For each register that may be used for calling a function, this
863 gives a mode used to copy the register's value. VOIDmode indicates
864 the register is not used for calling a function. If the machine
865 has register windows, this gives only the outbound registers.
866 INCOMING_REGNO gives the corresponding inbound register. */
867 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
868
869 /* For each register that may be used for returning values, this gives
870 a mode used to copy the register's value. VOIDmode indicates the
871 register is not used for returning values. If the machine has
872 register windows, this gives only the outbound registers.
873 INCOMING_REGNO gives the corresponding inbound register. */
874 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
875
876 /* For each register that may be used for calling a function, this
877 gives the offset of that register into the block returned by
878 __builtin_apply_args. 0 indicates that the register is not
879 used for calling a function. */
880 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
881
882 /* Return the size required for the block returned by __builtin_apply_args,
883 and initialize apply_args_mode. */
884
885 static int
886 apply_args_size (void)
887 {
888 static int size = -1;
889 int align;
890 unsigned int regno;
891 enum machine_mode mode;
892
893 /* The values computed by this function never change. */
894 if (size < 0)
895 {
896 /* The first value is the incoming arg-pointer. */
897 size = GET_MODE_SIZE (Pmode);
898
899 /* The second value is the structure value address unless this is
900 passed as an "invisible" first argument. */
901 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
902 size += GET_MODE_SIZE (Pmode);
903
904 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
905 if (FUNCTION_ARG_REGNO_P (regno))
906 {
907 /* Search for the proper mode for copying this register's
908 value. I'm not sure this is right, but it works so far. */
909 enum machine_mode best_mode = VOIDmode;
910
911 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
912 mode != VOIDmode;
913 mode = GET_MODE_WIDER_MODE (mode))
914 if (HARD_REGNO_MODE_OK (regno, mode)
915 && hard_regno_nregs[regno][mode] == 1)
916 best_mode = mode;
917
918 if (best_mode == VOIDmode)
919 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
920 mode != VOIDmode;
921 mode = GET_MODE_WIDER_MODE (mode))
922 if (HARD_REGNO_MODE_OK (regno, mode)
923 && have_insn_for (SET, mode))
924 best_mode = mode;
925
926 if (best_mode == VOIDmode)
927 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
928 mode != VOIDmode;
929 mode = GET_MODE_WIDER_MODE (mode))
930 if (HARD_REGNO_MODE_OK (regno, mode)
931 && have_insn_for (SET, mode))
932 best_mode = mode;
933
934 if (best_mode == VOIDmode)
935 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
936 mode != VOIDmode;
937 mode = GET_MODE_WIDER_MODE (mode))
938 if (HARD_REGNO_MODE_OK (regno, mode)
939 && have_insn_for (SET, mode))
940 best_mode = mode;
941
942 mode = best_mode;
943 if (mode == VOIDmode)
944 abort ();
945
946 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
947 if (size % align != 0)
948 size = CEIL (size, align) * align;
949 apply_args_reg_offset[regno] = size;
950 size += GET_MODE_SIZE (mode);
951 apply_args_mode[regno] = mode;
952 }
953 else
954 {
955 apply_args_mode[regno] = VOIDmode;
956 apply_args_reg_offset[regno] = 0;
957 }
958 }
959 return size;
960 }
961
962 /* Return the size required for the block returned by __builtin_apply,
963 and initialize apply_result_mode. */
964
965 static int
966 apply_result_size (void)
967 {
968 static int size = -1;
969 int align, regno;
970 enum machine_mode mode;
971
972 /* The values computed by this function never change. */
973 if (size < 0)
974 {
975 size = 0;
976
977 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
978 if (FUNCTION_VALUE_REGNO_P (regno))
979 {
980 /* Search for the proper mode for copying this register's
981 value. I'm not sure this is right, but it works so far. */
982 enum machine_mode best_mode = VOIDmode;
983
984 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
985 mode != TImode;
986 mode = GET_MODE_WIDER_MODE (mode))
987 if (HARD_REGNO_MODE_OK (regno, mode))
988 best_mode = mode;
989
990 if (best_mode == VOIDmode)
991 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
992 mode != VOIDmode;
993 mode = GET_MODE_WIDER_MODE (mode))
994 if (HARD_REGNO_MODE_OK (regno, mode)
995 && have_insn_for (SET, mode))
996 best_mode = mode;
997
998 if (best_mode == VOIDmode)
999 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1000 mode != VOIDmode;
1001 mode = GET_MODE_WIDER_MODE (mode))
1002 if (HARD_REGNO_MODE_OK (regno, mode)
1003 && have_insn_for (SET, mode))
1004 best_mode = mode;
1005
1006 if (best_mode == VOIDmode)
1007 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1008 mode != VOIDmode;
1009 mode = GET_MODE_WIDER_MODE (mode))
1010 if (HARD_REGNO_MODE_OK (regno, mode)
1011 && have_insn_for (SET, mode))
1012 best_mode = mode;
1013
1014 mode = best_mode;
1015 if (mode == VOIDmode)
1016 abort ();
1017
1018 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1019 if (size % align != 0)
1020 size = CEIL (size, align) * align;
1021 size += GET_MODE_SIZE (mode);
1022 apply_result_mode[regno] = mode;
1023 }
1024 else
1025 apply_result_mode[regno] = VOIDmode;
1026
1027 /* Allow targets that use untyped_call and untyped_return to override
1028 the size so that machine-specific information can be stored here. */
1029 #ifdef APPLY_RESULT_SIZE
1030 size = APPLY_RESULT_SIZE;
1031 #endif
1032 }
1033 return size;
1034 }
1035
1036 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1037 /* Create a vector describing the result block RESULT. If SAVEP is true,
1038 the result block is used to save the values; otherwise it is used to
1039 restore the values. */
1040
1041 static rtx
1042 result_vector (int savep, rtx result)
1043 {
1044 int regno, size, align, nelts;
1045 enum machine_mode mode;
1046 rtx reg, mem;
1047 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1048
1049 size = nelts = 0;
1050 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1051 if ((mode = apply_result_mode[regno]) != VOIDmode)
1052 {
1053 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1054 if (size % align != 0)
1055 size = CEIL (size, align) * align;
1056 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1057 mem = adjust_address (result, mode, size);
1058 savevec[nelts++] = (savep
1059 ? gen_rtx_SET (VOIDmode, mem, reg)
1060 : gen_rtx_SET (VOIDmode, reg, mem));
1061 size += GET_MODE_SIZE (mode);
1062 }
1063 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1064 }
1065 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1066
1067 /* Save the state required to perform an untyped call with the same
1068 arguments as were passed to the current function. */
1069
1070 static rtx
1071 expand_builtin_apply_args_1 (void)
1072 {
1073 rtx registers, tem;
1074 int size, align, regno;
1075 enum machine_mode mode;
1076 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1077
1078 /* Create a block where the arg-pointer, structure value address,
1079 and argument registers can be saved. */
1080 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1081
1082 /* Walk past the arg-pointer and structure value address. */
1083 size = GET_MODE_SIZE (Pmode);
1084 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1085 size += GET_MODE_SIZE (Pmode);
1086
1087 /* Save each register used in calling a function to the block. */
1088 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1089 if ((mode = apply_args_mode[regno]) != VOIDmode)
1090 {
1091 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1092 if (size % align != 0)
1093 size = CEIL (size, align) * align;
1094
1095 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1096
1097 emit_move_insn (adjust_address (registers, mode, size), tem);
1098 size += GET_MODE_SIZE (mode);
1099 }
1100
1101 /* Save the arg pointer to the block. */
1102 tem = copy_to_reg (virtual_incoming_args_rtx);
1103 #ifdef STACK_GROWS_DOWNWARD
1104 /* We need the pointer as the caller actually passed them to us, not
1105 as we might have pretended they were passed. Make sure it's a valid
1106 operand, as emit_move_insn isn't expected to handle a PLUS. */
1107 tem
1108 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1109 NULL_RTX);
1110 #endif
1111 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1112
1113 size = GET_MODE_SIZE (Pmode);
1114
1115 /* Save the structure value address unless this is passed as an
1116 "invisible" first argument. */
1117 if (struct_incoming_value)
1118 {
1119 emit_move_insn (adjust_address (registers, Pmode, size),
1120 copy_to_reg (struct_incoming_value));
1121 size += GET_MODE_SIZE (Pmode);
1122 }
1123
1124 /* Return the address of the block. */
1125 return copy_addr_to_reg (XEXP (registers, 0));
1126 }
1127
1128 /* __builtin_apply_args returns block of memory allocated on
1129 the stack into which is stored the arg pointer, structure
1130 value address, static chain, and all the registers that might
1131 possibly be used in performing a function call. The code is
1132 moved to the start of the function so the incoming values are
1133 saved. */
1134
1135 static rtx
1136 expand_builtin_apply_args (void)
1137 {
1138 /* Don't do __builtin_apply_args more than once in a function.
1139 Save the result of the first call and reuse it. */
1140 if (apply_args_value != 0)
1141 return apply_args_value;
1142 {
1143 /* When this function is called, it means that registers must be
1144 saved on entry to this function. So we migrate the
1145 call to the first insn of this function. */
1146 rtx temp;
1147 rtx seq;
1148
1149 start_sequence ();
1150 temp = expand_builtin_apply_args_1 ();
1151 seq = get_insns ();
1152 end_sequence ();
1153
1154 apply_args_value = temp;
1155
1156 /* Put the insns after the NOTE that starts the function.
1157 If this is inside a start_sequence, make the outer-level insn
1158 chain current, so the code is placed at the start of the
1159 function. */
1160 push_topmost_sequence ();
1161 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1162 pop_topmost_sequence ();
1163 return temp;
1164 }
1165 }
1166
1167 /* Perform an untyped call and save the state required to perform an
1168 untyped return of whatever value was returned by the given function. */
1169
1170 static rtx
1171 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1172 {
1173 int size, align, regno;
1174 enum machine_mode mode;
1175 rtx incoming_args, result, reg, dest, src, call_insn;
1176 rtx old_stack_level = 0;
1177 rtx call_fusage = 0;
1178 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1179
1180 arguments = convert_memory_address (Pmode, arguments);
1181
1182 /* Create a block where the return registers can be saved. */
1183 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1184
1185 /* Fetch the arg pointer from the ARGUMENTS block. */
1186 incoming_args = gen_reg_rtx (Pmode);
1187 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1188 #ifndef STACK_GROWS_DOWNWARD
1189 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1190 incoming_args, 0, OPTAB_LIB_WIDEN);
1191 #endif
1192
1193 /* Perform postincrements before actually calling the function. */
1194 emit_queue ();
1195
1196 /* Push a new argument block and copy the arguments. Do not allow
1197 the (potential) memcpy call below to interfere with our stack
1198 manipulations. */
1199 do_pending_stack_adjust ();
1200 NO_DEFER_POP;
1201
1202 /* Save the stack with nonlocal if available. */
1203 #ifdef HAVE_save_stack_nonlocal
1204 if (HAVE_save_stack_nonlocal)
1205 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1206 else
1207 #endif
1208 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1209
1210 /* Allocate a block of memory onto the stack and copy the memory
1211 arguments to the outgoing arguments address. */
1212 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1213 dest = virtual_outgoing_args_rtx;
1214 #ifndef STACK_GROWS_DOWNWARD
1215 if (GET_CODE (argsize) == CONST_INT)
1216 dest = plus_constant (dest, -INTVAL (argsize));
1217 else
1218 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1219 #endif
1220 dest = gen_rtx_MEM (BLKmode, dest);
1221 set_mem_align (dest, PARM_BOUNDARY);
1222 src = gen_rtx_MEM (BLKmode, incoming_args);
1223 set_mem_align (src, PARM_BOUNDARY);
1224 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1225
1226 /* Refer to the argument block. */
1227 apply_args_size ();
1228 arguments = gen_rtx_MEM (BLKmode, arguments);
1229 set_mem_align (arguments, PARM_BOUNDARY);
1230
1231 /* Walk past the arg-pointer and structure value address. */
1232 size = GET_MODE_SIZE (Pmode);
1233 if (struct_value)
1234 size += GET_MODE_SIZE (Pmode);
1235
1236 /* Restore each of the registers previously saved. Make USE insns
1237 for each of these registers for use in making the call. */
1238 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1239 if ((mode = apply_args_mode[regno]) != VOIDmode)
1240 {
1241 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1242 if (size % align != 0)
1243 size = CEIL (size, align) * align;
1244 reg = gen_rtx_REG (mode, regno);
1245 emit_move_insn (reg, adjust_address (arguments, mode, size));
1246 use_reg (&call_fusage, reg);
1247 size += GET_MODE_SIZE (mode);
1248 }
1249
1250 /* Restore the structure value address unless this is passed as an
1251 "invisible" first argument. */
1252 size = GET_MODE_SIZE (Pmode);
1253 if (struct_value)
1254 {
1255 rtx value = gen_reg_rtx (Pmode);
1256 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1257 emit_move_insn (struct_value, value);
1258 if (GET_CODE (struct_value) == REG)
1259 use_reg (&call_fusage, struct_value);
1260 size += GET_MODE_SIZE (Pmode);
1261 }
1262
1263 /* All arguments and registers used for the call are set up by now! */
1264 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1265
1266 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1267 and we don't want to load it into a register as an optimization,
1268 because prepare_call_address already did it if it should be done. */
1269 if (GET_CODE (function) != SYMBOL_REF)
1270 function = memory_address (FUNCTION_MODE, function);
1271
1272 /* Generate the actual call instruction and save the return value. */
1273 #ifdef HAVE_untyped_call
1274 if (HAVE_untyped_call)
1275 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1276 result, result_vector (1, result)));
1277 else
1278 #endif
1279 #ifdef HAVE_call_value
1280 if (HAVE_call_value)
1281 {
1282 rtx valreg = 0;
1283
1284 /* Locate the unique return register. It is not possible to
1285 express a call that sets more than one return register using
1286 call_value; use untyped_call for that. In fact, untyped_call
1287 only needs to save the return registers in the given block. */
1288 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1289 if ((mode = apply_result_mode[regno]) != VOIDmode)
1290 {
1291 if (valreg)
1292 abort (); /* HAVE_untyped_call required. */
1293 valreg = gen_rtx_REG (mode, regno);
1294 }
1295
1296 emit_call_insn (GEN_CALL_VALUE (valreg,
1297 gen_rtx_MEM (FUNCTION_MODE, function),
1298 const0_rtx, NULL_RTX, const0_rtx));
1299
1300 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1301 }
1302 else
1303 #endif
1304 abort ();
1305
1306 /* Find the CALL insn we just emitted, and attach the register usage
1307 information. */
1308 call_insn = last_call_insn ();
1309 add_function_usage_to (call_insn, call_fusage);
1310
1311 /* Restore the stack. */
1312 #ifdef HAVE_save_stack_nonlocal
1313 if (HAVE_save_stack_nonlocal)
1314 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1315 else
1316 #endif
1317 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1318
1319 OK_DEFER_POP;
1320
1321 /* Return the address of the result block. */
1322 result = copy_addr_to_reg (XEXP (result, 0));
1323 return convert_memory_address (ptr_mode, result);
1324 }
1325
1326 /* Perform an untyped return. */
1327
1328 static void
1329 expand_builtin_return (rtx result)
1330 {
1331 int size, align, regno;
1332 enum machine_mode mode;
1333 rtx reg;
1334 rtx call_fusage = 0;
1335
1336 result = convert_memory_address (Pmode, result);
1337
1338 apply_result_size ();
1339 result = gen_rtx_MEM (BLKmode, result);
1340
1341 #ifdef HAVE_untyped_return
1342 if (HAVE_untyped_return)
1343 {
1344 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1345 emit_barrier ();
1346 return;
1347 }
1348 #endif
1349
1350 /* Restore the return value and note that each value is used. */
1351 size = 0;
1352 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1353 if ((mode = apply_result_mode[regno]) != VOIDmode)
1354 {
1355 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1356 if (size % align != 0)
1357 size = CEIL (size, align) * align;
1358 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1359 emit_move_insn (reg, adjust_address (result, mode, size));
1360
1361 push_to_sequence (call_fusage);
1362 emit_insn (gen_rtx_USE (VOIDmode, reg));
1363 call_fusage = get_insns ();
1364 end_sequence ();
1365 size += GET_MODE_SIZE (mode);
1366 }
1367
1368 /* Put the USE insns before the return. */
1369 emit_insn (call_fusage);
1370
1371 /* Return whatever values was restored by jumping directly to the end
1372 of the function. */
1373 expand_naked_return ();
1374 }
1375
1376 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1377
1378 static enum type_class
1379 type_to_class (tree type)
1380 {
1381 switch (TREE_CODE (type))
1382 {
1383 case VOID_TYPE: return void_type_class;
1384 case INTEGER_TYPE: return integer_type_class;
1385 case CHAR_TYPE: return char_type_class;
1386 case ENUMERAL_TYPE: return enumeral_type_class;
1387 case BOOLEAN_TYPE: return boolean_type_class;
1388 case POINTER_TYPE: return pointer_type_class;
1389 case REFERENCE_TYPE: return reference_type_class;
1390 case OFFSET_TYPE: return offset_type_class;
1391 case REAL_TYPE: return real_type_class;
1392 case COMPLEX_TYPE: return complex_type_class;
1393 case FUNCTION_TYPE: return function_type_class;
1394 case METHOD_TYPE: return method_type_class;
1395 case RECORD_TYPE: return record_type_class;
1396 case UNION_TYPE:
1397 case QUAL_UNION_TYPE: return union_type_class;
1398 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1399 ? string_type_class : array_type_class);
1400 case SET_TYPE: return set_type_class;
1401 case FILE_TYPE: return file_type_class;
1402 case LANG_TYPE: return lang_type_class;
1403 default: return no_type_class;
1404 }
1405 }
1406
1407 /* Expand a call to __builtin_classify_type with arguments found in
1408 ARGLIST. */
1409
1410 static rtx
1411 expand_builtin_classify_type (tree arglist)
1412 {
1413 if (arglist != 0)
1414 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1415 return GEN_INT (no_type_class);
1416 }
1417
1418 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1419
1420 static rtx
1421 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1422 {
1423 rtx tmp;
1424
1425 if (arglist == 0)
1426 return const0_rtx;
1427 arglist = TREE_VALUE (arglist);
1428
1429 /* We have taken care of the easy cases during constant folding. This
1430 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1431 get a chance to see if it can deduce whether ARGLIST is constant.
1432 If CSE isn't going to run, of course, don't bother waiting. */
1433
1434 if (cse_not_expected)
1435 return const0_rtx;
1436
1437 current_function_calls_constant_p = 1;
1438
1439 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1440 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1441 return tmp;
1442 }
1443
1444 /* This helper macro, meant to be used in mathfn_built_in below,
1445 determines which among a set of three builtin math functions is
1446 appropriate for a given type mode. The `F' and `L' cases are
1447 automatically generated from the `double' case. */
1448 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1449 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1450 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1451 fcodel = BUILT_IN_MATHFN##L ; break;
1452
1453 /* Return mathematic function equivalent to FN but operating directly
1454 on TYPE, if available. If we can't do the conversion, return zero. */
1455 tree
1456 mathfn_built_in (tree type, enum built_in_function fn)
1457 {
1458 const enum machine_mode type_mode = TYPE_MODE (type);
1459 enum built_in_function fcode, fcodef, fcodel;
1460
1461 switch (fn)
1462 {
1463 CASE_MATHFN (BUILT_IN_ACOS)
1464 CASE_MATHFN (BUILT_IN_ACOSH)
1465 CASE_MATHFN (BUILT_IN_ASIN)
1466 CASE_MATHFN (BUILT_IN_ASINH)
1467 CASE_MATHFN (BUILT_IN_ATAN)
1468 CASE_MATHFN (BUILT_IN_ATAN2)
1469 CASE_MATHFN (BUILT_IN_ATANH)
1470 CASE_MATHFN (BUILT_IN_CBRT)
1471 CASE_MATHFN (BUILT_IN_CEIL)
1472 CASE_MATHFN (BUILT_IN_COPYSIGN)
1473 CASE_MATHFN (BUILT_IN_COS)
1474 CASE_MATHFN (BUILT_IN_COSH)
1475 CASE_MATHFN (BUILT_IN_DREM)
1476 CASE_MATHFN (BUILT_IN_ERF)
1477 CASE_MATHFN (BUILT_IN_ERFC)
1478 CASE_MATHFN (BUILT_IN_EXP)
1479 CASE_MATHFN (BUILT_IN_EXP10)
1480 CASE_MATHFN (BUILT_IN_EXP2)
1481 CASE_MATHFN (BUILT_IN_EXPM1)
1482 CASE_MATHFN (BUILT_IN_FABS)
1483 CASE_MATHFN (BUILT_IN_FDIM)
1484 CASE_MATHFN (BUILT_IN_FLOOR)
1485 CASE_MATHFN (BUILT_IN_FMA)
1486 CASE_MATHFN (BUILT_IN_FMAX)
1487 CASE_MATHFN (BUILT_IN_FMIN)
1488 CASE_MATHFN (BUILT_IN_FMOD)
1489 CASE_MATHFN (BUILT_IN_FREXP)
1490 CASE_MATHFN (BUILT_IN_GAMMA)
1491 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1492 CASE_MATHFN (BUILT_IN_HYPOT)
1493 CASE_MATHFN (BUILT_IN_ILOGB)
1494 CASE_MATHFN (BUILT_IN_INF)
1495 CASE_MATHFN (BUILT_IN_J0)
1496 CASE_MATHFN (BUILT_IN_J1)
1497 CASE_MATHFN (BUILT_IN_JN)
1498 CASE_MATHFN (BUILT_IN_LDEXP)
1499 CASE_MATHFN (BUILT_IN_LGAMMA)
1500 CASE_MATHFN (BUILT_IN_LLRINT)
1501 CASE_MATHFN (BUILT_IN_LLROUND)
1502 CASE_MATHFN (BUILT_IN_LOG)
1503 CASE_MATHFN (BUILT_IN_LOG10)
1504 CASE_MATHFN (BUILT_IN_LOG1P)
1505 CASE_MATHFN (BUILT_IN_LOG2)
1506 CASE_MATHFN (BUILT_IN_LOGB)
1507 CASE_MATHFN (BUILT_IN_LRINT)
1508 CASE_MATHFN (BUILT_IN_LROUND)
1509 CASE_MATHFN (BUILT_IN_MODF)
1510 CASE_MATHFN (BUILT_IN_NAN)
1511 CASE_MATHFN (BUILT_IN_NANS)
1512 CASE_MATHFN (BUILT_IN_NEARBYINT)
1513 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1514 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1515 CASE_MATHFN (BUILT_IN_POW)
1516 CASE_MATHFN (BUILT_IN_POW10)
1517 CASE_MATHFN (BUILT_IN_REMAINDER)
1518 CASE_MATHFN (BUILT_IN_REMQUO)
1519 CASE_MATHFN (BUILT_IN_RINT)
1520 CASE_MATHFN (BUILT_IN_ROUND)
1521 CASE_MATHFN (BUILT_IN_SCALB)
1522 CASE_MATHFN (BUILT_IN_SCALBLN)
1523 CASE_MATHFN (BUILT_IN_SCALBN)
1524 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1525 CASE_MATHFN (BUILT_IN_SIN)
1526 CASE_MATHFN (BUILT_IN_SINCOS)
1527 CASE_MATHFN (BUILT_IN_SINH)
1528 CASE_MATHFN (BUILT_IN_SQRT)
1529 CASE_MATHFN (BUILT_IN_TAN)
1530 CASE_MATHFN (BUILT_IN_TANH)
1531 CASE_MATHFN (BUILT_IN_TGAMMA)
1532 CASE_MATHFN (BUILT_IN_TRUNC)
1533 CASE_MATHFN (BUILT_IN_Y0)
1534 CASE_MATHFN (BUILT_IN_Y1)
1535 CASE_MATHFN (BUILT_IN_YN)
1536
1537 default:
1538 return 0;
1539 }
1540
1541 if (type_mode == TYPE_MODE (double_type_node))
1542 return implicit_built_in_decls[fcode];
1543 else if (type_mode == TYPE_MODE (float_type_node))
1544 return implicit_built_in_decls[fcodef];
1545 else if (type_mode == TYPE_MODE (long_double_type_node))
1546 return implicit_built_in_decls[fcodel];
1547 else
1548 return 0;
1549 }
1550
1551 /* If errno must be maintained, expand the RTL to check if the result,
1552 TARGET, of a built-in function call, EXP, is NaN, and if so set
1553 errno to EDOM. */
1554
1555 static void
1556 expand_errno_check (tree exp, rtx target)
1557 {
1558 rtx lab = gen_label_rtx ();
1559
1560 /* Test the result; if it is NaN, set errno=EDOM because
1561 the argument was not in the domain. */
1562 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1563 0, lab);
1564
1565 #ifdef TARGET_EDOM
1566 /* If this built-in doesn't throw an exception, set errno directly. */
1567 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1568 {
1569 #ifdef GEN_ERRNO_RTX
1570 rtx errno_rtx = GEN_ERRNO_RTX;
1571 #else
1572 rtx errno_rtx
1573 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1574 #endif
1575 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1576 emit_label (lab);
1577 return;
1578 }
1579 #endif
1580
1581 /* We can't set errno=EDOM directly; let the library call do it.
1582 Pop the arguments right away in case the call gets deleted. */
1583 NO_DEFER_POP;
1584 expand_call (exp, target, 0);
1585 OK_DEFER_POP;
1586 emit_label (lab);
1587 }
1588
1589
1590 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1591 Return 0 if a normal call should be emitted rather than expanding the
1592 function in-line. EXP is the expression that is a call to the builtin
1593 function; if convenient, the result should be placed in TARGET.
1594 SUBTARGET may be used as the target for computing one of EXP's operands. */
1595
1596 static rtx
1597 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1598 {
1599 optab builtin_optab;
1600 rtx op0, insns, before_call;
1601 tree fndecl = get_callee_fndecl (exp);
1602 tree arglist = TREE_OPERAND (exp, 1);
1603 enum machine_mode mode;
1604 bool errno_set = false;
1605 tree arg, narg;
1606
1607 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1608 return 0;
1609
1610 arg = TREE_VALUE (arglist);
1611
1612 switch (DECL_FUNCTION_CODE (fndecl))
1613 {
1614 case BUILT_IN_SIN:
1615 case BUILT_IN_SINF:
1616 case BUILT_IN_SINL:
1617 builtin_optab = sin_optab; break;
1618 case BUILT_IN_COS:
1619 case BUILT_IN_COSF:
1620 case BUILT_IN_COSL:
1621 builtin_optab = cos_optab; break;
1622 case BUILT_IN_SQRT:
1623 case BUILT_IN_SQRTF:
1624 case BUILT_IN_SQRTL:
1625 errno_set = ! tree_expr_nonnegative_p (arg);
1626 builtin_optab = sqrt_optab;
1627 break;
1628 case BUILT_IN_EXP:
1629 case BUILT_IN_EXPF:
1630 case BUILT_IN_EXPL:
1631 errno_set = true; builtin_optab = exp_optab; break;
1632 case BUILT_IN_EXP10:
1633 case BUILT_IN_EXP10F:
1634 case BUILT_IN_EXP10L:
1635 case BUILT_IN_POW10:
1636 case BUILT_IN_POW10F:
1637 case BUILT_IN_POW10L:
1638 errno_set = true; builtin_optab = exp10_optab; break;
1639 case BUILT_IN_EXP2:
1640 case BUILT_IN_EXP2F:
1641 case BUILT_IN_EXP2L:
1642 errno_set = true; builtin_optab = exp2_optab; break;
1643 case BUILT_IN_LOG:
1644 case BUILT_IN_LOGF:
1645 case BUILT_IN_LOGL:
1646 errno_set = true; builtin_optab = log_optab; break;
1647 case BUILT_IN_LOG10:
1648 case BUILT_IN_LOG10F:
1649 case BUILT_IN_LOG10L:
1650 errno_set = true; builtin_optab = log10_optab; break;
1651 case BUILT_IN_LOG2:
1652 case BUILT_IN_LOG2F:
1653 case BUILT_IN_LOG2L:
1654 errno_set = true; builtin_optab = log2_optab; break;
1655 case BUILT_IN_TAN:
1656 case BUILT_IN_TANF:
1657 case BUILT_IN_TANL:
1658 builtin_optab = tan_optab; break;
1659 case BUILT_IN_ATAN:
1660 case BUILT_IN_ATANF:
1661 case BUILT_IN_ATANL:
1662 builtin_optab = atan_optab; break;
1663 case BUILT_IN_FLOOR:
1664 case BUILT_IN_FLOORF:
1665 case BUILT_IN_FLOORL:
1666 builtin_optab = floor_optab; break;
1667 case BUILT_IN_CEIL:
1668 case BUILT_IN_CEILF:
1669 case BUILT_IN_CEILL:
1670 builtin_optab = ceil_optab; break;
1671 case BUILT_IN_TRUNC:
1672 case BUILT_IN_TRUNCF:
1673 case BUILT_IN_TRUNCL:
1674 builtin_optab = btrunc_optab; break;
1675 case BUILT_IN_ROUND:
1676 case BUILT_IN_ROUNDF:
1677 case BUILT_IN_ROUNDL:
1678 builtin_optab = round_optab; break;
1679 case BUILT_IN_NEARBYINT:
1680 case BUILT_IN_NEARBYINTF:
1681 case BUILT_IN_NEARBYINTL:
1682 builtin_optab = nearbyint_optab; break;
1683 default:
1684 abort ();
1685 }
1686
1687 /* Make a suitable register to place result in. */
1688 mode = TYPE_MODE (TREE_TYPE (exp));
1689
1690 if (! flag_errno_math || ! HONOR_NANS (mode))
1691 errno_set = false;
1692
1693 /* Before working hard, check whether the instruction is available. */
1694 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1695 {
1696 target = gen_reg_rtx (mode);
1697
1698 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1699 need to expand the argument again. This way, we will not perform
1700 side-effects more the once. */
1701 narg = save_expr (arg);
1702 if (narg != arg)
1703 {
1704 arglist = build_tree_list (NULL_TREE, arg);
1705 exp = build_function_call_expr (fndecl, arglist);
1706 }
1707
1708 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1709
1710 emit_queue ();
1711 start_sequence ();
1712
1713 /* Compute into TARGET.
1714 Set TARGET to wherever the result comes back. */
1715 target = expand_unop (mode, builtin_optab, op0, target, 0);
1716
1717 if (target != 0)
1718 {
1719 if (errno_set)
1720 expand_errno_check (exp, target);
1721
1722 /* Output the entire sequence. */
1723 insns = get_insns ();
1724 end_sequence ();
1725 emit_insn (insns);
1726 return target;
1727 }
1728
1729 /* If we were unable to expand via the builtin, stop the sequence
1730 (without outputting the insns) and call to the library function
1731 with the stabilized argument list. */
1732 end_sequence ();
1733 }
1734
1735 before_call = get_last_insn ();
1736
1737 target = expand_call (exp, target, target == const0_rtx);
1738
1739 /* If this is a sqrt operation and we don't care about errno, try to
1740 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1741 This allows the semantics of the libcall to be visible to the RTL
1742 optimizers. */
1743 if (builtin_optab == sqrt_optab && !errno_set)
1744 {
1745 /* Search backwards through the insns emitted by expand_call looking
1746 for the instruction with the REG_RETVAL note. */
1747 rtx last = get_last_insn ();
1748 while (last != before_call)
1749 {
1750 if (find_reg_note (last, REG_RETVAL, NULL))
1751 {
1752 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1753 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1754 two elements, i.e. symbol_ref(sqrt) and the operand. */
1755 if (note
1756 && GET_CODE (note) == EXPR_LIST
1757 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1758 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1759 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1760 {
1761 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1762 /* Check operand is a register with expected mode. */
1763 if (operand
1764 && GET_CODE (operand) == REG
1765 && GET_MODE (operand) == mode)
1766 {
1767 /* Replace the REG_EQUAL note with a SQRT rtx. */
1768 rtx equiv = gen_rtx_SQRT (mode, operand);
1769 set_unique_reg_note (last, REG_EQUAL, equiv);
1770 }
1771 }
1772 break;
1773 }
1774 last = PREV_INSN (last);
1775 }
1776 }
1777
1778 return target;
1779 }
1780
1781 /* Expand a call to the builtin binary math functions (pow and atan2).
1782 Return 0 if a normal call should be emitted rather than expanding the
1783 function in-line. EXP is the expression that is a call to the builtin
1784 function; if convenient, the result should be placed in TARGET.
1785 SUBTARGET may be used as the target for computing one of EXP's
1786 operands. */
1787
1788 static rtx
1789 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1790 {
1791 optab builtin_optab;
1792 rtx op0, op1, insns;
1793 tree fndecl = get_callee_fndecl (exp);
1794 tree arglist = TREE_OPERAND (exp, 1);
1795 tree arg0, arg1, temp, narg;
1796 enum machine_mode mode;
1797 bool errno_set = true;
1798 bool stable = true;
1799
1800 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1801 return 0;
1802
1803 arg0 = TREE_VALUE (arglist);
1804 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1805
1806 switch (DECL_FUNCTION_CODE (fndecl))
1807 {
1808 case BUILT_IN_POW:
1809 case BUILT_IN_POWF:
1810 case BUILT_IN_POWL:
1811 builtin_optab = pow_optab; break;
1812 case BUILT_IN_ATAN2:
1813 case BUILT_IN_ATAN2F:
1814 case BUILT_IN_ATAN2L:
1815 builtin_optab = atan2_optab; break;
1816 default:
1817 abort ();
1818 }
1819
1820 /* Make a suitable register to place result in. */
1821 mode = TYPE_MODE (TREE_TYPE (exp));
1822
1823 /* Before working hard, check whether the instruction is available. */
1824 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1825 return 0;
1826
1827 target = gen_reg_rtx (mode);
1828
1829 if (! flag_errno_math || ! HONOR_NANS (mode))
1830 errno_set = false;
1831
1832 /* Alway stabilize the argument list. */
1833 narg = save_expr (arg1);
1834 if (narg != arg1)
1835 {
1836 temp = build_tree_list (NULL_TREE, narg);
1837 stable = false;
1838 }
1839 else
1840 temp = TREE_CHAIN (arglist);
1841
1842 narg = save_expr (arg0);
1843 if (narg != arg0)
1844 {
1845 arglist = tree_cons (NULL_TREE, narg, temp);
1846 stable = false;
1847 }
1848 else if (! stable)
1849 arglist = tree_cons (NULL_TREE, arg0, temp);
1850
1851 if (! stable)
1852 exp = build_function_call_expr (fndecl, arglist);
1853
1854 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1855 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1856
1857 emit_queue ();
1858 start_sequence ();
1859
1860 /* Compute into TARGET.
1861 Set TARGET to wherever the result comes back. */
1862 target = expand_binop (mode, builtin_optab, op0, op1,
1863 target, 0, OPTAB_DIRECT);
1864
1865 /* If we were unable to expand via the builtin, stop the sequence
1866 (without outputting the insns) and call to the library function
1867 with the stabilized argument list. */
1868 if (target == 0)
1869 {
1870 end_sequence ();
1871 return expand_call (exp, target, target == const0_rtx);
1872 }
1873
1874 if (errno_set)
1875 expand_errno_check (exp, target);
1876
1877 /* Output the entire sequence. */
1878 insns = get_insns ();
1879 end_sequence ();
1880 emit_insn (insns);
1881
1882 return target;
1883 }
1884
1885 /* To evaluate powi(x,n), the floating point value x raised to the
1886 constant integer exponent n, we use a hybrid algorithm that
1887 combines the "window method" with look-up tables. For an
1888 introduction to exponentiation algorithms and "addition chains",
1889 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1890 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1891 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1892 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1893
1894 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1895 multiplications to inline before calling the system library's pow
1896 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1897 so this default never requires calling pow, powf or powl. */
1898
1899 #ifndef POWI_MAX_MULTS
1900 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1901 #endif
1902
1903 /* The size of the "optimal power tree" lookup table. All
1904 exponents less than this value are simply looked up in the
1905 powi_table below. This threshold is also used to size the
1906 cache of pseudo registers that hold intermediate results. */
1907 #define POWI_TABLE_SIZE 256
1908
1909 /* The size, in bits of the window, used in the "window method"
1910 exponentiation algorithm. This is equivalent to a radix of
1911 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1912 #define POWI_WINDOW_SIZE 3
1913
1914 /* The following table is an efficient representation of an
1915 "optimal power tree". For each value, i, the corresponding
1916 value, j, in the table states than an optimal evaluation
1917 sequence for calculating pow(x,i) can be found by evaluating
1918 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1919 100 integers is given in Knuth's "Seminumerical algorithms". */
1920
1921 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1922 {
1923 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1924 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1925 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1926 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1927 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1928 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1929 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1930 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1931 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1932 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1933 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1934 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1935 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1936 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1937 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1938 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1939 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1940 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1941 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1942 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1943 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1944 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1945 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1946 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1947 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1948 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1949 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1950 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1951 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1952 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1953 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1954 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1955 };
1956
1957
1958 /* Return the number of multiplications required to calculate
1959 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
1960 subroutine of powi_cost. CACHE is an array indicating
1961 which exponents have already been calculated. */
1962
1963 static int
1964 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1965 {
1966 /* If we've already calculated this exponent, then this evaluation
1967 doesn't require any additional multiplications. */
1968 if (cache[n])
1969 return 0;
1970
1971 cache[n] = true;
1972 return powi_lookup_cost (n - powi_table[n], cache)
1973 + powi_lookup_cost (powi_table[n], cache) + 1;
1974 }
1975
1976 /* Return the number of multiplications required to calculate
1977 powi(x,n) for an arbitrary x, given the exponent N. This
1978 function needs to be kept in sync with expand_powi below. */
1979
1980 static int
1981 powi_cost (HOST_WIDE_INT n)
1982 {
1983 bool cache[POWI_TABLE_SIZE];
1984 unsigned HOST_WIDE_INT digit;
1985 unsigned HOST_WIDE_INT val;
1986 int result;
1987
1988 if (n == 0)
1989 return 0;
1990
1991 /* Ignore the reciprocal when calculating the cost. */
1992 val = (n < 0) ? -n : n;
1993
1994 /* Initialize the exponent cache. */
1995 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
1996 cache[1] = true;
1997
1998 result = 0;
1999
2000 while (val >= POWI_TABLE_SIZE)
2001 {
2002 if (val & 1)
2003 {
2004 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2005 result += powi_lookup_cost (digit, cache)
2006 + POWI_WINDOW_SIZE + 1;
2007 val >>= POWI_WINDOW_SIZE;
2008 }
2009 else
2010 {
2011 val >>= 1;
2012 result++;
2013 }
2014 }
2015
2016 return result + powi_lookup_cost (val, cache);
2017 }
2018
2019 /* Recursive subroutine of expand_powi. This function takes the array,
2020 CACHE, of already calculated exponents and an exponent N and returns
2021 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2022
2023 static rtx
2024 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2025 {
2026 unsigned HOST_WIDE_INT digit;
2027 rtx target, result;
2028 rtx op0, op1;
2029
2030 if (n < POWI_TABLE_SIZE)
2031 {
2032 if (cache[n])
2033 return cache[n];
2034
2035 target = gen_reg_rtx (mode);
2036 cache[n] = target;
2037
2038 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2039 op1 = expand_powi_1 (mode, powi_table[n], cache);
2040 }
2041 else if (n & 1)
2042 {
2043 target = gen_reg_rtx (mode);
2044 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2045 op0 = expand_powi_1 (mode, n - digit, cache);
2046 op1 = expand_powi_1 (mode, digit, cache);
2047 }
2048 else
2049 {
2050 target = gen_reg_rtx (mode);
2051 op0 = expand_powi_1 (mode, n >> 1, cache);
2052 op1 = op0;
2053 }
2054
2055 result = expand_mult (mode, op0, op1, target, 0);
2056 if (result != target)
2057 emit_move_insn (target, result);
2058 return target;
2059 }
2060
2061 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2062 floating point operand in mode MODE, and N is the exponent. This
2063 function needs to be kept in sync with powi_cost above. */
2064
2065 static rtx
2066 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2067 {
2068 unsigned HOST_WIDE_INT val;
2069 rtx cache[POWI_TABLE_SIZE];
2070 rtx result;
2071
2072 if (n == 0)
2073 return CONST1_RTX (mode);
2074
2075 val = (n < 0) ? -n : n;
2076
2077 memset (cache, 0, sizeof (cache));
2078 cache[1] = x;
2079
2080 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2081
2082 /* If the original exponent was negative, reciprocate the result. */
2083 if (n < 0)
2084 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2085 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2086
2087 return result;
2088 }
2089
2090 /* Expand a call to the pow built-in mathematical function. Return 0 if
2091 a normal call should be emitted rather than expanding the function
2092 in-line. EXP is the expression that is a call to the builtin
2093 function; if convenient, the result should be placed in TARGET. */
2094
2095 static rtx
2096 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2097 {
2098 tree arglist = TREE_OPERAND (exp, 1);
2099 tree arg0, arg1;
2100
2101 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2102 return 0;
2103
2104 arg0 = TREE_VALUE (arglist);
2105 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2106
2107 if (TREE_CODE (arg1) == REAL_CST
2108 && ! TREE_CONSTANT_OVERFLOW (arg1))
2109 {
2110 REAL_VALUE_TYPE cint;
2111 REAL_VALUE_TYPE c;
2112 HOST_WIDE_INT n;
2113
2114 c = TREE_REAL_CST (arg1);
2115 n = real_to_integer (&c);
2116 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2117 if (real_identical (&c, &cint))
2118 {
2119 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2120 Otherwise, check the number of multiplications required.
2121 Note that pow never sets errno for an integer exponent. */
2122 if ((n >= -1 && n <= 2)
2123 || (flag_unsafe_math_optimizations
2124 && ! optimize_size
2125 && powi_cost (n) <= POWI_MAX_MULTS))
2126 {
2127 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2128 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2129 op = force_reg (mode, op);
2130 return expand_powi (op, mode, n);
2131 }
2132 }
2133 }
2134
2135 if (! flag_unsafe_math_optimizations)
2136 return NULL_RTX;
2137 return expand_builtin_mathfn_2 (exp, target, subtarget);
2138 }
2139
2140 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2141 if we failed the caller should emit a normal call, otherwise
2142 try to get the result in TARGET, if convenient. */
2143
2144 static rtx
2145 expand_builtin_strlen (tree arglist, rtx target,
2146 enum machine_mode target_mode)
2147 {
2148 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2149 return 0;
2150 else
2151 {
2152 rtx pat;
2153 tree len, src = TREE_VALUE (arglist);
2154 rtx result, src_reg, char_rtx, before_strlen;
2155 enum machine_mode insn_mode = target_mode, char_mode;
2156 enum insn_code icode = CODE_FOR_nothing;
2157 int align;
2158
2159 /* If the length can be computed at compile-time, return it. */
2160 len = c_strlen (src, 0);
2161 if (len)
2162 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2163
2164 /* If the length can be computed at compile-time and is constant
2165 integer, but there are side-effects in src, evaluate
2166 src for side-effects, then return len.
2167 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2168 can be optimized into: i++; x = 3; */
2169 len = c_strlen (src, 1);
2170 if (len && TREE_CODE (len) == INTEGER_CST)
2171 {
2172 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2173 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2174 }
2175
2176 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2177
2178 /* If SRC is not a pointer type, don't do this operation inline. */
2179 if (align == 0)
2180 return 0;
2181
2182 /* Bail out if we can't compute strlen in the right mode. */
2183 while (insn_mode != VOIDmode)
2184 {
2185 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2186 if (icode != CODE_FOR_nothing)
2187 break;
2188
2189 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2190 }
2191 if (insn_mode == VOIDmode)
2192 return 0;
2193
2194 /* Make a place to write the result of the instruction. */
2195 result = target;
2196 if (! (result != 0
2197 && GET_CODE (result) == REG
2198 && GET_MODE (result) == insn_mode
2199 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2200 result = gen_reg_rtx (insn_mode);
2201
2202 /* Make a place to hold the source address. We will not expand
2203 the actual source until we are sure that the expansion will
2204 not fail -- there are trees that cannot be expanded twice. */
2205 src_reg = gen_reg_rtx (Pmode);
2206
2207 /* Mark the beginning of the strlen sequence so we can emit the
2208 source operand later. */
2209 before_strlen = get_last_insn ();
2210
2211 char_rtx = const0_rtx;
2212 char_mode = insn_data[(int) icode].operand[2].mode;
2213 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2214 char_mode))
2215 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2216
2217 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2218 char_rtx, GEN_INT (align));
2219 if (! pat)
2220 return 0;
2221 emit_insn (pat);
2222
2223 /* Now that we are assured of success, expand the source. */
2224 start_sequence ();
2225 pat = memory_address (BLKmode,
2226 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2227 if (pat != src_reg)
2228 emit_move_insn (src_reg, pat);
2229 pat = get_insns ();
2230 end_sequence ();
2231
2232 if (before_strlen)
2233 emit_insn_after (pat, before_strlen);
2234 else
2235 emit_insn_before (pat, get_insns ());
2236
2237 /* Return the value in the proper mode for this function. */
2238 if (GET_MODE (result) == target_mode)
2239 target = result;
2240 else if (target != 0)
2241 convert_move (target, result, 0);
2242 else
2243 target = convert_to_mode (target_mode, result, 0);
2244
2245 return target;
2246 }
2247 }
2248
2249 /* Expand a call to the strstr builtin. Return 0 if we failed the
2250 caller should emit a normal call, otherwise try to get the result
2251 in TARGET, if convenient (and in mode MODE if that's convenient). */
2252
2253 static rtx
2254 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2255 {
2256 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2257 return 0;
2258 else
2259 {
2260 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2261 tree fn;
2262 const char *p1, *p2;
2263
2264 p2 = c_getstr (s2);
2265 if (p2 == NULL)
2266 return 0;
2267
2268 p1 = c_getstr (s1);
2269 if (p1 != NULL)
2270 {
2271 const char *r = strstr (p1, p2);
2272
2273 if (r == NULL)
2274 return const0_rtx;
2275
2276 /* Return an offset into the constant string argument. */
2277 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2278 s1, convert (TREE_TYPE (s1),
2279 ssize_int (r - p1)))),
2280 target, mode, EXPAND_NORMAL);
2281 }
2282
2283 if (p2[0] == '\0')
2284 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2285
2286 if (p2[1] != '\0')
2287 return 0;
2288
2289 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2290 if (!fn)
2291 return 0;
2292
2293 /* New argument list transforming strstr(s1, s2) to
2294 strchr(s1, s2[0]). */
2295 arglist =
2296 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2297 arglist = tree_cons (NULL_TREE, s1, arglist);
2298 return expand_expr (build_function_call_expr (fn, arglist),
2299 target, mode, EXPAND_NORMAL);
2300 }
2301 }
2302
2303 /* Expand a call to the strchr builtin. Return 0 if we failed the
2304 caller should emit a normal call, otherwise try to get the result
2305 in TARGET, if convenient (and in mode MODE if that's convenient). */
2306
2307 static rtx
2308 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2309 {
2310 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2311 return 0;
2312 else
2313 {
2314 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2315 const char *p1;
2316
2317 if (TREE_CODE (s2) != INTEGER_CST)
2318 return 0;
2319
2320 p1 = c_getstr (s1);
2321 if (p1 != NULL)
2322 {
2323 char c;
2324 const char *r;
2325
2326 if (target_char_cast (s2, &c))
2327 return 0;
2328
2329 r = strchr (p1, c);
2330
2331 if (r == NULL)
2332 return const0_rtx;
2333
2334 /* Return an offset into the constant string argument. */
2335 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2336 s1, convert (TREE_TYPE (s1),
2337 ssize_int (r - p1)))),
2338 target, mode, EXPAND_NORMAL);
2339 }
2340
2341 /* FIXME: Should use here strchrM optab so that ports can optimize
2342 this. */
2343 return 0;
2344 }
2345 }
2346
2347 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2348 caller should emit a normal call, otherwise try to get the result
2349 in TARGET, if convenient (and in mode MODE if that's convenient). */
2350
2351 static rtx
2352 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2353 {
2354 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2355 return 0;
2356 else
2357 {
2358 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2359 tree fn;
2360 const char *p1;
2361
2362 if (TREE_CODE (s2) != INTEGER_CST)
2363 return 0;
2364
2365 p1 = c_getstr (s1);
2366 if (p1 != NULL)
2367 {
2368 char c;
2369 const char *r;
2370
2371 if (target_char_cast (s2, &c))
2372 return 0;
2373
2374 r = strrchr (p1, c);
2375
2376 if (r == NULL)
2377 return const0_rtx;
2378
2379 /* Return an offset into the constant string argument. */
2380 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2381 s1, convert (TREE_TYPE (s1),
2382 ssize_int (r - p1)))),
2383 target, mode, EXPAND_NORMAL);
2384 }
2385
2386 if (! integer_zerop (s2))
2387 return 0;
2388
2389 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2390 if (!fn)
2391 return 0;
2392
2393 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2394 return expand_expr (build_function_call_expr (fn, arglist),
2395 target, mode, EXPAND_NORMAL);
2396 }
2397 }
2398
2399 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2400 caller should emit a normal call, otherwise try to get the result
2401 in TARGET, if convenient (and in mode MODE if that's convenient). */
2402
2403 static rtx
2404 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2405 {
2406 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2407 return 0;
2408 else
2409 {
2410 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2411 tree fn;
2412 const char *p1, *p2;
2413
2414 p2 = c_getstr (s2);
2415 if (p2 == NULL)
2416 return 0;
2417
2418 p1 = c_getstr (s1);
2419 if (p1 != NULL)
2420 {
2421 const char *r = strpbrk (p1, p2);
2422
2423 if (r == NULL)
2424 return const0_rtx;
2425
2426 /* Return an offset into the constant string argument. */
2427 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2428 s1, convert (TREE_TYPE (s1),
2429 ssize_int (r - p1)))),
2430 target, mode, EXPAND_NORMAL);
2431 }
2432
2433 if (p2[0] == '\0')
2434 {
2435 /* strpbrk(x, "") == NULL.
2436 Evaluate and ignore the arguments in case they had
2437 side-effects. */
2438 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2439 return const0_rtx;
2440 }
2441
2442 if (p2[1] != '\0')
2443 return 0; /* Really call strpbrk. */
2444
2445 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2446 if (!fn)
2447 return 0;
2448
2449 /* New argument list transforming strpbrk(s1, s2) to
2450 strchr(s1, s2[0]). */
2451 arglist =
2452 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2453 arglist = tree_cons (NULL_TREE, s1, arglist);
2454 return expand_expr (build_function_call_expr (fn, arglist),
2455 target, mode, EXPAND_NORMAL);
2456 }
2457 }
2458
2459 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2460 bytes from constant string DATA + OFFSET and return it as target
2461 constant. */
2462
2463 static rtx
2464 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2465 enum machine_mode mode)
2466 {
2467 const char *str = (const char *) data;
2468
2469 if (offset < 0
2470 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2471 > strlen (str) + 1))
2472 abort (); /* Attempt to read past the end of constant string. */
2473
2474 return c_readstr (str + offset, mode);
2475 }
2476
2477 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2478 Return 0 if we failed, the caller should emit a normal call,
2479 otherwise try to get the result in TARGET, if convenient (and in
2480 mode MODE if that's convenient). */
2481 static rtx
2482 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2483 {
2484 if (!validate_arglist (arglist,
2485 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2486 return 0;
2487 else
2488 {
2489 tree dest = TREE_VALUE (arglist);
2490 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2491 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2492 const char *src_str;
2493 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2494 unsigned int dest_align
2495 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2496 rtx dest_mem, src_mem, dest_addr, len_rtx;
2497
2498 /* If DEST is not a pointer type, call the normal function. */
2499 if (dest_align == 0)
2500 return 0;
2501
2502 /* If the LEN parameter is zero, return DEST. */
2503 if (integer_zerop (len))
2504 {
2505 /* Evaluate and ignore SRC in case it has side-effects. */
2506 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2507 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2508 }
2509
2510 /* If SRC and DEST are the same (and not volatile), return DEST. */
2511 if (operand_equal_p (src, dest, 0))
2512 {
2513 /* Evaluate and ignore LEN in case it has side-effects. */
2514 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2515 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2516 }
2517
2518 /* If either SRC is not a pointer type, don't do this
2519 operation in-line. */
2520 if (src_align == 0)
2521 return 0;
2522
2523 dest_mem = get_memory_rtx (dest);
2524 set_mem_align (dest_mem, dest_align);
2525 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2526 src_str = c_getstr (src);
2527
2528 /* If SRC is a string constant and block move would be done
2529 by pieces, we can avoid loading the string from memory
2530 and only stored the computed constants. */
2531 if (src_str
2532 && GET_CODE (len_rtx) == CONST_INT
2533 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2534 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2535 (void *) src_str, dest_align))
2536 {
2537 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2538 builtin_memcpy_read_str,
2539 (void *) src_str, dest_align, 0);
2540 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2541 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2542 return dest_mem;
2543 }
2544
2545 src_mem = get_memory_rtx (src);
2546 set_mem_align (src_mem, src_align);
2547
2548 /* Copy word part most expediently. */
2549 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2550 BLOCK_OP_NORMAL);
2551
2552 if (dest_addr == 0)
2553 {
2554 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2555 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2556 }
2557 return dest_addr;
2558 }
2559 }
2560
2561 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2562 Return 0 if we failed the caller should emit a normal call,
2563 otherwise try to get the result in TARGET, if convenient (and in
2564 mode MODE if that's convenient). If ENDP is 0 return the
2565 destination pointer, if ENDP is 1 return the end pointer ala
2566 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2567 stpcpy. */
2568
2569 static rtx
2570 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2571 int endp)
2572 {
2573 if (!validate_arglist (arglist,
2574 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2575 return 0;
2576 /* If return value is ignored, transform mempcpy into memcpy. */
2577 else if (target == const0_rtx)
2578 {
2579 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2580
2581 if (!fn)
2582 return 0;
2583
2584 return expand_expr (build_function_call_expr (fn, arglist),
2585 target, mode, EXPAND_NORMAL);
2586 }
2587 else
2588 {
2589 tree dest = TREE_VALUE (arglist);
2590 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2591 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2592 const char *src_str;
2593 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2594 unsigned int dest_align
2595 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2596 rtx dest_mem, src_mem, len_rtx;
2597
2598 /* If DEST is not a pointer type, call the normal function. */
2599 if (dest_align == 0)
2600 return 0;
2601
2602 /* If SRC and DEST are the same (and not volatile), do nothing. */
2603 if (operand_equal_p (src, dest, 0))
2604 {
2605 tree expr;
2606
2607 if (endp == 0)
2608 {
2609 /* Evaluate and ignore LEN in case it has side-effects. */
2610 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2611 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2612 }
2613
2614 if (endp == 2)
2615 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2616 integer_one_node));
2617 len = convert (TREE_TYPE (dest), len);
2618 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2619 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2620 }
2621
2622 /* If LEN is not constant, call the normal function. */
2623 if (! host_integerp (len, 1))
2624 return 0;
2625
2626 /* If the LEN parameter is zero, return DEST. */
2627 if (tree_low_cst (len, 1) == 0)
2628 {
2629 /* Evaluate and ignore SRC in case it has side-effects. */
2630 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2631 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2632 }
2633
2634 /* If either SRC is not a pointer type, don't do this
2635 operation in-line. */
2636 if (src_align == 0)
2637 return 0;
2638
2639 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2640 src_str = c_getstr (src);
2641
2642 /* If SRC is a string constant and block move would be done
2643 by pieces, we can avoid loading the string from memory
2644 and only stored the computed constants. */
2645 if (src_str
2646 && GET_CODE (len_rtx) == CONST_INT
2647 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2648 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2649 (void *) src_str, dest_align))
2650 {
2651 dest_mem = get_memory_rtx (dest);
2652 set_mem_align (dest_mem, dest_align);
2653 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2654 builtin_memcpy_read_str,
2655 (void *) src_str, dest_align, endp);
2656 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2657 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2658 return dest_mem;
2659 }
2660
2661 if (GET_CODE (len_rtx) == CONST_INT
2662 && can_move_by_pieces (INTVAL (len_rtx),
2663 MIN (dest_align, src_align)))
2664 {
2665 dest_mem = get_memory_rtx (dest);
2666 set_mem_align (dest_mem, dest_align);
2667 src_mem = get_memory_rtx (src);
2668 set_mem_align (src_mem, src_align);
2669 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2670 MIN (dest_align, src_align), endp);
2671 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2672 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2673 return dest_mem;
2674 }
2675
2676 return 0;
2677 }
2678 }
2679
2680 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2681 if we failed the caller should emit a normal call. */
2682
2683 static rtx
2684 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2685 {
2686 if (!validate_arglist (arglist,
2687 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2688 return 0;
2689 else
2690 {
2691 tree dest = TREE_VALUE (arglist);
2692 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2693 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2694
2695 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2696 unsigned int dest_align
2697 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2698
2699 /* If DEST is not a pointer type, call the normal function. */
2700 if (dest_align == 0)
2701 return 0;
2702
2703 /* If the LEN parameter is zero, return DEST. */
2704 if (integer_zerop (len))
2705 {
2706 /* Evaluate and ignore SRC in case it has side-effects. */
2707 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2708 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2709 }
2710
2711 /* If SRC and DEST are the same (and not volatile), return DEST. */
2712 if (operand_equal_p (src, dest, 0))
2713 {
2714 /* Evaluate and ignore LEN in case it has side-effects. */
2715 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2716 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2717 }
2718
2719 /* If either SRC is not a pointer type, don't do this
2720 operation in-line. */
2721 if (src_align == 0)
2722 return 0;
2723
2724 /* If src is categorized for a readonly section we can use
2725 normal memcpy. */
2726 if (readonly_data_expr (src))
2727 {
2728 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2729 if (!fn)
2730 return 0;
2731 return expand_expr (build_function_call_expr (fn, arglist),
2732 target, mode, EXPAND_NORMAL);
2733 }
2734
2735 /* Otherwise, call the normal function. */
2736 return 0;
2737 }
2738 }
2739
2740 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2741 if we failed the caller should emit a normal call. */
2742
2743 static rtx
2744 expand_builtin_bcopy (tree arglist)
2745 {
2746 tree src, dest, size, newarglist;
2747
2748 if (!validate_arglist (arglist,
2749 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2750 return NULL_RTX;
2751
2752 src = TREE_VALUE (arglist);
2753 dest = TREE_VALUE (TREE_CHAIN (arglist));
2754 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2755
2756 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2757 memmove(ptr y, ptr x, size_t z). This is done this way
2758 so that if it isn't expanded inline, we fallback to
2759 calling bcopy instead of memmove. */
2760
2761 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2762 newarglist = tree_cons (NULL_TREE, src, newarglist);
2763 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2764
2765 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2766 }
2767
2768 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2769 if we failed the caller should emit a normal call, otherwise try to get
2770 the result in TARGET, if convenient (and in mode MODE if that's
2771 convenient). */
2772
2773 static rtx
2774 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2775 {
2776 tree fn, len, src, dst;
2777
2778 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2779 return 0;
2780
2781 src = TREE_VALUE (TREE_CHAIN (arglist));
2782 dst = TREE_VALUE (arglist);
2783
2784 /* If SRC and DST are equal (and not volatile), return DST. */
2785 if (operand_equal_p (src, dst, 0))
2786 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2787
2788 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2789 if (!fn)
2790 return 0;
2791
2792 len = c_strlen (src, 1);
2793 if (len == 0 || TREE_SIDE_EFFECTS (len))
2794 return 0;
2795
2796 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2797 arglist = build_tree_list (NULL_TREE, len);
2798 arglist = tree_cons (NULL_TREE, src, arglist);
2799 arglist = tree_cons (NULL_TREE, dst, arglist);
2800 return expand_expr (build_function_call_expr (fn, arglist),
2801 target, mode, EXPAND_NORMAL);
2802 }
2803
2804 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2805 Return 0 if we failed the caller should emit a normal call,
2806 otherwise try to get the result in TARGET, if convenient (and in
2807 mode MODE if that's convenient). */
2808
2809 static rtx
2810 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2811 {
2812 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2813 return 0;
2814 else
2815 {
2816 tree dst, src, len;
2817
2818 /* If return value is ignored, transform stpcpy into strcpy. */
2819 if (target == const0_rtx)
2820 {
2821 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2822 if (!fn)
2823 return 0;
2824
2825 return expand_expr (build_function_call_expr (fn, arglist),
2826 target, mode, EXPAND_NORMAL);
2827 }
2828
2829 /* Ensure we get an actual string whose length can be evaluated at
2830 compile-time, not an expression containing a string. This is
2831 because the latter will potentially produce pessimized code
2832 when used to produce the return value. */
2833 src = TREE_VALUE (TREE_CHAIN (arglist));
2834 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2835 return 0;
2836
2837 dst = TREE_VALUE (arglist);
2838 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2839 arglist = build_tree_list (NULL_TREE, len);
2840 arglist = tree_cons (NULL_TREE, src, arglist);
2841 arglist = tree_cons (NULL_TREE, dst, arglist);
2842 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2843 }
2844 }
2845
2846 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2847 bytes from constant string DATA + OFFSET and return it as target
2848 constant. */
2849
2850 static rtx
2851 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2852 enum machine_mode mode)
2853 {
2854 const char *str = (const char *) data;
2855
2856 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2857 return const0_rtx;
2858
2859 return c_readstr (str + offset, mode);
2860 }
2861
2862 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2863 if we failed the caller should emit a normal call. */
2864
2865 static rtx
2866 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2867 {
2868 if (!validate_arglist (arglist,
2869 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2870 return 0;
2871 else
2872 {
2873 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2874 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2875 tree fn;
2876
2877 /* We must be passed a constant len parameter. */
2878 if (TREE_CODE (len) != INTEGER_CST)
2879 return 0;
2880
2881 /* If the len parameter is zero, return the dst parameter. */
2882 if (integer_zerop (len))
2883 {
2884 /* Evaluate and ignore the src argument in case it has
2885 side-effects. */
2886 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2887 VOIDmode, EXPAND_NORMAL);
2888 /* Return the dst parameter. */
2889 return expand_expr (TREE_VALUE (arglist), target, mode,
2890 EXPAND_NORMAL);
2891 }
2892
2893 /* Now, we must be passed a constant src ptr parameter. */
2894 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2895 return 0;
2896
2897 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2898
2899 /* We're required to pad with trailing zeros if the requested
2900 len is greater than strlen(s2)+1. In that case try to
2901 use store_by_pieces, if it fails, punt. */
2902 if (tree_int_cst_lt (slen, len))
2903 {
2904 tree dest = TREE_VALUE (arglist);
2905 unsigned int dest_align
2906 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2907 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2908 rtx dest_mem;
2909
2910 if (!p || dest_align == 0 || !host_integerp (len, 1)
2911 || !can_store_by_pieces (tree_low_cst (len, 1),
2912 builtin_strncpy_read_str,
2913 (void *) p, dest_align))
2914 return 0;
2915
2916 dest_mem = get_memory_rtx (dest);
2917 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2918 builtin_strncpy_read_str,
2919 (void *) p, dest_align, 0);
2920 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2921 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2922 return dest_mem;
2923 }
2924
2925 /* OK transform into builtin memcpy. */
2926 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2927 if (!fn)
2928 return 0;
2929 return expand_expr (build_function_call_expr (fn, arglist),
2930 target, mode, EXPAND_NORMAL);
2931 }
2932 }
2933
2934 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2935 bytes from constant string DATA + OFFSET and return it as target
2936 constant. */
2937
2938 static rtx
2939 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2940 enum machine_mode mode)
2941 {
2942 const char *c = (const char *) data;
2943 char *p = alloca (GET_MODE_SIZE (mode));
2944
2945 memset (p, *c, GET_MODE_SIZE (mode));
2946
2947 return c_readstr (p, mode);
2948 }
2949
2950 /* Callback routine for store_by_pieces. Return the RTL of a register
2951 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2952 char value given in the RTL register data. For example, if mode is
2953 4 bytes wide, return the RTL for 0x01010101*data. */
2954
2955 static rtx
2956 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2957 enum machine_mode mode)
2958 {
2959 rtx target, coeff;
2960 size_t size;
2961 char *p;
2962
2963 size = GET_MODE_SIZE (mode);
2964 if (size == 1)
2965 return (rtx) data;
2966
2967 p = alloca (size);
2968 memset (p, 1, size);
2969 coeff = c_readstr (p, mode);
2970
2971 target = convert_to_mode (mode, (rtx) data, 1);
2972 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2973 return force_reg (mode, target);
2974 }
2975
2976 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2977 if we failed the caller should emit a normal call, otherwise try to get
2978 the result in TARGET, if convenient (and in mode MODE if that's
2979 convenient). */
2980
2981 static rtx
2982 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2983 {
2984 if (!validate_arglist (arglist,
2985 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2986 return 0;
2987 else
2988 {
2989 tree dest = TREE_VALUE (arglist);
2990 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2991 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2992 char c;
2993
2994 unsigned int dest_align
2995 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2996 rtx dest_mem, dest_addr, len_rtx;
2997
2998 /* If DEST is not a pointer type, don't do this
2999 operation in-line. */
3000 if (dest_align == 0)
3001 return 0;
3002
3003 /* If the LEN parameter is zero, return DEST. */
3004 if (integer_zerop (len))
3005 {
3006 /* Evaluate and ignore VAL in case it has side-effects. */
3007 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3008 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3009 }
3010
3011 if (TREE_CODE (val) != INTEGER_CST)
3012 {
3013 rtx val_rtx;
3014
3015 if (!host_integerp (len, 1))
3016 return 0;
3017
3018 if (optimize_size && tree_low_cst (len, 1) > 1)
3019 return 0;
3020
3021 /* Assume that we can memset by pieces if we can store the
3022 * the coefficients by pieces (in the required modes).
3023 * We can't pass builtin_memset_gen_str as that emits RTL. */
3024 c = 1;
3025 if (!can_store_by_pieces (tree_low_cst (len, 1),
3026 builtin_memset_read_str,
3027 &c, dest_align))
3028 return 0;
3029
3030 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3031 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3032 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3033 val_rtx);
3034 dest_mem = get_memory_rtx (dest);
3035 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3036 builtin_memset_gen_str,
3037 val_rtx, dest_align, 0);
3038 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3039 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3040 return dest_mem;
3041 }
3042
3043 if (target_char_cast (val, &c))
3044 return 0;
3045
3046 if (c)
3047 {
3048 if (!host_integerp (len, 1))
3049 return 0;
3050 if (!can_store_by_pieces (tree_low_cst (len, 1),
3051 builtin_memset_read_str, &c,
3052 dest_align))
3053 return 0;
3054
3055 dest_mem = get_memory_rtx (dest);
3056 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3057 builtin_memset_read_str,
3058 &c, dest_align, 0);
3059 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3060 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3061 return dest_mem;
3062 }
3063
3064 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3065
3066 dest_mem = get_memory_rtx (dest);
3067 set_mem_align (dest_mem, dest_align);
3068 dest_addr = clear_storage (dest_mem, len_rtx);
3069
3070 if (dest_addr == 0)
3071 {
3072 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3073 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3074 }
3075
3076 return dest_addr;
3077 }
3078 }
3079
3080 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3081 if we failed the caller should emit a normal call. */
3082
3083 static rtx
3084 expand_builtin_bzero (tree arglist)
3085 {
3086 tree dest, size, newarglist;
3087
3088 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3089 return NULL_RTX;
3090
3091 dest = TREE_VALUE (arglist);
3092 size = TREE_VALUE (TREE_CHAIN (arglist));
3093
3094 /* New argument list transforming bzero(ptr x, int y) to
3095 memset(ptr x, int 0, size_t y). This is done this way
3096 so that if it isn't expanded inline, we fallback to
3097 calling bzero instead of memset. */
3098
3099 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3100 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3101 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3102
3103 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3104 }
3105
3106 /* Expand expression EXP, which is a call to the memcmp built-in function.
3107 ARGLIST is the argument list for this call. Return 0 if we failed and the
3108 caller should emit a normal call, otherwise try to get the result in
3109 TARGET, if convenient (and in mode MODE, if that's convenient). */
3110
3111 static rtx
3112 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3113 enum machine_mode mode)
3114 {
3115 tree arg1, arg2, len;
3116 const char *p1, *p2;
3117
3118 if (!validate_arglist (arglist,
3119 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3120 return 0;
3121
3122 arg1 = TREE_VALUE (arglist);
3123 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3124 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3125
3126 /* If the len parameter is zero, return zero. */
3127 if (integer_zerop (len))
3128 {
3129 /* Evaluate and ignore arg1 and arg2 in case they have
3130 side-effects. */
3131 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3132 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3133 return const0_rtx;
3134 }
3135
3136 /* If both arguments are equal (and not volatile), return zero. */
3137 if (operand_equal_p (arg1, arg2, 0))
3138 {
3139 /* Evaluate and ignore len in case it has side-effects. */
3140 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3141 return const0_rtx;
3142 }
3143
3144 p1 = c_getstr (arg1);
3145 p2 = c_getstr (arg2);
3146
3147 /* If all arguments are constant, and the value of len is not greater
3148 than the lengths of arg1 and arg2, evaluate at compile-time. */
3149 if (host_integerp (len, 1) && p1 && p2
3150 && compare_tree_int (len, strlen (p1) + 1) <= 0
3151 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3152 {
3153 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3154
3155 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3156 }
3157
3158 /* If len parameter is one, return an expression corresponding to
3159 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3160 if (integer_onep (len))
3161 {
3162 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3163 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3164 tree ind1 =
3165 fold (build1 (CONVERT_EXPR, integer_type_node,
3166 build1 (INDIRECT_REF, cst_uchar_node,
3167 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3168 tree ind2 =
3169 fold (build1 (CONVERT_EXPR, integer_type_node,
3170 build1 (INDIRECT_REF, cst_uchar_node,
3171 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3172 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3173 return expand_expr (result, target, mode, EXPAND_NORMAL);
3174 }
3175
3176 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3177 {
3178 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3179 rtx result;
3180 rtx insn;
3181
3182 int arg1_align
3183 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3184 int arg2_align
3185 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3186 enum machine_mode insn_mode;
3187
3188 #ifdef HAVE_cmpmemsi
3189 if (HAVE_cmpmemsi)
3190 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3191 else
3192 #endif
3193 #ifdef HAVE_cmpstrsi
3194 if (HAVE_cmpstrsi)
3195 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3196 else
3197 #endif
3198 return 0;
3199
3200 /* If we don't have POINTER_TYPE, call the function. */
3201 if (arg1_align == 0 || arg2_align == 0)
3202 return 0;
3203
3204 /* Make a place to write the result of the instruction. */
3205 result = target;
3206 if (! (result != 0
3207 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3208 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3209 result = gen_reg_rtx (insn_mode);
3210
3211 arg1_rtx = get_memory_rtx (arg1);
3212 arg2_rtx = get_memory_rtx (arg2);
3213 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3214 #ifdef HAVE_cmpmemsi
3215 if (HAVE_cmpmemsi)
3216 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3217 GEN_INT (MIN (arg1_align, arg2_align)));
3218 else
3219 #endif
3220 #ifdef HAVE_cmpstrsi
3221 if (HAVE_cmpstrsi)
3222 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3223 GEN_INT (MIN (arg1_align, arg2_align)));
3224 else
3225 #endif
3226 abort ();
3227
3228 if (insn)
3229 emit_insn (insn);
3230 else
3231 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3232 TYPE_MODE (integer_type_node), 3,
3233 XEXP (arg1_rtx, 0), Pmode,
3234 XEXP (arg2_rtx, 0), Pmode,
3235 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3236 TREE_UNSIGNED (sizetype)),
3237 TYPE_MODE (sizetype));
3238
3239 /* Return the value in the proper mode for this function. */
3240 mode = TYPE_MODE (TREE_TYPE (exp));
3241 if (GET_MODE (result) == mode)
3242 return result;
3243 else if (target != 0)
3244 {
3245 convert_move (target, result, 0);
3246 return target;
3247 }
3248 else
3249 return convert_to_mode (mode, result, 0);
3250 }
3251 #endif
3252
3253 return 0;
3254 }
3255
3256 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3257 if we failed the caller should emit a normal call, otherwise try to get
3258 the result in TARGET, if convenient. */
3259
3260 static rtx
3261 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3262 {
3263 tree arglist = TREE_OPERAND (exp, 1);
3264 tree arg1, arg2;
3265 const char *p1, *p2;
3266
3267 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3268 return 0;
3269
3270 arg1 = TREE_VALUE (arglist);
3271 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3272
3273 /* If both arguments are equal (and not volatile), return zero. */
3274 if (operand_equal_p (arg1, arg2, 0))
3275 return const0_rtx;
3276
3277 p1 = c_getstr (arg1);
3278 p2 = c_getstr (arg2);
3279
3280 if (p1 && p2)
3281 {
3282 const int i = strcmp (p1, p2);
3283 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3284 }
3285
3286 /* If either arg is "", return an expression corresponding to
3287 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3288 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3289 {
3290 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3291 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3292 tree ind1 =
3293 fold (build1 (CONVERT_EXPR, integer_type_node,
3294 build1 (INDIRECT_REF, cst_uchar_node,
3295 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3296 tree ind2 =
3297 fold (build1 (CONVERT_EXPR, integer_type_node,
3298 build1 (INDIRECT_REF, cst_uchar_node,
3299 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3300 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3301 return expand_expr (result, target, mode, EXPAND_NORMAL);
3302 }
3303
3304 #ifdef HAVE_cmpstrsi
3305 if (HAVE_cmpstrsi)
3306 {
3307 tree len, len1, len2;
3308 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3309 rtx result, insn;
3310 tree fndecl;
3311
3312 int arg1_align
3313 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3314 int arg2_align
3315 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3316 enum machine_mode insn_mode
3317 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3318
3319 len1 = c_strlen (arg1, 1);
3320 len2 = c_strlen (arg2, 1);
3321
3322 if (len1)
3323 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3324 if (len2)
3325 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3326
3327 /* If we don't have a constant length for the first, use the length
3328 of the second, if we know it. We don't require a constant for
3329 this case; some cost analysis could be done if both are available
3330 but neither is constant. For now, assume they're equally cheap,
3331 unless one has side effects. If both strings have constant lengths,
3332 use the smaller. */
3333
3334 if (!len1)
3335 len = len2;
3336 else if (!len2)
3337 len = len1;
3338 else if (TREE_SIDE_EFFECTS (len1))
3339 len = len2;
3340 else if (TREE_SIDE_EFFECTS (len2))
3341 len = len1;
3342 else if (TREE_CODE (len1) != INTEGER_CST)
3343 len = len2;
3344 else if (TREE_CODE (len2) != INTEGER_CST)
3345 len = len1;
3346 else if (tree_int_cst_lt (len1, len2))
3347 len = len1;
3348 else
3349 len = len2;
3350
3351 /* If both arguments have side effects, we cannot optimize. */
3352 if (!len || TREE_SIDE_EFFECTS (len))
3353 return 0;
3354
3355 /* If we don't have POINTER_TYPE, call the function. */
3356 if (arg1_align == 0 || arg2_align == 0)
3357 return 0;
3358
3359 /* Make a place to write the result of the instruction. */
3360 result = target;
3361 if (! (result != 0
3362 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3363 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3364 result = gen_reg_rtx (insn_mode);
3365
3366 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3367 arg1 = save_expr (arg1);
3368 arg2 = save_expr (arg2);
3369
3370 arg1_rtx = get_memory_rtx (arg1);
3371 arg2_rtx = get_memory_rtx (arg2);
3372 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3373 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3374 GEN_INT (MIN (arg1_align, arg2_align)));
3375 if (insn)
3376 {
3377 emit_insn (insn);
3378
3379 /* Return the value in the proper mode for this function. */
3380 mode = TYPE_MODE (TREE_TYPE (exp));
3381 if (GET_MODE (result) == mode)
3382 return result;
3383 if (target == 0)
3384 return convert_to_mode (mode, result, 0);
3385 convert_move (target, result, 0);
3386 return target;
3387 }
3388
3389 /* Expand the library call ourselves using a stabilized argument
3390 list to avoid re-evaluating the function's arguments twice. */
3391 arglist = build_tree_list (NULL_TREE, arg2);
3392 arglist = tree_cons (NULL_TREE, arg1, arglist);
3393 fndecl = get_callee_fndecl (exp);
3394 exp = build_function_call_expr (fndecl, arglist);
3395 return expand_call (exp, target, target == const0_rtx);
3396 }
3397 #endif
3398 return 0;
3399 }
3400
3401 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3402 if we failed the caller should emit a normal call, otherwise try to get
3403 the result in TARGET, if convenient. */
3404
3405 static rtx
3406 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3407 {
3408 tree arglist = TREE_OPERAND (exp, 1);
3409 tree arg1, arg2, arg3;
3410 const char *p1, *p2;
3411
3412 if (!validate_arglist (arglist,
3413 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3414 return 0;
3415
3416 arg1 = TREE_VALUE (arglist);
3417 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3418 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3419
3420 /* If the len parameter is zero, return zero. */
3421 if (integer_zerop (arg3))
3422 {
3423 /* Evaluate and ignore arg1 and arg2 in case they have
3424 side-effects. */
3425 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3426 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3427 return const0_rtx;
3428 }
3429
3430 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3431 if (operand_equal_p (arg1, arg2, 0))
3432 {
3433 /* Evaluate and ignore arg3 in case it has side-effects. */
3434 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3435 return const0_rtx;
3436 }
3437
3438 p1 = c_getstr (arg1);
3439 p2 = c_getstr (arg2);
3440
3441 /* If all arguments are constant, evaluate at compile-time. */
3442 if (host_integerp (arg3, 1) && p1 && p2)
3443 {
3444 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3445 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3446 }
3447
3448 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3449 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3450 if (host_integerp (arg3, 1)
3451 && (tree_low_cst (arg3, 1) == 1
3452 || (tree_low_cst (arg3, 1) > 1
3453 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3454 {
3455 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3456 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3457 tree ind1 =
3458 fold (build1 (CONVERT_EXPR, integer_type_node,
3459 build1 (INDIRECT_REF, cst_uchar_node,
3460 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3461 tree ind2 =
3462 fold (build1 (CONVERT_EXPR, integer_type_node,
3463 build1 (INDIRECT_REF, cst_uchar_node,
3464 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3465 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3466 return expand_expr (result, target, mode, EXPAND_NORMAL);
3467 }
3468
3469 /* If c_strlen can determine an expression for one of the string
3470 lengths, and it doesn't have side effects, then emit cmpstrsi
3471 using length MIN(strlen(string)+1, arg3). */
3472 #ifdef HAVE_cmpstrsi
3473 if (HAVE_cmpstrsi)
3474 {
3475 tree len, len1, len2;
3476 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3477 rtx result, insn;
3478 tree fndecl;
3479
3480 int arg1_align
3481 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3482 int arg2_align
3483 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3484 enum machine_mode insn_mode
3485 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3486
3487 len1 = c_strlen (arg1, 1);
3488 len2 = c_strlen (arg2, 1);
3489
3490 if (len1)
3491 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3492 if (len2)
3493 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3494
3495 /* If we don't have a constant length for the first, use the length
3496 of the second, if we know it. We don't require a constant for
3497 this case; some cost analysis could be done if both are available
3498 but neither is constant. For now, assume they're equally cheap,
3499 unless one has side effects. If both strings have constant lengths,
3500 use the smaller. */
3501
3502 if (!len1)
3503 len = len2;
3504 else if (!len2)
3505 len = len1;
3506 else if (TREE_SIDE_EFFECTS (len1))
3507 len = len2;
3508 else if (TREE_SIDE_EFFECTS (len2))
3509 len = len1;
3510 else if (TREE_CODE (len1) != INTEGER_CST)
3511 len = len2;
3512 else if (TREE_CODE (len2) != INTEGER_CST)
3513 len = len1;
3514 else if (tree_int_cst_lt (len1, len2))
3515 len = len1;
3516 else
3517 len = len2;
3518
3519 /* If both arguments have side effects, we cannot optimize. */
3520 if (!len || TREE_SIDE_EFFECTS (len))
3521 return 0;
3522
3523 /* The actual new length parameter is MIN(len,arg3). */
3524 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3525
3526 /* If we don't have POINTER_TYPE, call the function. */
3527 if (arg1_align == 0 || arg2_align == 0)
3528 return 0;
3529
3530 /* Make a place to write the result of the instruction. */
3531 result = target;
3532 if (! (result != 0
3533 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3534 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3535 result = gen_reg_rtx (insn_mode);
3536
3537 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3538 arg1 = save_expr (arg1);
3539 arg2 = save_expr (arg2);
3540 len = save_expr (len);
3541
3542 arg1_rtx = get_memory_rtx (arg1);
3543 arg2_rtx = get_memory_rtx (arg2);
3544 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3545 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3546 GEN_INT (MIN (arg1_align, arg2_align)));
3547 if (insn)
3548 {
3549 emit_insn (insn);
3550
3551 /* Return the value in the proper mode for this function. */
3552 mode = TYPE_MODE (TREE_TYPE (exp));
3553 if (GET_MODE (result) == mode)
3554 return result;
3555 if (target == 0)
3556 return convert_to_mode (mode, result, 0);
3557 convert_move (target, result, 0);
3558 return target;
3559 }
3560
3561 /* Expand the library call ourselves using a stabilized argument
3562 list to avoid re-evaluating the function's arguments twice. */
3563 arglist = build_tree_list (NULL_TREE, len);
3564 arglist = tree_cons (NULL_TREE, arg2, arglist);
3565 arglist = tree_cons (NULL_TREE, arg1, arglist);
3566 fndecl = get_callee_fndecl (exp);
3567 exp = build_function_call_expr (fndecl, arglist);
3568 return expand_call (exp, target, target == const0_rtx);
3569 }
3570 #endif
3571 return 0;
3572 }
3573
3574 /* Expand expression EXP, which is a call to the strcat builtin.
3575 Return 0 if we failed the caller should emit a normal call,
3576 otherwise try to get the result in TARGET, if convenient. */
3577
3578 static rtx
3579 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3580 {
3581 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3582 return 0;
3583 else
3584 {
3585 tree dst = TREE_VALUE (arglist),
3586 src = TREE_VALUE (TREE_CHAIN (arglist));
3587 const char *p = c_getstr (src);
3588
3589 if (p)
3590 {
3591 /* If the string length is zero, return the dst parameter. */
3592 if (*p == '\0')
3593 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3594 else if (!optimize_size)
3595 {
3596 /* Otherwise if !optimize_size, see if we can store by
3597 pieces into (dst + strlen(dst)). */
3598 tree newdst, arglist,
3599 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3600
3601 /* This is the length argument. */
3602 arglist = build_tree_list (NULL_TREE,
3603 fold (size_binop (PLUS_EXPR,
3604 c_strlen (src, 0),
3605 ssize_int (1))));
3606 /* Prepend src argument. */
3607 arglist = tree_cons (NULL_TREE, src, arglist);
3608
3609 /* We're going to use dst more than once. */
3610 dst = save_expr (dst);
3611
3612 /* Create strlen (dst). */
3613 newdst =
3614 fold (build_function_call_expr (strlen_fn,
3615 build_tree_list (NULL_TREE,
3616 dst)));
3617 /* Create (dst + strlen (dst)). */
3618 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3619
3620 /* Prepend the new dst argument. */
3621 arglist = tree_cons (NULL_TREE, newdst, arglist);
3622
3623 /* We don't want to get turned into a memcpy if the
3624 target is const0_rtx, i.e. when the return value
3625 isn't used. That would produce pessimized code so
3626 pass in a target of zero, it should never actually be
3627 used. If this was successful return the original
3628 dst, not the result of mempcpy. */
3629 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3630 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3631 else
3632 return 0;
3633 }
3634 }
3635
3636 return 0;
3637 }
3638 }
3639
3640 /* Expand expression EXP, which is a call to the strncat builtin.
3641 Return 0 if we failed the caller should emit a normal call,
3642 otherwise try to get the result in TARGET, if convenient. */
3643
3644 static rtx
3645 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3646 {
3647 if (!validate_arglist (arglist,
3648 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3649 return 0;
3650 else
3651 {
3652 tree dst = TREE_VALUE (arglist),
3653 src = TREE_VALUE (TREE_CHAIN (arglist)),
3654 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3655 const char *p = c_getstr (src);
3656
3657 /* If the requested length is zero, or the src parameter string
3658 length is zero, return the dst parameter. */
3659 if (integer_zerop (len) || (p && *p == '\0'))
3660 {
3661 /* Evaluate and ignore the src and len parameters in case
3662 they have side-effects. */
3663 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3664 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3665 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3666 }
3667
3668 /* If the requested len is greater than or equal to the string
3669 length, call strcat. */
3670 if (TREE_CODE (len) == INTEGER_CST && p
3671 && compare_tree_int (len, strlen (p)) >= 0)
3672 {
3673 tree newarglist
3674 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3675 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3676
3677 /* If the replacement _DECL isn't initialized, don't do the
3678 transformation. */
3679 if (!fn)
3680 return 0;
3681
3682 return expand_expr (build_function_call_expr (fn, newarglist),
3683 target, mode, EXPAND_NORMAL);
3684 }
3685 return 0;
3686 }
3687 }
3688
3689 /* Expand expression EXP, which is a call to the strspn builtin.
3690 Return 0 if we failed the caller should emit a normal call,
3691 otherwise try to get the result in TARGET, if convenient. */
3692
3693 static rtx
3694 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3695 {
3696 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3697 return 0;
3698 else
3699 {
3700 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3701 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3702
3703 /* If both arguments are constants, evaluate at compile-time. */
3704 if (p1 && p2)
3705 {
3706 const size_t r = strspn (p1, p2);
3707 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3708 }
3709
3710 /* If either argument is "", return 0. */
3711 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3712 {
3713 /* Evaluate and ignore both arguments in case either one has
3714 side-effects. */
3715 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3716 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3717 return const0_rtx;
3718 }
3719 return 0;
3720 }
3721 }
3722
3723 /* Expand expression EXP, which is a call to the strcspn builtin.
3724 Return 0 if we failed the caller should emit a normal call,
3725 otherwise try to get the result in TARGET, if convenient. */
3726
3727 static rtx
3728 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3729 {
3730 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3731 return 0;
3732 else
3733 {
3734 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3735 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3736
3737 /* If both arguments are constants, evaluate at compile-time. */
3738 if (p1 && p2)
3739 {
3740 const size_t r = strcspn (p1, p2);
3741 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3742 }
3743
3744 /* If the first argument is "", return 0. */
3745 if (p1 && *p1 == '\0')
3746 {
3747 /* Evaluate and ignore argument s2 in case it has
3748 side-effects. */
3749 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3750 return const0_rtx;
3751 }
3752
3753 /* If the second argument is "", return __builtin_strlen(s1). */
3754 if (p2 && *p2 == '\0')
3755 {
3756 tree newarglist = build_tree_list (NULL_TREE, s1),
3757 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3758
3759 /* If the replacement _DECL isn't initialized, don't do the
3760 transformation. */
3761 if (!fn)
3762 return 0;
3763
3764 return expand_expr (build_function_call_expr (fn, newarglist),
3765 target, mode, EXPAND_NORMAL);
3766 }
3767 return 0;
3768 }
3769 }
3770
3771 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3772 if that's convenient. */
3773
3774 rtx
3775 expand_builtin_saveregs (void)
3776 {
3777 rtx val, seq;
3778
3779 /* Don't do __builtin_saveregs more than once in a function.
3780 Save the result of the first call and reuse it. */
3781 if (saveregs_value != 0)
3782 return saveregs_value;
3783
3784 /* When this function is called, it means that registers must be
3785 saved on entry to this function. So we migrate the call to the
3786 first insn of this function. */
3787
3788 start_sequence ();
3789
3790 /* Do whatever the machine needs done in this case. */
3791 val = targetm.calls.expand_builtin_saveregs ();
3792
3793 seq = get_insns ();
3794 end_sequence ();
3795
3796 saveregs_value = val;
3797
3798 /* Put the insns after the NOTE that starts the function. If this
3799 is inside a start_sequence, make the outer-level insn chain current, so
3800 the code is placed at the start of the function. */
3801 push_topmost_sequence ();
3802 emit_insn_after (seq, get_insns ());
3803 pop_topmost_sequence ();
3804
3805 return val;
3806 }
3807
3808 /* __builtin_args_info (N) returns word N of the arg space info
3809 for the current function. The number and meanings of words
3810 is controlled by the definition of CUMULATIVE_ARGS. */
3811
3812 static rtx
3813 expand_builtin_args_info (tree arglist)
3814 {
3815 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3816 int *word_ptr = (int *) &current_function_args_info;
3817
3818 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3819 abort ();
3820
3821 if (arglist != 0)
3822 {
3823 if (!host_integerp (TREE_VALUE (arglist), 0))
3824 error ("argument of `__builtin_args_info' must be constant");
3825 else
3826 {
3827 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3828
3829 if (wordnum < 0 || wordnum >= nwords)
3830 error ("argument of `__builtin_args_info' out of range");
3831 else
3832 return GEN_INT (word_ptr[wordnum]);
3833 }
3834 }
3835 else
3836 error ("missing argument in `__builtin_args_info'");
3837
3838 return const0_rtx;
3839 }
3840
3841 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3842
3843 static rtx
3844 expand_builtin_next_arg (tree arglist)
3845 {
3846 tree fntype = TREE_TYPE (current_function_decl);
3847
3848 if (TYPE_ARG_TYPES (fntype) == 0
3849 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3850 == void_type_node))
3851 {
3852 error ("`va_start' used in function with fixed args");
3853 return const0_rtx;
3854 }
3855
3856 if (arglist)
3857 {
3858 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3859 tree arg = TREE_VALUE (arglist);
3860
3861 /* Strip off all nops for the sake of the comparison. This
3862 is not quite the same as STRIP_NOPS. It does more.
3863 We must also strip off INDIRECT_EXPR for C++ reference
3864 parameters. */
3865 while (TREE_CODE (arg) == NOP_EXPR
3866 || TREE_CODE (arg) == CONVERT_EXPR
3867 || TREE_CODE (arg) == NON_LVALUE_EXPR
3868 || TREE_CODE (arg) == INDIRECT_REF)
3869 arg = TREE_OPERAND (arg, 0);
3870 if (arg != last_parm)
3871 warning ("second parameter of `va_start' not last named argument");
3872 }
3873 else
3874 /* Evidently an out of date version of <stdarg.h>; can't validate
3875 va_start's second argument, but can still work as intended. */
3876 warning ("`__builtin_next_arg' called without an argument");
3877
3878 return expand_binop (Pmode, add_optab,
3879 current_function_internal_arg_pointer,
3880 current_function_arg_offset_rtx,
3881 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3882 }
3883
3884 /* Make it easier for the backends by protecting the valist argument
3885 from multiple evaluations. */
3886
3887 static tree
3888 stabilize_va_list (tree valist, int needs_lvalue)
3889 {
3890 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3891 {
3892 if (TREE_SIDE_EFFECTS (valist))
3893 valist = save_expr (valist);
3894
3895 /* For this case, the backends will be expecting a pointer to
3896 TREE_TYPE (va_list_type_node), but it's possible we've
3897 actually been given an array (an actual va_list_type_node).
3898 So fix it. */
3899 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3900 {
3901 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3902 tree p2 = build_pointer_type (va_list_type_node);
3903
3904 valist = build1 (ADDR_EXPR, p2, valist);
3905 valist = fold (build1 (NOP_EXPR, p1, valist));
3906 }
3907 }
3908 else
3909 {
3910 tree pt;
3911
3912 if (! needs_lvalue)
3913 {
3914 if (! TREE_SIDE_EFFECTS (valist))
3915 return valist;
3916
3917 pt = build_pointer_type (va_list_type_node);
3918 valist = fold (build1 (ADDR_EXPR, pt, valist));
3919 TREE_SIDE_EFFECTS (valist) = 1;
3920 }
3921
3922 if (TREE_SIDE_EFFECTS (valist))
3923 valist = save_expr (valist);
3924 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3925 valist));
3926 }
3927
3928 return valist;
3929 }
3930
3931 /* The "standard" definition of va_list is void*. */
3932
3933 tree
3934 std_build_builtin_va_list (void)
3935 {
3936 return ptr_type_node;
3937 }
3938
3939 /* The "standard" implementation of va_start: just assign `nextarg' to
3940 the variable. */
3941
3942 void
3943 std_expand_builtin_va_start (tree valist, rtx nextarg)
3944 {
3945 tree t;
3946
3947 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3948 make_tree (ptr_type_node, nextarg));
3949 TREE_SIDE_EFFECTS (t) = 1;
3950
3951 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3952 }
3953
3954 /* Expand ARGLIST, from a call to __builtin_va_start. */
3955
3956 static rtx
3957 expand_builtin_va_start (tree arglist)
3958 {
3959 rtx nextarg;
3960 tree chain, valist;
3961
3962 chain = TREE_CHAIN (arglist);
3963
3964 if (TREE_CHAIN (chain))
3965 error ("too many arguments to function `va_start'");
3966
3967 nextarg = expand_builtin_next_arg (chain);
3968 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3969
3970 #ifdef EXPAND_BUILTIN_VA_START
3971 EXPAND_BUILTIN_VA_START (valist, nextarg);
3972 #else
3973 std_expand_builtin_va_start (valist, nextarg);
3974 #endif
3975
3976 return const0_rtx;
3977 }
3978
3979 /* The "standard" implementation of va_arg: read the value from the
3980 current (padded) address and increment by the (padded) size. */
3981
3982 rtx
3983 std_expand_builtin_va_arg (tree valist, tree type)
3984 {
3985 tree addr_tree, t, type_size = NULL;
3986 tree align, alignm1;
3987 tree rounded_size;
3988 rtx addr;
3989 HOST_WIDE_INT boundary;
3990
3991 /* Compute the rounded size of the type. */
3992 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3993 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3994 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
3995
3996 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
3997 requires greater alignment, we must perform dynamic alignment. */
3998
3999 if (boundary > PARM_BOUNDARY)
4000 {
4001 if (!PAD_VARARGS_DOWN)
4002 {
4003 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4004 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4005 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4006 TREE_SIDE_EFFECTS (t) = 1;
4007 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4008 }
4009 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4010 build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4011 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4012 TREE_SIDE_EFFECTS (t) = 1;
4013 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4014 }
4015 if (type == error_mark_node
4016 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4017 || TREE_OVERFLOW (type_size))
4018 rounded_size = size_zero_node;
4019 else
4020 rounded_size = fold (build (MULT_EXPR, sizetype,
4021 fold (build (TRUNC_DIV_EXPR, sizetype,
4022 fold (build (PLUS_EXPR, sizetype,
4023 type_size, alignm1)),
4024 align)),
4025 align));
4026
4027 /* Get AP. */
4028 addr_tree = valist;
4029 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4030 {
4031 /* Small args are padded downward. */
4032 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4033 fold (build (COND_EXPR, sizetype,
4034 fold (build (GT_EXPR, sizetype,
4035 rounded_size,
4036 align)),
4037 size_zero_node,
4038 fold (build (MINUS_EXPR, sizetype,
4039 rounded_size,
4040 type_size))))));
4041 }
4042
4043 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4044 addr = copy_to_reg (addr);
4045
4046 /* Compute new value for AP. */
4047 if (! integer_zerop (rounded_size))
4048 {
4049 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4050 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4051 rounded_size));
4052 TREE_SIDE_EFFECTS (t) = 1;
4053 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4054 }
4055
4056 return addr;
4057 }
4058
4059 /* Expand __builtin_va_arg, which is not really a builtin function, but
4060 a very special sort of operator. */
4061
4062 rtx
4063 expand_builtin_va_arg (tree valist, tree type)
4064 {
4065 rtx addr, result;
4066 tree promoted_type, want_va_type, have_va_type;
4067
4068 /* Verify that valist is of the proper type. */
4069
4070 want_va_type = va_list_type_node;
4071 have_va_type = TREE_TYPE (valist);
4072 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4073 {
4074 /* If va_list is an array type, the argument may have decayed
4075 to a pointer type, e.g. by being passed to another function.
4076 In that case, unwrap both types so that we can compare the
4077 underlying records. */
4078 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4079 || TREE_CODE (have_va_type) == POINTER_TYPE)
4080 {
4081 want_va_type = TREE_TYPE (want_va_type);
4082 have_va_type = TREE_TYPE (have_va_type);
4083 }
4084 }
4085 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4086 {
4087 error ("first argument to `va_arg' not of type `va_list'");
4088 addr = const0_rtx;
4089 }
4090
4091 /* Generate a diagnostic for requesting data of a type that cannot
4092 be passed through `...' due to type promotion at the call site. */
4093 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4094 != type)
4095 {
4096 const char *name = "<anonymous type>", *pname = 0;
4097 static bool gave_help;
4098
4099 if (TYPE_NAME (type))
4100 {
4101 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4102 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4103 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4104 && DECL_NAME (TYPE_NAME (type)))
4105 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4106 }
4107 if (TYPE_NAME (promoted_type))
4108 {
4109 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4110 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4111 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4112 && DECL_NAME (TYPE_NAME (promoted_type)))
4113 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4114 }
4115
4116 /* Unfortunately, this is merely undefined, rather than a constraint
4117 violation, so we cannot make this an error. If this call is never
4118 executed, the program is still strictly conforming. */
4119 warning ("`%s' is promoted to `%s' when passed through `...'",
4120 name, pname);
4121 if (! gave_help)
4122 {
4123 gave_help = true;
4124 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4125 pname, name);
4126 }
4127
4128 /* We can, however, treat "undefined" any way we please.
4129 Call abort to encourage the user to fix the program. */
4130 inform ("if this code is reached, the program will abort");
4131 expand_builtin_trap ();
4132
4133 /* This is dead code, but go ahead and finish so that the
4134 mode of the result comes out right. */
4135 addr = const0_rtx;
4136 }
4137 else
4138 {
4139 /* Make it easier for the backends by protecting the valist argument
4140 from multiple evaluations. */
4141 valist = stabilize_va_list (valist, 0);
4142
4143 #ifdef EXPAND_BUILTIN_VA_ARG
4144 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4145 #else
4146 addr = std_expand_builtin_va_arg (valist, type);
4147 #endif
4148 }
4149
4150 addr = convert_memory_address (Pmode, addr);
4151
4152 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4153 set_mem_alias_set (result, get_varargs_alias_set ());
4154
4155 return result;
4156 }
4157
4158 /* Expand ARGLIST, from a call to __builtin_va_end. */
4159
4160 static rtx
4161 expand_builtin_va_end (tree arglist)
4162 {
4163 tree valist = TREE_VALUE (arglist);
4164
4165 /* Evaluate for side effects, if needed. I hate macros that don't
4166 do that. */
4167 if (TREE_SIDE_EFFECTS (valist))
4168 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4169
4170 return const0_rtx;
4171 }
4172
4173 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4174 builtin rather than just as an assignment in stdarg.h because of the
4175 nastiness of array-type va_list types. */
4176
4177 static rtx
4178 expand_builtin_va_copy (tree arglist)
4179 {
4180 tree dst, src, t;
4181
4182 dst = TREE_VALUE (arglist);
4183 src = TREE_VALUE (TREE_CHAIN (arglist));
4184
4185 dst = stabilize_va_list (dst, 1);
4186 src = stabilize_va_list (src, 0);
4187
4188 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4189 {
4190 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4191 TREE_SIDE_EFFECTS (t) = 1;
4192 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4193 }
4194 else
4195 {
4196 rtx dstb, srcb, size;
4197
4198 /* Evaluate to pointers. */
4199 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4200 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4201 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4202 VOIDmode, EXPAND_NORMAL);
4203
4204 dstb = convert_memory_address (Pmode, dstb);
4205 srcb = convert_memory_address (Pmode, srcb);
4206
4207 /* "Dereference" to BLKmode memories. */
4208 dstb = gen_rtx_MEM (BLKmode, dstb);
4209 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4210 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4211 srcb = gen_rtx_MEM (BLKmode, srcb);
4212 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4213 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4214
4215 /* Copy. */
4216 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4217 }
4218
4219 return const0_rtx;
4220 }
4221
4222 /* Expand a call to one of the builtin functions __builtin_frame_address or
4223 __builtin_return_address. */
4224
4225 static rtx
4226 expand_builtin_frame_address (tree fndecl, tree arglist)
4227 {
4228 /* The argument must be a nonnegative integer constant.
4229 It counts the number of frames to scan up the stack.
4230 The value is the return address saved in that frame. */
4231 if (arglist == 0)
4232 /* Warning about missing arg was already issued. */
4233 return const0_rtx;
4234 else if (! host_integerp (TREE_VALUE (arglist), 1))
4235 {
4236 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4237 error ("invalid arg to `__builtin_frame_address'");
4238 else
4239 error ("invalid arg to `__builtin_return_address'");
4240 return const0_rtx;
4241 }
4242 else
4243 {
4244 rtx tem
4245 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4246 tree_low_cst (TREE_VALUE (arglist), 1),
4247 hard_frame_pointer_rtx);
4248
4249 /* Some ports cannot access arbitrary stack frames. */
4250 if (tem == NULL)
4251 {
4252 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4253 warning ("unsupported arg to `__builtin_frame_address'");
4254 else
4255 warning ("unsupported arg to `__builtin_return_address'");
4256 return const0_rtx;
4257 }
4258
4259 /* For __builtin_frame_address, return what we've got. */
4260 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4261 return tem;
4262
4263 if (GET_CODE (tem) != REG
4264 && ! CONSTANT_P (tem))
4265 tem = copy_to_mode_reg (Pmode, tem);
4266 return tem;
4267 }
4268 }
4269
4270 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4271 we failed and the caller should emit a normal call, otherwise try to get
4272 the result in TARGET, if convenient. */
4273
4274 static rtx
4275 expand_builtin_alloca (tree arglist, rtx target)
4276 {
4277 rtx op0;
4278 rtx result;
4279
4280 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4281 return 0;
4282
4283 /* Compute the argument. */
4284 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4285
4286 /* Allocate the desired space. */
4287 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4288 result = convert_memory_address (ptr_mode, result);
4289
4290 return result;
4291 }
4292
4293 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4294 Return 0 if a normal call should be emitted rather than expanding the
4295 function in-line. If convenient, the result should be placed in TARGET.
4296 SUBTARGET may be used as the target for computing one of EXP's operands. */
4297
4298 static rtx
4299 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4300 rtx subtarget, optab op_optab)
4301 {
4302 rtx op0;
4303 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4304 return 0;
4305
4306 /* Compute the argument. */
4307 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4308 /* Compute op, into TARGET if possible.
4309 Set TARGET to wherever the result comes back. */
4310 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4311 op_optab, op0, target, 1);
4312 if (target == 0)
4313 abort ();
4314
4315 return convert_to_mode (target_mode, target, 0);
4316 }
4317
4318 /* If the string passed to fputs is a constant and is one character
4319 long, we attempt to transform this call into __builtin_fputc(). */
4320
4321 static rtx
4322 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4323 {
4324 tree len, fn;
4325 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4326 : implicit_built_in_decls[BUILT_IN_FPUTC];
4327 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4328 : implicit_built_in_decls[BUILT_IN_FWRITE];
4329
4330 /* If the return value is used, or the replacement _DECL isn't
4331 initialized, don't do the transformation. */
4332 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4333 return 0;
4334
4335 /* Verify the arguments in the original call. */
4336 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4337 return 0;
4338
4339 /* Get the length of the string passed to fputs. If the length
4340 can't be determined, punt. */
4341 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4342 || TREE_CODE (len) != INTEGER_CST)
4343 return 0;
4344
4345 switch (compare_tree_int (len, 1))
4346 {
4347 case -1: /* length is 0, delete the call entirely . */
4348 {
4349 /* Evaluate and ignore the argument in case it has
4350 side-effects. */
4351 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4352 VOIDmode, EXPAND_NORMAL);
4353 return const0_rtx;
4354 }
4355 case 0: /* length is 1, call fputc. */
4356 {
4357 const char *p = c_getstr (TREE_VALUE (arglist));
4358
4359 if (p != NULL)
4360 {
4361 /* New argument list transforming fputs(string, stream) to
4362 fputc(string[0], stream). */
4363 arglist =
4364 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4365 arglist =
4366 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4367 fn = fn_fputc;
4368 break;
4369 }
4370 }
4371 /* Fall through. */
4372 case 1: /* length is greater than 1, call fwrite. */
4373 {
4374 tree string_arg;
4375
4376 /* If optimizing for size keep fputs. */
4377 if (optimize_size)
4378 return 0;
4379 string_arg = TREE_VALUE (arglist);
4380 /* New argument list transforming fputs(string, stream) to
4381 fwrite(string, 1, len, stream). */
4382 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4383 arglist = tree_cons (NULL_TREE, len, arglist);
4384 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4385 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4386 fn = fn_fwrite;
4387 break;
4388 }
4389 default:
4390 abort ();
4391 }
4392
4393 return expand_expr (build_function_call_expr (fn, arglist),
4394 const0_rtx, VOIDmode, EXPAND_NORMAL);
4395 }
4396
4397 /* Expand a call to __builtin_expect. We return our argument and emit a
4398 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4399 a non-jump context. */
4400
4401 static rtx
4402 expand_builtin_expect (tree arglist, rtx target)
4403 {
4404 tree exp, c;
4405 rtx note, rtx_c;
4406
4407 if (arglist == NULL_TREE
4408 || TREE_CHAIN (arglist) == NULL_TREE)
4409 return const0_rtx;
4410 exp = TREE_VALUE (arglist);
4411 c = TREE_VALUE (TREE_CHAIN (arglist));
4412
4413 if (TREE_CODE (c) != INTEGER_CST)
4414 {
4415 error ("second arg to `__builtin_expect' must be a constant");
4416 c = integer_zero_node;
4417 }
4418
4419 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4420
4421 /* Don't bother with expected value notes for integral constants. */
4422 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4423 {
4424 /* We do need to force this into a register so that we can be
4425 moderately sure to be able to correctly interpret the branch
4426 condition later. */
4427 target = force_reg (GET_MODE (target), target);
4428
4429 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4430
4431 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4432 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4433 }
4434
4435 return target;
4436 }
4437
4438 /* Like expand_builtin_expect, except do this in a jump context. This is
4439 called from do_jump if the conditional is a __builtin_expect. Return either
4440 a list of insns to emit the jump or NULL if we cannot optimize
4441 __builtin_expect. We need to optimize this at jump time so that machines
4442 like the PowerPC don't turn the test into a SCC operation, and then jump
4443 based on the test being 0/1. */
4444
4445 rtx
4446 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4447 {
4448 tree arglist = TREE_OPERAND (exp, 1);
4449 tree arg0 = TREE_VALUE (arglist);
4450 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4451 rtx ret = NULL_RTX;
4452
4453 /* Only handle __builtin_expect (test, 0) and
4454 __builtin_expect (test, 1). */
4455 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4456 && (integer_zerop (arg1) || integer_onep (arg1)))
4457 {
4458 rtx insn, drop_through_label, temp;
4459
4460 /* Expand the jump insns. */
4461 start_sequence ();
4462 do_jump (arg0, if_false_label, if_true_label);
4463 ret = get_insns ();
4464
4465 drop_through_label = get_last_insn ();
4466 if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4467 drop_through_label = prev_nonnote_insn (drop_through_label);
4468 if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4469 drop_through_label = NULL_RTX;
4470 end_sequence ();
4471
4472 if (! if_true_label)
4473 if_true_label = drop_through_label;
4474 if (! if_false_label)
4475 if_false_label = drop_through_label;
4476
4477 /* Go through and add the expect's to each of the conditional jumps. */
4478 insn = ret;
4479 while (insn != NULL_RTX)
4480 {
4481 rtx next = NEXT_INSN (insn);
4482
4483 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4484 {
4485 rtx ifelse = SET_SRC (pc_set (insn));
4486 rtx then_dest = XEXP (ifelse, 1);
4487 rtx else_dest = XEXP (ifelse, 2);
4488 int taken = -1;
4489
4490 /* First check if we recognize any of the labels. */
4491 if (GET_CODE (then_dest) == LABEL_REF
4492 && XEXP (then_dest, 0) == if_true_label)
4493 taken = 1;
4494 else if (GET_CODE (then_dest) == LABEL_REF
4495 && XEXP (then_dest, 0) == if_false_label)
4496 taken = 0;
4497 else if (GET_CODE (else_dest) == LABEL_REF
4498 && XEXP (else_dest, 0) == if_false_label)
4499 taken = 1;
4500 else if (GET_CODE (else_dest) == LABEL_REF
4501 && XEXP (else_dest, 0) == if_true_label)
4502 taken = 0;
4503 /* Otherwise check where we drop through. */
4504 else if (else_dest == pc_rtx)
4505 {
4506 if (next && GET_CODE (next) == NOTE)
4507 next = next_nonnote_insn (next);
4508
4509 if (next && GET_CODE (next) == JUMP_INSN
4510 && any_uncondjump_p (next))
4511 temp = XEXP (SET_SRC (pc_set (next)), 0);
4512 else
4513 temp = next;
4514
4515 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4516 else that can't possibly match either target label. */
4517 if (temp == if_false_label)
4518 taken = 1;
4519 else if (temp == if_true_label)
4520 taken = 0;
4521 }
4522 else if (then_dest == pc_rtx)
4523 {
4524 if (next && GET_CODE (next) == NOTE)
4525 next = next_nonnote_insn (next);
4526
4527 if (next && GET_CODE (next) == JUMP_INSN
4528 && any_uncondjump_p (next))
4529 temp = XEXP (SET_SRC (pc_set (next)), 0);
4530 else
4531 temp = next;
4532
4533 if (temp == if_false_label)
4534 taken = 0;
4535 else if (temp == if_true_label)
4536 taken = 1;
4537 }
4538
4539 if (taken != -1)
4540 {
4541 /* If the test is expected to fail, reverse the
4542 probabilities. */
4543 if (integer_zerop (arg1))
4544 taken = 1 - taken;
4545 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4546 }
4547 }
4548
4549 insn = next;
4550 }
4551 }
4552
4553 return ret;
4554 }
4555
4556 void
4557 expand_builtin_trap (void)
4558 {
4559 #ifdef HAVE_trap
4560 if (HAVE_trap)
4561 emit_insn (gen_trap ());
4562 else
4563 #endif
4564 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4565 emit_barrier ();
4566 }
4567
4568 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4569 Return 0 if a normal call should be emitted rather than expanding
4570 the function inline. If convenient, the result should be placed
4571 in TARGET. SUBTARGET may be used as the target for computing
4572 the operand. */
4573
4574 static rtx
4575 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4576 {
4577 enum machine_mode mode;
4578 tree arg;
4579 rtx op0;
4580
4581 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4582 return 0;
4583
4584 arg = TREE_VALUE (arglist);
4585 mode = TYPE_MODE (TREE_TYPE (arg));
4586 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4587 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4588 }
4589
4590 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4591 Return 0 if a normal call should be emitted rather than expanding
4592 the function inline. If convenient, the result should be placed
4593 in target. */
4594
4595 static rtx
4596 expand_builtin_cabs (tree arglist, rtx target)
4597 {
4598 enum machine_mode mode;
4599 tree arg;
4600 rtx op0;
4601
4602 if (arglist == 0 || TREE_CHAIN (arglist))
4603 return 0;
4604 arg = TREE_VALUE (arglist);
4605 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4606 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4607 return 0;
4608
4609 mode = TYPE_MODE (TREE_TYPE (arg));
4610 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4611 return expand_complex_abs (mode, op0, target, 0);
4612 }
4613
4614 /* Create a new constant string literal and return a char* pointer to it.
4615 The STRING_CST value is the LEN characters at STR. */
4616 static tree
4617 build_string_literal (int len, const char *str)
4618 {
4619 tree t, elem, index, type;
4620
4621 t = build_string (len, str);
4622 elem = build_type_variant (char_type_node, 1, 0);
4623 index = build_index_type (build_int_2 (len - 1, 0));
4624 type = build_array_type (elem, index);
4625 TREE_TYPE (t) = type;
4626 TREE_CONSTANT (t) = 1;
4627 TREE_READONLY (t) = 1;
4628 TREE_STATIC (t) = 1;
4629
4630 type = build_pointer_type (type);
4631 t = build1 (ADDR_EXPR, type, t);
4632
4633 type = build_pointer_type (elem);
4634 t = build1 (NOP_EXPR, type, t);
4635 return t;
4636 }
4637
4638 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4639 Return 0 if a normal call should be emitted rather than transforming
4640 the function inline. If convenient, the result should be placed in
4641 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4642 call. */
4643 static rtx
4644 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4645 bool unlocked)
4646 {
4647 tree fn_putchar = unlocked
4648 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4649 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4650 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4651 : implicit_built_in_decls[BUILT_IN_PUTS];
4652 const char *fmt_str;
4653 tree fn, fmt, arg;
4654
4655 /* If the return value is used, don't do the transformation. */
4656 if (target != const0_rtx)
4657 return 0;
4658
4659 /* Verify the required arguments in the original call. */
4660 if (! arglist)
4661 return 0;
4662 fmt = TREE_VALUE (arglist);
4663 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4664 return 0;
4665 arglist = TREE_CHAIN (arglist);
4666
4667 /* Check whether the format is a literal string constant. */
4668 fmt_str = c_getstr (fmt);
4669 if (fmt_str == NULL)
4670 return 0;
4671
4672 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4673 if (strcmp (fmt_str, "%s\n") == 0)
4674 {
4675 if (! arglist
4676 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4677 || TREE_CHAIN (arglist))
4678 return 0;
4679 fn = fn_puts;
4680 }
4681 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4682 else if (strcmp (fmt_str, "%c") == 0)
4683 {
4684 if (! arglist
4685 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4686 || TREE_CHAIN (arglist))
4687 return 0;
4688 fn = fn_putchar;
4689 }
4690 else
4691 {
4692 /* We can't handle anything else with % args or %% ... yet. */
4693 if (strchr (fmt_str, '%'))
4694 return 0;
4695
4696 if (arglist)
4697 return 0;
4698
4699 /* If the format specifier was "", printf does nothing. */
4700 if (fmt_str[0] == '\0')
4701 return const0_rtx;
4702 /* If the format specifier has length of 1, call putchar. */
4703 if (fmt_str[1] == '\0')
4704 {
4705 /* Given printf("c"), (where c is any one character,)
4706 convert "c"[0] to an int and pass that to the replacement
4707 function. */
4708 arg = build_int_2 (fmt_str[0], 0);
4709 arglist = build_tree_list (NULL_TREE, arg);
4710 fn = fn_putchar;
4711 }
4712 else
4713 {
4714 /* If the format specifier was "string\n", call puts("string"). */
4715 size_t len = strlen (fmt_str);
4716 if (fmt_str[len - 1] == '\n')
4717 {
4718 /* Create a NUL-terminated string that's one char shorter
4719 than the original, stripping off the trailing '\n'. */
4720 char *newstr = (char *) alloca (len);
4721 memcpy (newstr, fmt_str, len - 1);
4722 newstr[len - 1] = 0;
4723
4724 arg = build_string_literal (len, newstr);
4725 arglist = build_tree_list (NULL_TREE, arg);
4726 fn = fn_puts;
4727 }
4728 else
4729 /* We'd like to arrange to call fputs(string,stdout) here,
4730 but we need stdout and don't have a way to get it yet. */
4731 return 0;
4732 }
4733 }
4734
4735 if (!fn)
4736 return 0;
4737 return expand_expr (build_function_call_expr (fn, arglist),
4738 target, mode, EXPAND_NORMAL);
4739 }
4740
4741 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4742 Return 0 if a normal call should be emitted rather than transforming
4743 the function inline. If convenient, the result should be placed in
4744 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4745 call. */
4746 static rtx
4747 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4748 bool unlocked)
4749 {
4750 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4751 : implicit_built_in_decls[BUILT_IN_FPUTC];
4752 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4753 : implicit_built_in_decls[BUILT_IN_FPUTS];
4754 const char *fmt_str;
4755 tree fn, fmt, fp, arg;
4756
4757 /* If the return value is used, don't do the transformation. */
4758 if (target != const0_rtx)
4759 return 0;
4760
4761 /* Verify the required arguments in the original call. */
4762 if (! arglist)
4763 return 0;
4764 fp = TREE_VALUE (arglist);
4765 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4766 return 0;
4767 arglist = TREE_CHAIN (arglist);
4768 if (! arglist)
4769 return 0;
4770 fmt = TREE_VALUE (arglist);
4771 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4772 return 0;
4773 arglist = TREE_CHAIN (arglist);
4774
4775 /* Check whether the format is a literal string constant. */
4776 fmt_str = c_getstr (fmt);
4777 if (fmt_str == NULL)
4778 return 0;
4779
4780 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4781 if (strcmp (fmt_str, "%s") == 0)
4782 {
4783 if (! arglist
4784 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4785 || TREE_CHAIN (arglist))
4786 return 0;
4787 arg = TREE_VALUE (arglist);
4788 arglist = build_tree_list (NULL_TREE, fp);
4789 arglist = tree_cons (NULL_TREE, arg, arglist);
4790 fn = fn_fputs;
4791 }
4792 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4793 else if (strcmp (fmt_str, "%c") == 0)
4794 {
4795 if (! arglist
4796 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4797 || TREE_CHAIN (arglist))
4798 return 0;
4799 arg = TREE_VALUE (arglist);
4800 arglist = build_tree_list (NULL_TREE, fp);
4801 arglist = tree_cons (NULL_TREE, arg, arglist);
4802 fn = fn_fputc;
4803 }
4804 else
4805 {
4806 /* We can't handle anything else with % args or %% ... yet. */
4807 if (strchr (fmt_str, '%'))
4808 return 0;
4809
4810 if (arglist)
4811 return 0;
4812
4813 /* If the format specifier was "", fprintf does nothing. */
4814 if (fmt_str[0] == '\0')
4815 {
4816 /* Evaluate and ignore FILE* argument for side-effects. */
4817 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4818 return const0_rtx;
4819 }
4820
4821 /* When "string" doesn't contain %, replace all cases of
4822 fprintf(stream,string) with fputs(string,stream). The fputs
4823 builtin will take care of special cases like length == 1. */
4824 arglist = build_tree_list (NULL_TREE, fp);
4825 arglist = tree_cons (NULL_TREE, fmt, arglist);
4826 fn = fn_fputs;
4827 }
4828
4829 if (!fn)
4830 return 0;
4831 return expand_expr (build_function_call_expr (fn, arglist),
4832 target, mode, EXPAND_NORMAL);
4833 }
4834
4835 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4836 a normal call should be emitted rather than expanding the function
4837 inline. If convenient, the result should be placed in TARGET with
4838 mode MODE. */
4839
4840 static rtx
4841 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4842 {
4843 tree orig_arglist, dest, fmt;
4844 const char *fmt_str;
4845
4846 orig_arglist = arglist;
4847
4848 /* Verify the required arguments in the original call. */
4849 if (! arglist)
4850 return 0;
4851 dest = TREE_VALUE (arglist);
4852 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4853 return 0;
4854 arglist = TREE_CHAIN (arglist);
4855 if (! arglist)
4856 return 0;
4857 fmt = TREE_VALUE (arglist);
4858 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4859 return 0;
4860 arglist = TREE_CHAIN (arglist);
4861
4862 /* Check whether the format is a literal string constant. */
4863 fmt_str = c_getstr (fmt);
4864 if (fmt_str == NULL)
4865 return 0;
4866
4867 /* If the format doesn't contain % args or %%, use strcpy. */
4868 if (strchr (fmt_str, '%') == 0)
4869 {
4870 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4871 tree exp;
4872
4873 if (arglist || ! fn)
4874 return 0;
4875 expand_expr (build_function_call_expr (fn, orig_arglist),
4876 const0_rtx, VOIDmode, EXPAND_NORMAL);
4877 if (target == const0_rtx)
4878 return const0_rtx;
4879 exp = build_int_2 (strlen (fmt_str), 0);
4880 exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4881 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4882 }
4883 /* If the format is "%s", use strcpy if the result isn't used. */
4884 else if (strcmp (fmt_str, "%s") == 0)
4885 {
4886 tree fn, arg, len;
4887 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4888
4889 if (! fn)
4890 return 0;
4891
4892 if (! arglist || TREE_CHAIN (arglist))
4893 return 0;
4894 arg = TREE_VALUE (arglist);
4895 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4896 return 0;
4897
4898 if (target != const0_rtx)
4899 {
4900 len = c_strlen (arg, 1);
4901 if (! len || TREE_CODE (len) != INTEGER_CST)
4902 return 0;
4903 }
4904 else
4905 len = NULL_TREE;
4906
4907 arglist = build_tree_list (NULL_TREE, arg);
4908 arglist = tree_cons (NULL_TREE, dest, arglist);
4909 expand_expr (build_function_call_expr (fn, arglist),
4910 const0_rtx, VOIDmode, EXPAND_NORMAL);
4911
4912 if (target == const0_rtx)
4913 return const0_rtx;
4914 return expand_expr (len, target, mode, EXPAND_NORMAL);
4915 }
4916
4917 return 0;
4918 }
4919
4920 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4921 Return NULL_RTX if a normal call should be emitted rather than expanding
4922 the function in-line. EXP is the expression that is a call to the builtin
4923 function; if convenient, the result should be placed in TARGET. */
4924
4925 static rtx
4926 expand_builtin_signbit (tree exp, rtx target)
4927 {
4928 const struct real_format *fmt;
4929 enum machine_mode fmode, imode, rmode;
4930 HOST_WIDE_INT hi, lo;
4931 tree arg, arglist;
4932 int bitpos;
4933 rtx temp;
4934
4935 arglist = TREE_OPERAND (exp, 1);
4936 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4937 return 0;
4938
4939 arg = TREE_VALUE (arglist);
4940 fmode = TYPE_MODE (TREE_TYPE (arg));
4941 rmode = TYPE_MODE (TREE_TYPE (exp));
4942 fmt = REAL_MODE_FORMAT (fmode);
4943
4944 /* For floating point formats without a sign bit, implement signbit
4945 as "ARG < 0.0". */
4946 if (fmt->signbit < 0)
4947 {
4948 /* But we can't do this if the format supports signed zero. */
4949 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4950 return 0;
4951
4952 arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
4953 build_real (TREE_TYPE (arg), dconst0)));
4954 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4955 }
4956
4957 imode = int_mode_for_mode (fmode);
4958 if (imode == BLKmode)
4959 return 0;
4960
4961 bitpos = fmt->signbit;
4962 /* Handle targets with different FP word orders. */
4963 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4964 {
4965 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4966 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4967 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4968 }
4969
4970 /* If the sign bit is not in the lowpart and the floating point format
4971 is wider than an integer, check that is twice the size of an integer
4972 so that we can use gen_highpart below. */
4973 if (bitpos >= GET_MODE_BITSIZE (rmode)
4974 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4975 return 0;
4976
4977 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4978 temp = gen_lowpart (imode, temp);
4979
4980 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4981 {
4982 if (BITS_BIG_ENDIAN)
4983 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
4984 temp = copy_to_mode_reg (imode, temp);
4985 temp = extract_bit_field (temp, 1, bitpos, 1,
4986 NULL_RTX, rmode, rmode,
4987 GET_MODE_SIZE (imode));
4988 }
4989 else
4990 {
4991 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
4992 temp = gen_lowpart (rmode, temp);
4993 if (bitpos < HOST_BITS_PER_WIDE_INT)
4994 {
4995 hi = 0;
4996 lo = (HOST_WIDE_INT) 1 << bitpos;
4997 }
4998 else
4999 {
5000 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5001 lo = 0;
5002 }
5003
5004 temp = force_reg (rmode, temp);
5005 temp = expand_binop (rmode, and_optab, temp,
5006 immed_double_const (lo, hi, rmode),
5007 target, 1, OPTAB_LIB_WIDEN);
5008 }
5009 return temp;
5010 }
5011 \f
5012 /* Expand an expression EXP that calls a built-in function,
5013 with result going to TARGET if that's convenient
5014 (and in mode MODE if that's convenient).
5015 SUBTARGET may be used as the target for computing one of EXP's operands.
5016 IGNORE is nonzero if the value is to be ignored. */
5017
5018 rtx
5019 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5020 int ignore)
5021 {
5022 tree fndecl = get_callee_fndecl (exp);
5023 tree arglist = TREE_OPERAND (exp, 1);
5024 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5025 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5026
5027 /* Perform postincrements before expanding builtin functions. */
5028 emit_queue ();
5029
5030 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5031 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
5032
5033 /* When not optimizing, generate calls to library functions for a certain
5034 set of builtins. */
5035 if (!optimize
5036 && !CALLED_AS_BUILT_IN (fndecl)
5037 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5038 && fcode != BUILT_IN_ALLOCA)
5039 return expand_call (exp, target, ignore);
5040
5041 /* The built-in function expanders test for target == const0_rtx
5042 to determine whether the function's result will be ignored. */
5043 if (ignore)
5044 target = const0_rtx;
5045
5046 /* If the result of a pure or const built-in function is ignored, and
5047 none of its arguments are volatile, we can avoid expanding the
5048 built-in call and just evaluate the arguments for side-effects. */
5049 if (target == const0_rtx
5050 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5051 {
5052 bool volatilep = false;
5053 tree arg;
5054
5055 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5056 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5057 {
5058 volatilep = true;
5059 break;
5060 }
5061
5062 if (! volatilep)
5063 {
5064 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5065 expand_expr (TREE_VALUE (arg), const0_rtx,
5066 VOIDmode, EXPAND_NORMAL);
5067 return const0_rtx;
5068 }
5069 }
5070
5071 switch (fcode)
5072 {
5073 case BUILT_IN_ABS:
5074 case BUILT_IN_LABS:
5075 case BUILT_IN_LLABS:
5076 case BUILT_IN_IMAXABS:
5077 /* build_function_call changes these into ABS_EXPR. */
5078 abort ();
5079
5080 case BUILT_IN_FABS:
5081 case BUILT_IN_FABSF:
5082 case BUILT_IN_FABSL:
5083 target = expand_builtin_fabs (arglist, target, subtarget);
5084 if (target)
5085 return target;
5086 break;
5087
5088 case BUILT_IN_CABS:
5089 case BUILT_IN_CABSF:
5090 case BUILT_IN_CABSL:
5091 if (flag_unsafe_math_optimizations)
5092 {
5093 target = expand_builtin_cabs (arglist, target);
5094 if (target)
5095 return target;
5096 }
5097 break;
5098
5099 case BUILT_IN_CONJ:
5100 case BUILT_IN_CONJF:
5101 case BUILT_IN_CONJL:
5102 case BUILT_IN_CREAL:
5103 case BUILT_IN_CREALF:
5104 case BUILT_IN_CREALL:
5105 case BUILT_IN_CIMAG:
5106 case BUILT_IN_CIMAGF:
5107 case BUILT_IN_CIMAGL:
5108 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5109 and IMAGPART_EXPR. */
5110 abort ();
5111
5112 case BUILT_IN_SIN:
5113 case BUILT_IN_SINF:
5114 case BUILT_IN_SINL:
5115 case BUILT_IN_COS:
5116 case BUILT_IN_COSF:
5117 case BUILT_IN_COSL:
5118 case BUILT_IN_EXP:
5119 case BUILT_IN_EXPF:
5120 case BUILT_IN_EXPL:
5121 case BUILT_IN_EXP10:
5122 case BUILT_IN_EXP10F:
5123 case BUILT_IN_EXP10L:
5124 case BUILT_IN_POW10:
5125 case BUILT_IN_POW10F:
5126 case BUILT_IN_POW10L:
5127 case BUILT_IN_EXP2:
5128 case BUILT_IN_EXP2F:
5129 case BUILT_IN_EXP2L:
5130 case BUILT_IN_LOG:
5131 case BUILT_IN_LOGF:
5132 case BUILT_IN_LOGL:
5133 case BUILT_IN_LOG10:
5134 case BUILT_IN_LOG10F:
5135 case BUILT_IN_LOG10L:
5136 case BUILT_IN_LOG2:
5137 case BUILT_IN_LOG2F:
5138 case BUILT_IN_LOG2L:
5139 case BUILT_IN_TAN:
5140 case BUILT_IN_TANF:
5141 case BUILT_IN_TANL:
5142 case BUILT_IN_ATAN:
5143 case BUILT_IN_ATANF:
5144 case BUILT_IN_ATANL:
5145 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5146 because of possible accuracy problems. */
5147 if (! flag_unsafe_math_optimizations)
5148 break;
5149 case BUILT_IN_SQRT:
5150 case BUILT_IN_SQRTF:
5151 case BUILT_IN_SQRTL:
5152 case BUILT_IN_FLOOR:
5153 case BUILT_IN_FLOORF:
5154 case BUILT_IN_FLOORL:
5155 case BUILT_IN_CEIL:
5156 case BUILT_IN_CEILF:
5157 case BUILT_IN_CEILL:
5158 case BUILT_IN_TRUNC:
5159 case BUILT_IN_TRUNCF:
5160 case BUILT_IN_TRUNCL:
5161 case BUILT_IN_ROUND:
5162 case BUILT_IN_ROUNDF:
5163 case BUILT_IN_ROUNDL:
5164 case BUILT_IN_NEARBYINT:
5165 case BUILT_IN_NEARBYINTF:
5166 case BUILT_IN_NEARBYINTL:
5167 target = expand_builtin_mathfn (exp, target, subtarget);
5168 if (target)
5169 return target;
5170 break;
5171
5172 case BUILT_IN_POW:
5173 case BUILT_IN_POWF:
5174 case BUILT_IN_POWL:
5175 target = expand_builtin_pow (exp, target, subtarget);
5176 if (target)
5177 return target;
5178 break;
5179
5180 case BUILT_IN_ATAN2:
5181 case BUILT_IN_ATAN2F:
5182 case BUILT_IN_ATAN2L:
5183 if (! flag_unsafe_math_optimizations)
5184 break;
5185 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5186 if (target)
5187 return target;
5188 break;
5189
5190 case BUILT_IN_APPLY_ARGS:
5191 return expand_builtin_apply_args ();
5192
5193 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5194 FUNCTION with a copy of the parameters described by
5195 ARGUMENTS, and ARGSIZE. It returns a block of memory
5196 allocated on the stack into which is stored all the registers
5197 that might possibly be used for returning the result of a
5198 function. ARGUMENTS is the value returned by
5199 __builtin_apply_args. ARGSIZE is the number of bytes of
5200 arguments that must be copied. ??? How should this value be
5201 computed? We'll also need a safe worst case value for varargs
5202 functions. */
5203 case BUILT_IN_APPLY:
5204 if (!validate_arglist (arglist, POINTER_TYPE,
5205 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5206 && !validate_arglist (arglist, REFERENCE_TYPE,
5207 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5208 return const0_rtx;
5209 else
5210 {
5211 int i;
5212 tree t;
5213 rtx ops[3];
5214
5215 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5216 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5217
5218 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5219 }
5220
5221 /* __builtin_return (RESULT) causes the function to return the
5222 value described by RESULT. RESULT is address of the block of
5223 memory returned by __builtin_apply. */
5224 case BUILT_IN_RETURN:
5225 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5226 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5227 NULL_RTX, VOIDmode, 0));
5228 return const0_rtx;
5229
5230 case BUILT_IN_SAVEREGS:
5231 return expand_builtin_saveregs ();
5232
5233 case BUILT_IN_ARGS_INFO:
5234 return expand_builtin_args_info (arglist);
5235
5236 /* Return the address of the first anonymous stack arg. */
5237 case BUILT_IN_NEXT_ARG:
5238 return expand_builtin_next_arg (arglist);
5239
5240 case BUILT_IN_CLASSIFY_TYPE:
5241 return expand_builtin_classify_type (arglist);
5242
5243 case BUILT_IN_CONSTANT_P:
5244 return expand_builtin_constant_p (arglist, target_mode);
5245
5246 case BUILT_IN_FRAME_ADDRESS:
5247 case BUILT_IN_RETURN_ADDRESS:
5248 return expand_builtin_frame_address (fndecl, arglist);
5249
5250 /* Returns the address of the area where the structure is returned.
5251 0 otherwise. */
5252 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5253 if (arglist != 0
5254 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5255 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5256 return const0_rtx;
5257 else
5258 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5259
5260 case BUILT_IN_ALLOCA:
5261 target = expand_builtin_alloca (arglist, target);
5262 if (target)
5263 return target;
5264 break;
5265
5266 case BUILT_IN_FFS:
5267 case BUILT_IN_FFSL:
5268 case BUILT_IN_FFSLL:
5269 target = expand_builtin_unop (target_mode, arglist, target,
5270 subtarget, ffs_optab);
5271 if (target)
5272 return target;
5273 break;
5274
5275 case BUILT_IN_CLZ:
5276 case BUILT_IN_CLZL:
5277 case BUILT_IN_CLZLL:
5278 target = expand_builtin_unop (target_mode, arglist, target,
5279 subtarget, clz_optab);
5280 if (target)
5281 return target;
5282 break;
5283
5284 case BUILT_IN_CTZ:
5285 case BUILT_IN_CTZL:
5286 case BUILT_IN_CTZLL:
5287 target = expand_builtin_unop (target_mode, arglist, target,
5288 subtarget, ctz_optab);
5289 if (target)
5290 return target;
5291 break;
5292
5293 case BUILT_IN_POPCOUNT:
5294 case BUILT_IN_POPCOUNTL:
5295 case BUILT_IN_POPCOUNTLL:
5296 target = expand_builtin_unop (target_mode, arglist, target,
5297 subtarget, popcount_optab);
5298 if (target)
5299 return target;
5300 break;
5301
5302 case BUILT_IN_PARITY:
5303 case BUILT_IN_PARITYL:
5304 case BUILT_IN_PARITYLL:
5305 target = expand_builtin_unop (target_mode, arglist, target,
5306 subtarget, parity_optab);
5307 if (target)
5308 return target;
5309 break;
5310
5311 case BUILT_IN_STRLEN:
5312 target = expand_builtin_strlen (arglist, target, target_mode);
5313 if (target)
5314 return target;
5315 break;
5316
5317 case BUILT_IN_STRCPY:
5318 target = expand_builtin_strcpy (arglist, target, mode);
5319 if (target)
5320 return target;
5321 break;
5322
5323 case BUILT_IN_STRNCPY:
5324 target = expand_builtin_strncpy (arglist, target, mode);
5325 if (target)
5326 return target;
5327 break;
5328
5329 case BUILT_IN_STPCPY:
5330 target = expand_builtin_stpcpy (arglist, target, mode);
5331 if (target)
5332 return target;
5333 break;
5334
5335 case BUILT_IN_STRCAT:
5336 target = expand_builtin_strcat (arglist, target, mode);
5337 if (target)
5338 return target;
5339 break;
5340
5341 case BUILT_IN_STRNCAT:
5342 target = expand_builtin_strncat (arglist, target, mode);
5343 if (target)
5344 return target;
5345 break;
5346
5347 case BUILT_IN_STRSPN:
5348 target = expand_builtin_strspn (arglist, target, mode);
5349 if (target)
5350 return target;
5351 break;
5352
5353 case BUILT_IN_STRCSPN:
5354 target = expand_builtin_strcspn (arglist, target, mode);
5355 if (target)
5356 return target;
5357 break;
5358
5359 case BUILT_IN_STRSTR:
5360 target = expand_builtin_strstr (arglist, target, mode);
5361 if (target)
5362 return target;
5363 break;
5364
5365 case BUILT_IN_STRPBRK:
5366 target = expand_builtin_strpbrk (arglist, target, mode);
5367 if (target)
5368 return target;
5369 break;
5370
5371 case BUILT_IN_INDEX:
5372 case BUILT_IN_STRCHR:
5373 target = expand_builtin_strchr (arglist, target, mode);
5374 if (target)
5375 return target;
5376 break;
5377
5378 case BUILT_IN_RINDEX:
5379 case BUILT_IN_STRRCHR:
5380 target = expand_builtin_strrchr (arglist, target, mode);
5381 if (target)
5382 return target;
5383 break;
5384
5385 case BUILT_IN_MEMCPY:
5386 target = expand_builtin_memcpy (arglist, target, mode);
5387 if (target)
5388 return target;
5389 break;
5390
5391 case BUILT_IN_MEMPCPY:
5392 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5393 if (target)
5394 return target;
5395 break;
5396
5397 case BUILT_IN_MEMMOVE:
5398 target = expand_builtin_memmove (arglist, target, mode);
5399 if (target)
5400 return target;
5401 break;
5402
5403 case BUILT_IN_BCOPY:
5404 target = expand_builtin_bcopy (arglist);
5405 if (target)
5406 return target;
5407 break;
5408
5409 case BUILT_IN_MEMSET:
5410 target = expand_builtin_memset (arglist, target, mode);
5411 if (target)
5412 return target;
5413 break;
5414
5415 case BUILT_IN_BZERO:
5416 target = expand_builtin_bzero (arglist);
5417 if (target)
5418 return target;
5419 break;
5420
5421 case BUILT_IN_STRCMP:
5422 target = expand_builtin_strcmp (exp, target, mode);
5423 if (target)
5424 return target;
5425 break;
5426
5427 case BUILT_IN_STRNCMP:
5428 target = expand_builtin_strncmp (exp, target, mode);
5429 if (target)
5430 return target;
5431 break;
5432
5433 case BUILT_IN_BCMP:
5434 case BUILT_IN_MEMCMP:
5435 target = expand_builtin_memcmp (exp, arglist, target, mode);
5436 if (target)
5437 return target;
5438 break;
5439
5440 case BUILT_IN_SETJMP:
5441 target = expand_builtin_setjmp (arglist, target);
5442 if (target)
5443 return target;
5444 break;
5445
5446 /* __builtin_longjmp is passed a pointer to an array of five words.
5447 It's similar to the C library longjmp function but works with
5448 __builtin_setjmp above. */
5449 case BUILT_IN_LONGJMP:
5450 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5451 break;
5452 else
5453 {
5454 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5455 VOIDmode, 0);
5456 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5457 NULL_RTX, VOIDmode, 0);
5458
5459 if (value != const1_rtx)
5460 {
5461 error ("__builtin_longjmp second argument must be 1");
5462 return const0_rtx;
5463 }
5464
5465 expand_builtin_longjmp (buf_addr, value);
5466 return const0_rtx;
5467 }
5468
5469 case BUILT_IN_TRAP:
5470 expand_builtin_trap ();
5471 return const0_rtx;
5472
5473 case BUILT_IN_PRINTF:
5474 target = expand_builtin_printf (arglist, target, mode, false);
5475 if (target)
5476 return target;
5477 break;
5478
5479 case BUILT_IN_PRINTF_UNLOCKED:
5480 target = expand_builtin_printf (arglist, target, mode, true);
5481 if (target)
5482 return target;
5483 break;
5484
5485 case BUILT_IN_FPUTS:
5486 target = expand_builtin_fputs (arglist, target, false);
5487 if (target)
5488 return target;
5489 break;
5490
5491 case BUILT_IN_FPUTS_UNLOCKED:
5492 target = expand_builtin_fputs (arglist, target, true);
5493 if (target)
5494 return target;
5495 break;
5496
5497 case BUILT_IN_FPRINTF:
5498 target = expand_builtin_fprintf (arglist, target, mode, false);
5499 if (target)
5500 return target;
5501 break;
5502
5503 case BUILT_IN_FPRINTF_UNLOCKED:
5504 target = expand_builtin_fprintf (arglist, target, mode, true);
5505 if (target)
5506 return target;
5507 break;
5508
5509 case BUILT_IN_SPRINTF:
5510 target = expand_builtin_sprintf (arglist, target, mode);
5511 if (target)
5512 return target;
5513 break;
5514
5515 case BUILT_IN_SIGNBIT:
5516 case BUILT_IN_SIGNBITF:
5517 case BUILT_IN_SIGNBITL:
5518 target = expand_builtin_signbit (exp, target);
5519 if (target)
5520 return target;
5521 break;
5522
5523 /* Various hooks for the DWARF 2 __throw routine. */
5524 case BUILT_IN_UNWIND_INIT:
5525 expand_builtin_unwind_init ();
5526 return const0_rtx;
5527 case BUILT_IN_DWARF_CFA:
5528 return virtual_cfa_rtx;
5529 #ifdef DWARF2_UNWIND_INFO
5530 case BUILT_IN_DWARF_SP_COLUMN:
5531 return expand_builtin_dwarf_sp_column ();
5532 case BUILT_IN_INIT_DWARF_REG_SIZES:
5533 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5534 return const0_rtx;
5535 #endif
5536 case BUILT_IN_FROB_RETURN_ADDR:
5537 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5538 case BUILT_IN_EXTRACT_RETURN_ADDR:
5539 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5540 case BUILT_IN_EH_RETURN:
5541 expand_builtin_eh_return (TREE_VALUE (arglist),
5542 TREE_VALUE (TREE_CHAIN (arglist)));
5543 return const0_rtx;
5544 #ifdef EH_RETURN_DATA_REGNO
5545 case BUILT_IN_EH_RETURN_DATA_REGNO:
5546 return expand_builtin_eh_return_data_regno (arglist);
5547 #endif
5548 case BUILT_IN_EXTEND_POINTER:
5549 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5550
5551 case BUILT_IN_VA_START:
5552 case BUILT_IN_STDARG_START:
5553 return expand_builtin_va_start (arglist);
5554 case BUILT_IN_VA_END:
5555 return expand_builtin_va_end (arglist);
5556 case BUILT_IN_VA_COPY:
5557 return expand_builtin_va_copy (arglist);
5558 case BUILT_IN_EXPECT:
5559 return expand_builtin_expect (arglist, target);
5560 case BUILT_IN_PREFETCH:
5561 expand_builtin_prefetch (arglist);
5562 return const0_rtx;
5563
5564
5565 default: /* just do library call, if unknown builtin */
5566 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5567 error ("built-in function `%s' not currently supported",
5568 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5569 }
5570
5571 /* The switch statement above can drop through to cause the function
5572 to be called normally. */
5573 return expand_call (exp, target, ignore);
5574 }
5575
5576 /* Determine whether a tree node represents a call to a built-in
5577 function. If the tree T is a call to a built-in function with
5578 the right number of arguments of the appropriate types, return
5579 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5580 Otherwise the return value is END_BUILTINS. */
5581
5582 enum built_in_function
5583 builtin_mathfn_code (tree t)
5584 {
5585 tree fndecl, arglist, parmlist;
5586 tree argtype, parmtype;
5587
5588 if (TREE_CODE (t) != CALL_EXPR
5589 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5590 return END_BUILTINS;
5591
5592 fndecl = get_callee_fndecl (t);
5593 if (fndecl == NULL_TREE
5594 || TREE_CODE (fndecl) != FUNCTION_DECL
5595 || ! DECL_BUILT_IN (fndecl)
5596 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5597 return END_BUILTINS;
5598
5599 arglist = TREE_OPERAND (t, 1);
5600 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5601 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5602 {
5603 /* If a function doesn't take a variable number of arguments,
5604 the last element in the list will have type `void'. */
5605 parmtype = TREE_VALUE (parmlist);
5606 if (VOID_TYPE_P (parmtype))
5607 {
5608 if (arglist)
5609 return END_BUILTINS;
5610 return DECL_FUNCTION_CODE (fndecl);
5611 }
5612
5613 if (! arglist)
5614 return END_BUILTINS;
5615
5616 argtype = TREE_TYPE (TREE_VALUE (arglist));
5617
5618 if (SCALAR_FLOAT_TYPE_P (parmtype))
5619 {
5620 if (! SCALAR_FLOAT_TYPE_P (argtype))
5621 return END_BUILTINS;
5622 }
5623 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5624 {
5625 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5626 return END_BUILTINS;
5627 }
5628 else if (POINTER_TYPE_P (parmtype))
5629 {
5630 if (! POINTER_TYPE_P (argtype))
5631 return END_BUILTINS;
5632 }
5633 else if (INTEGRAL_TYPE_P (parmtype))
5634 {
5635 if (! INTEGRAL_TYPE_P (argtype))
5636 return END_BUILTINS;
5637 }
5638 else
5639 return END_BUILTINS;
5640
5641 arglist = TREE_CHAIN (arglist);
5642 }
5643
5644 /* Variable-length argument list. */
5645 return DECL_FUNCTION_CODE (fndecl);
5646 }
5647
5648 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5649 constant. ARGLIST is the argument list of the call. */
5650
5651 static tree
5652 fold_builtin_constant_p (tree arglist)
5653 {
5654 if (arglist == 0)
5655 return 0;
5656
5657 arglist = TREE_VALUE (arglist);
5658
5659 /* We return 1 for a numeric type that's known to be a constant
5660 value at compile-time or for an aggregate type that's a
5661 literal constant. */
5662 STRIP_NOPS (arglist);
5663
5664 /* If we know this is a constant, emit the constant of one. */
5665 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5666 || (TREE_CODE (arglist) == CONSTRUCTOR
5667 && TREE_CONSTANT (arglist))
5668 || (TREE_CODE (arglist) == ADDR_EXPR
5669 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5670 return integer_one_node;
5671
5672 /* If this expression has side effects, show we don't know it to be a
5673 constant. Likewise if it's a pointer or aggregate type since in
5674 those case we only want literals, since those are only optimized
5675 when generating RTL, not later.
5676 And finally, if we are compiling an initializer, not code, we
5677 need to return a definite result now; there's not going to be any
5678 more optimization done. */
5679 if (TREE_SIDE_EFFECTS (arglist)
5680 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5681 || POINTER_TYPE_P (TREE_TYPE (arglist))
5682 || cfun == 0)
5683 return integer_zero_node;
5684
5685 return 0;
5686 }
5687
5688 /* Fold a call to __builtin_classify_type. */
5689
5690 static tree
5691 fold_builtin_classify_type (tree arglist)
5692 {
5693 if (arglist == 0)
5694 return build_int_2 (no_type_class, 0);
5695
5696 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5697 }
5698
5699 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5700
5701 static tree
5702 fold_builtin_inf (tree type, int warn)
5703 {
5704 REAL_VALUE_TYPE real;
5705
5706 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5707 warning ("target format does not support infinity");
5708
5709 real_inf (&real);
5710 return build_real (type, real);
5711 }
5712
5713 /* Fold a call to __builtin_nan or __builtin_nans. */
5714
5715 static tree
5716 fold_builtin_nan (tree arglist, tree type, int quiet)
5717 {
5718 REAL_VALUE_TYPE real;
5719 const char *str;
5720
5721 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5722 return 0;
5723 str = c_getstr (TREE_VALUE (arglist));
5724 if (!str)
5725 return 0;
5726
5727 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5728 return 0;
5729
5730 return build_real (type, real);
5731 }
5732
5733 /* Return true if the floating point expression T has an integer value.
5734 We also allow +Inf, -Inf and NaN to be considered integer values. */
5735
5736 static bool
5737 integer_valued_real_p (tree t)
5738 {
5739 switch (TREE_CODE (t))
5740 {
5741 case FLOAT_EXPR:
5742 return true;
5743
5744 case ABS_EXPR:
5745 case SAVE_EXPR:
5746 case NON_LVALUE_EXPR:
5747 return integer_valued_real_p (TREE_OPERAND (t, 0));
5748
5749 case COMPOUND_EXPR:
5750 case MODIFY_EXPR:
5751 case BIND_EXPR:
5752 return integer_valued_real_p (TREE_OPERAND (t, 1));
5753
5754 case PLUS_EXPR:
5755 case MINUS_EXPR:
5756 case MULT_EXPR:
5757 case MIN_EXPR:
5758 case MAX_EXPR:
5759 return integer_valued_real_p (TREE_OPERAND (t, 0))
5760 && integer_valued_real_p (TREE_OPERAND (t, 1));
5761
5762 case COND_EXPR:
5763 return integer_valued_real_p (TREE_OPERAND (t, 1))
5764 && integer_valued_real_p (TREE_OPERAND (t, 2));
5765
5766 case REAL_CST:
5767 if (! TREE_CONSTANT_OVERFLOW (t))
5768 {
5769 REAL_VALUE_TYPE c, cint;
5770
5771 c = TREE_REAL_CST (t);
5772 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5773 return real_identical (&c, &cint);
5774 }
5775
5776 case NOP_EXPR:
5777 {
5778 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5779 if (TREE_CODE (type) == INTEGER_TYPE)
5780 return true;
5781 if (TREE_CODE (type) == REAL_TYPE)
5782 return integer_valued_real_p (TREE_OPERAND (t, 0));
5783 break;
5784 }
5785
5786 case CALL_EXPR:
5787 switch (builtin_mathfn_code (t))
5788 {
5789 case BUILT_IN_CEIL:
5790 case BUILT_IN_CEILF:
5791 case BUILT_IN_CEILL:
5792 case BUILT_IN_FLOOR:
5793 case BUILT_IN_FLOORF:
5794 case BUILT_IN_FLOORL:
5795 case BUILT_IN_NEARBYINT:
5796 case BUILT_IN_NEARBYINTF:
5797 case BUILT_IN_NEARBYINTL:
5798 case BUILT_IN_ROUND:
5799 case BUILT_IN_ROUNDF:
5800 case BUILT_IN_ROUNDL:
5801 case BUILT_IN_TRUNC:
5802 case BUILT_IN_TRUNCF:
5803 case BUILT_IN_TRUNCL:
5804 return true;
5805
5806 default:
5807 break;
5808 }
5809 break;
5810
5811 default:
5812 break;
5813 }
5814 return false;
5815 }
5816
5817 /* EXP is assumed to be builtin call where truncation can be propagated
5818 across (for instance floor((double)f) == (double)floorf (f).
5819 Do the transformation. */
5820
5821 static tree
5822 fold_trunc_transparent_mathfn (tree exp)
5823 {
5824 tree fndecl = get_callee_fndecl (exp);
5825 tree arglist = TREE_OPERAND (exp, 1);
5826 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5827 tree arg;
5828
5829 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5830 return 0;
5831
5832 arg = TREE_VALUE (arglist);
5833 /* Integer rounding functions are idempotent. */
5834 if (fcode == builtin_mathfn_code (arg))
5835 return arg;
5836
5837 /* If argument is already integer valued, and we don't need to worry
5838 about setting errno, there's no need to perform rounding. */
5839 if (! flag_errno_math && integer_valued_real_p (arg))
5840 return arg;
5841
5842 if (optimize)
5843 {
5844 tree arg0 = strip_float_extensions (arg);
5845 tree ftype = TREE_TYPE (exp);
5846 tree newtype = TREE_TYPE (arg0);
5847 tree decl;
5848
5849 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5850 && (decl = mathfn_built_in (newtype, fcode)))
5851 {
5852 arglist =
5853 build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5854 return convert (ftype,
5855 build_function_call_expr (decl, arglist));
5856 }
5857 }
5858 return 0;
5859 }
5860
5861 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5862 function's DECL, ARGLIST is the argument list and TYPE is the return
5863 type. Return NULL_TREE if no simplification can be made. */
5864
5865 static tree
5866 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5867 {
5868 tree arg;
5869
5870 if (!arglist || TREE_CHAIN (arglist))
5871 return NULL_TREE;
5872
5873 arg = TREE_VALUE (arglist);
5874 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5875 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5876 return NULL_TREE;
5877
5878 /* Evaluate cabs of a constant at compile-time. */
5879 if (flag_unsafe_math_optimizations
5880 && TREE_CODE (arg) == COMPLEX_CST
5881 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5882 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5883 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5884 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5885 {
5886 REAL_VALUE_TYPE r, i;
5887
5888 r = TREE_REAL_CST (TREE_REALPART (arg));
5889 i = TREE_REAL_CST (TREE_IMAGPART (arg));
5890
5891 real_arithmetic (&r, MULT_EXPR, &r, &r);
5892 real_arithmetic (&i, MULT_EXPR, &i, &i);
5893 real_arithmetic (&r, PLUS_EXPR, &r, &i);
5894 if (real_sqrt (&r, TYPE_MODE (type), &r)
5895 || ! flag_trapping_math)
5896 return build_real (type, r);
5897 }
5898
5899 /* If either part is zero, cabs is fabs of the other. */
5900 if (TREE_CODE (arg) == COMPLEX_EXPR
5901 && real_zerop (TREE_OPERAND (arg, 0)))
5902 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5903 if (TREE_CODE (arg) == COMPLEX_EXPR
5904 && real_zerop (TREE_OPERAND (arg, 1)))
5905 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5906
5907 if (flag_unsafe_math_optimizations)
5908 {
5909 enum built_in_function fcode;
5910 tree sqrtfn;
5911
5912 fcode = DECL_FUNCTION_CODE (fndecl);
5913 if (fcode == BUILT_IN_CABS)
5914 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5915 else if (fcode == BUILT_IN_CABSF)
5916 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5917 else if (fcode == BUILT_IN_CABSL)
5918 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5919 else
5920 sqrtfn = NULL_TREE;
5921
5922 if (sqrtfn != NULL_TREE)
5923 {
5924 tree rpart, ipart, result, arglist;
5925
5926 arg = save_expr (arg);
5927
5928 rpart = fold (build1 (REALPART_EXPR, type, arg));
5929 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5930
5931 rpart = save_expr (rpart);
5932 ipart = save_expr (ipart);
5933
5934 result = fold (build (PLUS_EXPR, type,
5935 fold (build (MULT_EXPR, type,
5936 rpart, rpart)),
5937 fold (build (MULT_EXPR, type,
5938 ipart, ipart))));
5939
5940 arglist = build_tree_list (NULL_TREE, result);
5941 return build_function_call_expr (sqrtfn, arglist);
5942 }
5943 }
5944
5945 return NULL_TREE;
5946 }
5947
5948 /* Fold function call to builtin trunc, truncf or truncl. Return
5949 NULL_TREE if no simplification can be made. */
5950
5951 static tree
5952 fold_builtin_trunc (tree exp)
5953 {
5954 tree arglist = TREE_OPERAND (exp, 1);
5955 tree arg;
5956
5957 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5958 return 0;
5959
5960 /* Optimize trunc of constant value. */
5961 arg = TREE_VALUE (arglist);
5962 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5963 {
5964 REAL_VALUE_TYPE r, x;
5965 tree type = TREE_TYPE (exp);
5966
5967 x = TREE_REAL_CST (arg);
5968 real_trunc (&r, TYPE_MODE (type), &x);
5969 return build_real (type, r);
5970 }
5971
5972 return fold_trunc_transparent_mathfn (exp);
5973 }
5974
5975 /* Fold function call to builtin floor, floorf or floorl. Return
5976 NULL_TREE if no simplification can be made. */
5977
5978 static tree
5979 fold_builtin_floor (tree exp)
5980 {
5981 tree arglist = TREE_OPERAND (exp, 1);
5982 tree arg;
5983
5984 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5985 return 0;
5986
5987 /* Optimize floor of constant value. */
5988 arg = TREE_VALUE (arglist);
5989 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5990 {
5991 REAL_VALUE_TYPE x;
5992
5993 x = TREE_REAL_CST (arg);
5994 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5995 {
5996 tree type = TREE_TYPE (exp);
5997 REAL_VALUE_TYPE r;
5998
5999 real_floor (&r, TYPE_MODE (type), &x);
6000 return build_real (type, r);
6001 }
6002 }
6003
6004 return fold_trunc_transparent_mathfn (exp);
6005 }
6006
6007 /* Fold function call to builtin ceil, ceilf or ceill. Return
6008 NULL_TREE if no simplification can be made. */
6009
6010 static tree
6011 fold_builtin_ceil (tree exp)
6012 {
6013 tree arglist = TREE_OPERAND (exp, 1);
6014 tree arg;
6015
6016 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6017 return 0;
6018
6019 /* Optimize ceil of constant value. */
6020 arg = TREE_VALUE (arglist);
6021 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6022 {
6023 REAL_VALUE_TYPE x;
6024
6025 x = TREE_REAL_CST (arg);
6026 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6027 {
6028 tree type = TREE_TYPE (exp);
6029 REAL_VALUE_TYPE r;
6030
6031 real_ceil (&r, TYPE_MODE (type), &x);
6032 return build_real (type, r);
6033 }
6034 }
6035
6036 return fold_trunc_transparent_mathfn (exp);
6037 }
6038
6039 /* Fold function call to builtin round, roundf or roundl. Return
6040 NULL_TREE if no simplification can be made. */
6041
6042 static tree
6043 fold_builtin_round (tree exp)
6044 {
6045 tree arglist = TREE_OPERAND (exp, 1);
6046 tree arg;
6047
6048 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6049 return 0;
6050
6051 /* Optimize ceil of constant value. */
6052 arg = TREE_VALUE (arglist);
6053 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6054 {
6055 REAL_VALUE_TYPE x;
6056
6057 x = TREE_REAL_CST (arg);
6058 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6059 {
6060 tree type = TREE_TYPE (exp);
6061 REAL_VALUE_TYPE r;
6062
6063 real_round (&r, TYPE_MODE (type), &x);
6064 return build_real (type, r);
6065 }
6066 }
6067
6068 return fold_trunc_transparent_mathfn (exp);
6069 }
6070
6071 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6072 and their long and long long variants (i.e. ffsl and ffsll).
6073 Return NULL_TREE if no simplification can be made. */
6074
6075 static tree
6076 fold_builtin_bitop (tree exp)
6077 {
6078 tree fndecl = get_callee_fndecl (exp);
6079 tree arglist = TREE_OPERAND (exp, 1);
6080 tree arg;
6081
6082 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6083 return NULL_TREE;
6084
6085 /* Optimize for constant argument. */
6086 arg = TREE_VALUE (arglist);
6087 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6088 {
6089 HOST_WIDE_INT hi, width, result;
6090 unsigned HOST_WIDE_INT lo;
6091 tree type, t;
6092
6093 type = TREE_TYPE (arg);
6094 width = TYPE_PRECISION (type);
6095 lo = TREE_INT_CST_LOW (arg);
6096
6097 /* Clear all the bits that are beyond the type's precision. */
6098 if (width > HOST_BITS_PER_WIDE_INT)
6099 {
6100 hi = TREE_INT_CST_HIGH (arg);
6101 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6102 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6103 }
6104 else
6105 {
6106 hi = 0;
6107 if (width < HOST_BITS_PER_WIDE_INT)
6108 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6109 }
6110
6111 switch (DECL_FUNCTION_CODE (fndecl))
6112 {
6113 case BUILT_IN_FFS:
6114 case BUILT_IN_FFSL:
6115 case BUILT_IN_FFSLL:
6116 if (lo != 0)
6117 result = exact_log2 (lo & -lo) + 1;
6118 else if (hi != 0)
6119 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6120 else
6121 result = 0;
6122 break;
6123
6124 case BUILT_IN_CLZ:
6125 case BUILT_IN_CLZL:
6126 case BUILT_IN_CLZLL:
6127 if (hi != 0)
6128 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6129 else if (lo != 0)
6130 result = width - floor_log2 (lo) - 1;
6131 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6132 result = width;
6133 break;
6134
6135 case BUILT_IN_CTZ:
6136 case BUILT_IN_CTZL:
6137 case BUILT_IN_CTZLL:
6138 if (lo != 0)
6139 result = exact_log2 (lo & -lo);
6140 else if (hi != 0)
6141 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6142 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6143 result = width;
6144 break;
6145
6146 case BUILT_IN_POPCOUNT:
6147 case BUILT_IN_POPCOUNTL:
6148 case BUILT_IN_POPCOUNTLL:
6149 result = 0;
6150 while (lo)
6151 result++, lo &= lo - 1;
6152 while (hi)
6153 result++, hi &= hi - 1;
6154 break;
6155
6156 case BUILT_IN_PARITY:
6157 case BUILT_IN_PARITYL:
6158 case BUILT_IN_PARITYLL:
6159 result = 0;
6160 while (lo)
6161 result++, lo &= lo - 1;
6162 while (hi)
6163 result++, hi &= hi - 1;
6164 result &= 1;
6165 break;
6166
6167 default:
6168 abort();
6169 }
6170
6171 t = build_int_2 (result, 0);
6172 TREE_TYPE (t) = TREE_TYPE (exp);
6173 return t;
6174 }
6175
6176 return NULL_TREE;
6177 }
6178
6179 /* Return true if EXPR is the real constant contained in VALUE. */
6180
6181 static bool
6182 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6183 {
6184 STRIP_NOPS (expr);
6185
6186 return ((TREE_CODE (expr) == REAL_CST
6187 && ! TREE_CONSTANT_OVERFLOW (expr)
6188 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6189 || (TREE_CODE (expr) == COMPLEX_CST
6190 && real_dconstp (TREE_REALPART (expr), value)
6191 && real_zerop (TREE_IMAGPART (expr))));
6192 }
6193
6194 /* A subroutine of fold_builtin to fold the various logarithmic
6195 functions. EXP is the CALL_EXPR of a call to a builtin logN
6196 function. VALUE is the base of the logN function. */
6197
6198 static tree
6199 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6200 {
6201 tree arglist = TREE_OPERAND (exp, 1);
6202
6203 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6204 {
6205 tree fndecl = get_callee_fndecl (exp);
6206 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6207 tree arg = TREE_VALUE (arglist);
6208 const enum built_in_function fcode = builtin_mathfn_code (arg);
6209
6210 /* Optimize logN(1.0) = 0.0. */
6211 if (real_onep (arg))
6212 return build_real (type, dconst0);
6213
6214 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6215 exactly, then only do this if flag_unsafe_math_optimizations. */
6216 if (exact_real_truncate (TYPE_MODE (type), value)
6217 || flag_unsafe_math_optimizations)
6218 {
6219 const REAL_VALUE_TYPE value_truncate =
6220 real_value_truncate (TYPE_MODE (type), *value);
6221 if (real_dconstp (arg, &value_truncate))
6222 return build_real (type, dconst1);
6223 }
6224
6225 /* Special case, optimize logN(expN(x)) = x. */
6226 if (flag_unsafe_math_optimizations
6227 && ((value == &dconste
6228 && (fcode == BUILT_IN_EXP
6229 || fcode == BUILT_IN_EXPF
6230 || fcode == BUILT_IN_EXPL))
6231 || (value == &dconst2
6232 && (fcode == BUILT_IN_EXP2
6233 || fcode == BUILT_IN_EXP2F
6234 || fcode == BUILT_IN_EXP2L))
6235 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6236 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6237
6238 /* Optimize logN(func()) for various exponential functions. We
6239 want to determine the value "x" and the power "exponent" in
6240 order to transform logN(x**exponent) into exponent*logN(x). */
6241 if (flag_unsafe_math_optimizations)
6242 {
6243 tree exponent = 0, x = 0;
6244
6245 switch (fcode)
6246 {
6247 case BUILT_IN_EXP:
6248 case BUILT_IN_EXPF:
6249 case BUILT_IN_EXPL:
6250 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6251 x = build_real (type,
6252 real_value_truncate (TYPE_MODE (type), dconste));
6253 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6254 break;
6255 case BUILT_IN_EXP2:
6256 case BUILT_IN_EXP2F:
6257 case BUILT_IN_EXP2L:
6258 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6259 x = build_real (type, dconst2);
6260 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6261 break;
6262 case BUILT_IN_EXP10:
6263 case BUILT_IN_EXP10F:
6264 case BUILT_IN_EXP10L:
6265 case BUILT_IN_POW10:
6266 case BUILT_IN_POW10F:
6267 case BUILT_IN_POW10L:
6268 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6269 x = build_real (type, dconst10);
6270 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6271 break;
6272 case BUILT_IN_SQRT:
6273 case BUILT_IN_SQRTF:
6274 case BUILT_IN_SQRTL:
6275 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6276 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6277 exponent = build_real (type, dconsthalf);
6278 break;
6279 case BUILT_IN_CBRT:
6280 case BUILT_IN_CBRTF:
6281 case BUILT_IN_CBRTL:
6282 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6283 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6284 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6285 dconstthird));
6286 break;
6287 case BUILT_IN_POW:
6288 case BUILT_IN_POWF:
6289 case BUILT_IN_POWL:
6290 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6291 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6292 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6293 break;
6294 default:
6295 break;
6296 }
6297
6298 /* Now perform the optimization. */
6299 if (x && exponent)
6300 {
6301 tree logfn;
6302 arglist = build_tree_list (NULL_TREE, x);
6303 logfn = build_function_call_expr (fndecl, arglist);
6304 return fold (build (MULT_EXPR, type, exponent, logfn));
6305 }
6306 }
6307 }
6308
6309 return 0;
6310 }
6311
6312 /* A subroutine of fold_builtin to fold the various exponent
6313 functions. EXP is the CALL_EXPR of a call to a builtin function.
6314 VALUE is the value which will be raised to a power. */
6315
6316 static tree
6317 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6318 {
6319 tree arglist = TREE_OPERAND (exp, 1);
6320
6321 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6322 {
6323 tree fndecl = get_callee_fndecl (exp);
6324 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6325 tree arg = TREE_VALUE (arglist);
6326
6327 /* Optimize exp*(0.0) = 1.0. */
6328 if (real_zerop (arg))
6329 return build_real (type, dconst1);
6330
6331 /* Optimize expN(1.0) = N. */
6332 if (real_onep (arg))
6333 {
6334 REAL_VALUE_TYPE cst;
6335
6336 real_convert (&cst, TYPE_MODE (type), value);
6337 return build_real (type, cst);
6338 }
6339
6340 /* Attempt to evaluate expN(integer) at compile-time. */
6341 if (flag_unsafe_math_optimizations
6342 && TREE_CODE (arg) == REAL_CST
6343 && ! TREE_CONSTANT_OVERFLOW (arg))
6344 {
6345 REAL_VALUE_TYPE cint;
6346 REAL_VALUE_TYPE c;
6347 HOST_WIDE_INT n;
6348
6349 c = TREE_REAL_CST (arg);
6350 n = real_to_integer (&c);
6351 real_from_integer (&cint, VOIDmode, n,
6352 n < 0 ? -1 : 0, 0);
6353 if (real_identical (&c, &cint))
6354 {
6355 REAL_VALUE_TYPE x;
6356
6357 real_powi (&x, TYPE_MODE (type), value, n);
6358 return build_real (type, x);
6359 }
6360 }
6361
6362 /* Optimize expN(logN(x)) = x. */
6363 if (flag_unsafe_math_optimizations)
6364 {
6365 const enum built_in_function fcode = builtin_mathfn_code (arg);
6366
6367 if ((value == &dconste
6368 && (fcode == BUILT_IN_LOG
6369 || fcode == BUILT_IN_LOGF
6370 || fcode == BUILT_IN_LOGL))
6371 || (value == &dconst2
6372 && (fcode == BUILT_IN_LOG2
6373 || fcode == BUILT_IN_LOG2F
6374 || fcode == BUILT_IN_LOG2L))
6375 || (value == &dconst10
6376 && (fcode == BUILT_IN_LOG10
6377 || fcode == BUILT_IN_LOG10F
6378 || fcode == BUILT_IN_LOG10L)))
6379 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6380 }
6381 }
6382
6383 return 0;
6384 }
6385
6386 /* Fold function call to builtin memcpy. Return
6387 NULL_TREE if no simplification can be made. */
6388
6389 static tree
6390 fold_builtin_memcpy (tree exp)
6391 {
6392 tree arglist = TREE_OPERAND (exp, 1);
6393 tree dest, src, len;
6394
6395 if (!validate_arglist (arglist,
6396 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6397 return 0;
6398
6399 dest = TREE_VALUE (arglist);
6400 src = TREE_VALUE (TREE_CHAIN (arglist));
6401 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6402
6403 /* If the LEN parameter is zero, return DEST. */
6404 if (integer_zerop (len))
6405 return omit_one_operand (TREE_TYPE (exp), dest, src);
6406
6407 /* If SRC and DEST are the same (and not volatile), return DEST. */
6408 if (operand_equal_p (src, dest, 0))
6409 return omit_one_operand (TREE_TYPE (exp), dest, len);
6410
6411 return 0;
6412 }
6413
6414 /* Fold function call to builtin mempcpy. Return
6415 NULL_TREE if no simplification can be made. */
6416
6417 static tree
6418 fold_builtin_mempcpy (tree exp)
6419 {
6420 tree arglist = TREE_OPERAND (exp, 1);
6421 tree dest, src, len;
6422
6423 if (!validate_arglist (arglist,
6424 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6425 return 0;
6426
6427 dest = TREE_VALUE (arglist);
6428 src = TREE_VALUE (TREE_CHAIN (arglist));
6429 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6430
6431 /* If the LEN parameter is zero, return DEST. */
6432 if (integer_zerop (len))
6433 return omit_one_operand (TREE_TYPE (exp), dest, src);
6434
6435 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6436 if (operand_equal_p (src, dest, 0))
6437 {
6438 tree temp = convert (TREE_TYPE (dest), len);
6439 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6440 return convert (TREE_TYPE (exp), temp);
6441 }
6442
6443 return 0;
6444 }
6445
6446 /* Fold function call to builtin memmove. Return
6447 NULL_TREE if no simplification can be made. */
6448
6449 static tree
6450 fold_builtin_memmove (tree exp)
6451 {
6452 tree arglist = TREE_OPERAND (exp, 1);
6453 tree dest, src, len;
6454
6455 if (!validate_arglist (arglist,
6456 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6457 return 0;
6458
6459 dest = TREE_VALUE (arglist);
6460 src = TREE_VALUE (TREE_CHAIN (arglist));
6461 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6462
6463 /* If the LEN parameter is zero, return DEST. */
6464 if (integer_zerop (len))
6465 return omit_one_operand (TREE_TYPE (exp), dest, src);
6466
6467 /* If SRC and DEST are the same (and not volatile), return DEST. */
6468 if (operand_equal_p (src, dest, 0))
6469 return omit_one_operand (TREE_TYPE (exp), dest, len);
6470
6471 return 0;
6472 }
6473
6474 /* Fold function call to builtin strcpy. Return
6475 NULL_TREE if no simplification can be made. */
6476
6477 static tree
6478 fold_builtin_strcpy (tree exp)
6479 {
6480 tree arglist = TREE_OPERAND (exp, 1);
6481 tree dest, src;
6482
6483 if (!validate_arglist (arglist,
6484 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6485 return 0;
6486
6487 dest = TREE_VALUE (arglist);
6488 src = TREE_VALUE (TREE_CHAIN (arglist));
6489
6490 /* If SRC and DEST are the same (and not volatile), return DEST. */
6491 if (operand_equal_p (src, dest, 0))
6492 return convert (TREE_TYPE (exp), dest);
6493
6494 return 0;
6495 }
6496
6497 /* Fold function call to builtin strncpy. Return
6498 NULL_TREE if no simplification can be made. */
6499
6500 static tree
6501 fold_builtin_strncpy (tree exp)
6502 {
6503 tree arglist = TREE_OPERAND (exp, 1);
6504 tree dest, src, len;
6505
6506 if (!validate_arglist (arglist,
6507 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6508 return 0;
6509
6510 dest = TREE_VALUE (arglist);
6511 src = TREE_VALUE (TREE_CHAIN (arglist));
6512 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6513
6514 /* If the LEN parameter is zero, return DEST. */
6515 if (integer_zerop (len))
6516 return omit_one_operand (TREE_TYPE (exp), dest, src);
6517
6518 return 0;
6519 }
6520
6521 /* Fold function call to builtin memcmp. Return
6522 NULL_TREE if no simplification can be made. */
6523
6524 static tree
6525 fold_builtin_memcmp (tree exp)
6526 {
6527 tree arglist = TREE_OPERAND (exp, 1);
6528 tree arg1, arg2, len;
6529
6530 if (!validate_arglist (arglist,
6531 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6532 return 0;
6533
6534 arg1 = TREE_VALUE (arglist);
6535 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6536 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6537
6538 /* If the LEN parameter is zero, return zero. */
6539 if (integer_zerop (len))
6540 {
6541 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6542 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6543 }
6544
6545 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6546 if (operand_equal_p (arg1, arg2, 0))
6547 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6548
6549 return 0;
6550 }
6551
6552 /* Fold function call to builtin strcmp. Return
6553 NULL_TREE if no simplification can be made. */
6554
6555 static tree
6556 fold_builtin_strcmp (tree exp)
6557 {
6558 tree arglist = TREE_OPERAND (exp, 1);
6559 tree arg1, arg2;
6560 const char *p1, *p2;
6561
6562 if (!validate_arglist (arglist,
6563 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6564 return 0;
6565
6566 arg1 = TREE_VALUE (arglist);
6567 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6568
6569 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6570 if (operand_equal_p (arg1, arg2, 0))
6571 return convert (TREE_TYPE (exp), integer_zero_node);
6572
6573 p1 = c_getstr (arg1);
6574 p2 = c_getstr (arg2);
6575
6576 if (p1 && p2)
6577 {
6578 tree temp;
6579 const int i = strcmp (p1, p2);
6580 if (i < 0)
6581 temp = integer_minus_one_node;
6582 else if (i > 0)
6583 temp = integer_one_node;
6584 else
6585 temp = integer_zero_node;
6586 return convert (TREE_TYPE (exp), temp);
6587 }
6588
6589 return 0;
6590 }
6591
6592 /* Fold function call to builtin strncmp. Return
6593 NULL_TREE if no simplification can be made. */
6594
6595 static tree
6596 fold_builtin_strncmp (tree exp)
6597 {
6598 tree arglist = TREE_OPERAND (exp, 1);
6599 tree arg1, arg2, len;
6600 const char *p1, *p2;
6601
6602 if (!validate_arglist (arglist,
6603 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6604 return 0;
6605
6606 arg1 = TREE_VALUE (arglist);
6607 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6608 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6609
6610 /* If the LEN parameter is zero, return zero. */
6611 if (integer_zerop (len))
6612 {
6613 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6614 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6615 }
6616
6617 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6618 if (operand_equal_p (arg1, arg2, 0))
6619 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6620
6621 p1 = c_getstr (arg1);
6622 p2 = c_getstr (arg2);
6623
6624 if (host_integerp (len, 1) && p1 && p2)
6625 {
6626 tree temp;
6627 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6628 if (i < 0)
6629 temp = integer_minus_one_node;
6630 else if (i > 0)
6631 temp = integer_one_node;
6632 else
6633 temp = integer_zero_node;
6634 return convert (TREE_TYPE (exp), temp);
6635 }
6636
6637 return 0;
6638 }
6639
6640 /* Fold function call to builtin signbit, signbitf or signbitl. Return
6641 NULL_TREE if no simplification can be made. */
6642
6643 static tree
6644 fold_builtin_signbit (tree exp)
6645 {
6646 tree arglist = TREE_OPERAND (exp, 1);
6647 tree arg, temp;
6648
6649 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6650 return NULL_TREE;
6651
6652 arg = TREE_VALUE (arglist);
6653
6654 /* If ARG is a compile-time constant, determine the result. */
6655 if (TREE_CODE (arg) == REAL_CST
6656 && !TREE_CONSTANT_OVERFLOW (arg))
6657 {
6658 REAL_VALUE_TYPE c;
6659
6660 c = TREE_REAL_CST (arg);
6661 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
6662 return convert (TREE_TYPE (exp), temp);
6663 }
6664
6665 /* If ARG is non-negative, the result is always zero. */
6666 if (tree_expr_nonnegative_p (arg))
6667 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
6668
6669 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
6670 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
6671 return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
6672 build_real (TREE_TYPE (arg), dconst0)));
6673
6674 return NULL_TREE;
6675 }
6676
6677
6678 /* Used by constant folding to eliminate some builtin calls early. EXP is
6679 the CALL_EXPR of a call to a builtin function. */
6680
6681 tree
6682 fold_builtin (tree exp)
6683 {
6684 tree fndecl = get_callee_fndecl (exp);
6685 tree arglist = TREE_OPERAND (exp, 1);
6686 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6687
6688 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6689 return 0;
6690
6691 switch (DECL_FUNCTION_CODE (fndecl))
6692 {
6693 case BUILT_IN_CONSTANT_P:
6694 return fold_builtin_constant_p (arglist);
6695
6696 case BUILT_IN_CLASSIFY_TYPE:
6697 return fold_builtin_classify_type (arglist);
6698
6699 case BUILT_IN_STRLEN:
6700 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6701 {
6702 tree len = c_strlen (TREE_VALUE (arglist), 0);
6703 if (len)
6704 {
6705 /* Convert from the internal "sizetype" type to "size_t". */
6706 if (size_type_node)
6707 len = convert (size_type_node, len);
6708 return len;
6709 }
6710 }
6711 break;
6712
6713 case BUILT_IN_FABS:
6714 case BUILT_IN_FABSF:
6715 case BUILT_IN_FABSL:
6716 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6717 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6718 break;
6719
6720 case BUILT_IN_CABS:
6721 case BUILT_IN_CABSF:
6722 case BUILT_IN_CABSL:
6723 return fold_builtin_cabs (fndecl, arglist, type);
6724
6725 case BUILT_IN_SQRT:
6726 case BUILT_IN_SQRTF:
6727 case BUILT_IN_SQRTL:
6728 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6729 {
6730 enum built_in_function fcode;
6731 tree arg = TREE_VALUE (arglist);
6732
6733 /* Optimize sqrt of constant value. */
6734 if (TREE_CODE (arg) == REAL_CST
6735 && ! TREE_CONSTANT_OVERFLOW (arg))
6736 {
6737 REAL_VALUE_TYPE r, x;
6738
6739 x = TREE_REAL_CST (arg);
6740 if (real_sqrt (&r, TYPE_MODE (type), &x)
6741 || (!flag_trapping_math && !flag_errno_math))
6742 return build_real (type, r);
6743 }
6744
6745 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6746 fcode = builtin_mathfn_code (arg);
6747 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6748 {
6749 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6750 arg = fold (build (MULT_EXPR, type,
6751 TREE_VALUE (TREE_OPERAND (arg, 1)),
6752 build_real (type, dconsthalf)));
6753 arglist = build_tree_list (NULL_TREE, arg);
6754 return build_function_call_expr (expfn, arglist);
6755 }
6756
6757 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6758 if (flag_unsafe_math_optimizations
6759 && (fcode == BUILT_IN_POW
6760 || fcode == BUILT_IN_POWF
6761 || fcode == BUILT_IN_POWL))
6762 {
6763 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6764 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6765 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6766 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6767 build_real (type, dconsthalf)));
6768 arglist = tree_cons (NULL_TREE, arg0,
6769 build_tree_list (NULL_TREE, narg1));
6770 return build_function_call_expr (powfn, arglist);
6771 }
6772 }
6773 break;
6774
6775 case BUILT_IN_SIN:
6776 case BUILT_IN_SINF:
6777 case BUILT_IN_SINL:
6778 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6779 {
6780 tree arg = TREE_VALUE (arglist);
6781
6782 /* Optimize sin(0.0) = 0.0. */
6783 if (real_zerop (arg))
6784 return arg;
6785 }
6786 break;
6787
6788 case BUILT_IN_COS:
6789 case BUILT_IN_COSF:
6790 case BUILT_IN_COSL:
6791 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6792 {
6793 tree arg = TREE_VALUE (arglist);
6794
6795 /* Optimize cos(0.0) = 1.0. */
6796 if (real_zerop (arg))
6797 return build_real (type, dconst1);
6798
6799 /* Optimize cos(-x) into cos(x). */
6800 if (TREE_CODE (arg) == NEGATE_EXPR)
6801 {
6802 tree arglist = build_tree_list (NULL_TREE,
6803 TREE_OPERAND (arg, 0));
6804 return build_function_call_expr (fndecl, arglist);
6805 }
6806 }
6807 break;
6808
6809 case BUILT_IN_EXP:
6810 case BUILT_IN_EXPF:
6811 case BUILT_IN_EXPL:
6812 return fold_builtin_exponent (exp, &dconste);
6813 case BUILT_IN_EXP2:
6814 case BUILT_IN_EXP2F:
6815 case BUILT_IN_EXP2L:
6816 return fold_builtin_exponent (exp, &dconst2);
6817 case BUILT_IN_EXP10:
6818 case BUILT_IN_EXP10F:
6819 case BUILT_IN_EXP10L:
6820 case BUILT_IN_POW10:
6821 case BUILT_IN_POW10F:
6822 case BUILT_IN_POW10L:
6823 return fold_builtin_exponent (exp, &dconst10);
6824 case BUILT_IN_LOG:
6825 case BUILT_IN_LOGF:
6826 case BUILT_IN_LOGL:
6827 return fold_builtin_logarithm (exp, &dconste);
6828 break;
6829 case BUILT_IN_LOG2:
6830 case BUILT_IN_LOG2F:
6831 case BUILT_IN_LOG2L:
6832 return fold_builtin_logarithm (exp, &dconst2);
6833 break;
6834 case BUILT_IN_LOG10:
6835 case BUILT_IN_LOG10F:
6836 case BUILT_IN_LOG10L:
6837 return fold_builtin_logarithm (exp, &dconst10);
6838 break;
6839
6840 case BUILT_IN_TAN:
6841 case BUILT_IN_TANF:
6842 case BUILT_IN_TANL:
6843 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6844 {
6845 enum built_in_function fcode;
6846 tree arg = TREE_VALUE (arglist);
6847
6848 /* Optimize tan(0.0) = 0.0. */
6849 if (real_zerop (arg))
6850 return arg;
6851
6852 /* Optimize tan(atan(x)) = x. */
6853 fcode = builtin_mathfn_code (arg);
6854 if (flag_unsafe_math_optimizations
6855 && (fcode == BUILT_IN_ATAN
6856 || fcode == BUILT_IN_ATANF
6857 || fcode == BUILT_IN_ATANL))
6858 return TREE_VALUE (TREE_OPERAND (arg, 1));
6859 }
6860 break;
6861
6862 case BUILT_IN_ATAN:
6863 case BUILT_IN_ATANF:
6864 case BUILT_IN_ATANL:
6865 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6866 {
6867 tree arg = TREE_VALUE (arglist);
6868
6869 /* Optimize atan(0.0) = 0.0. */
6870 if (real_zerop (arg))
6871 return arg;
6872
6873 /* Optimize atan(1.0) = pi/4. */
6874 if (real_onep (arg))
6875 {
6876 REAL_VALUE_TYPE cst;
6877
6878 real_convert (&cst, TYPE_MODE (type), &dconstpi);
6879 cst.exp -= 2;
6880 return build_real (type, cst);
6881 }
6882 }
6883 break;
6884
6885 case BUILT_IN_POW:
6886 case BUILT_IN_POWF:
6887 case BUILT_IN_POWL:
6888 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6889 {
6890 enum built_in_function fcode;
6891 tree arg0 = TREE_VALUE (arglist);
6892 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6893
6894 /* Optimize pow(1.0,y) = 1.0. */
6895 if (real_onep (arg0))
6896 return omit_one_operand (type, build_real (type, dconst1), arg1);
6897
6898 if (TREE_CODE (arg1) == REAL_CST
6899 && ! TREE_CONSTANT_OVERFLOW (arg1))
6900 {
6901 REAL_VALUE_TYPE c;
6902 c = TREE_REAL_CST (arg1);
6903
6904 /* Optimize pow(x,0.0) = 1.0. */
6905 if (REAL_VALUES_EQUAL (c, dconst0))
6906 return omit_one_operand (type, build_real (type, dconst1),
6907 arg0);
6908
6909 /* Optimize pow(x,1.0) = x. */
6910 if (REAL_VALUES_EQUAL (c, dconst1))
6911 return arg0;
6912
6913 /* Optimize pow(x,-1.0) = 1.0/x. */
6914 if (REAL_VALUES_EQUAL (c, dconstm1))
6915 return fold (build (RDIV_EXPR, type,
6916 build_real (type, dconst1),
6917 arg0));
6918
6919 /* Optimize pow(x,0.5) = sqrt(x). */
6920 if (flag_unsafe_math_optimizations
6921 && REAL_VALUES_EQUAL (c, dconsthalf))
6922 {
6923 tree sqrtfn;
6924
6925 fcode = DECL_FUNCTION_CODE (fndecl);
6926 if (fcode == BUILT_IN_POW)
6927 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6928 else if (fcode == BUILT_IN_POWF)
6929 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6930 else if (fcode == BUILT_IN_POWL)
6931 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6932 else
6933 sqrtfn = NULL_TREE;
6934
6935 if (sqrtfn != NULL_TREE)
6936 {
6937 tree arglist = build_tree_list (NULL_TREE, arg0);
6938 return build_function_call_expr (sqrtfn, arglist);
6939 }
6940 }
6941
6942 /* Attempt to evaluate pow at compile-time. */
6943 if (TREE_CODE (arg0) == REAL_CST
6944 && ! TREE_CONSTANT_OVERFLOW (arg0))
6945 {
6946 REAL_VALUE_TYPE cint;
6947 HOST_WIDE_INT n;
6948
6949 n = real_to_integer (&c);
6950 real_from_integer (&cint, VOIDmode, n,
6951 n < 0 ? -1 : 0, 0);
6952 if (real_identical (&c, &cint))
6953 {
6954 REAL_VALUE_TYPE x;
6955 bool inexact;
6956
6957 x = TREE_REAL_CST (arg0);
6958 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6959 if (flag_unsafe_math_optimizations || !inexact)
6960 return build_real (type, x);
6961 }
6962 }
6963 }
6964
6965 /* Optimize pow(expN(x),y) = expN(x*y). */
6966 fcode = builtin_mathfn_code (arg0);
6967 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6968 {
6969 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6970 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6971 arg = fold (build (MULT_EXPR, type, arg, arg1));
6972 arglist = build_tree_list (NULL_TREE, arg);
6973 return build_function_call_expr (expfn, arglist);
6974 }
6975
6976 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
6977 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6978 {
6979 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6980 tree narg1 = fold (build (MULT_EXPR, type, arg1,
6981 build_real (type, dconsthalf)));
6982
6983 arglist = tree_cons (NULL_TREE, narg0,
6984 build_tree_list (NULL_TREE, narg1));
6985 return build_function_call_expr (fndecl, arglist);
6986 }
6987
6988 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
6989 if (flag_unsafe_math_optimizations
6990 && (fcode == BUILT_IN_POW
6991 || fcode == BUILT_IN_POWF
6992 || fcode == BUILT_IN_POWL))
6993 {
6994 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6995 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6996 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6997 arglist = tree_cons (NULL_TREE, arg00,
6998 build_tree_list (NULL_TREE, narg1));
6999 return build_function_call_expr (fndecl, arglist);
7000 }
7001 }
7002 break;
7003
7004 case BUILT_IN_INF:
7005 case BUILT_IN_INFF:
7006 case BUILT_IN_INFL:
7007 return fold_builtin_inf (type, true);
7008
7009 case BUILT_IN_HUGE_VAL:
7010 case BUILT_IN_HUGE_VALF:
7011 case BUILT_IN_HUGE_VALL:
7012 return fold_builtin_inf (type, false);
7013
7014 case BUILT_IN_NAN:
7015 case BUILT_IN_NANF:
7016 case BUILT_IN_NANL:
7017 return fold_builtin_nan (arglist, type, true);
7018
7019 case BUILT_IN_NANS:
7020 case BUILT_IN_NANSF:
7021 case BUILT_IN_NANSL:
7022 return fold_builtin_nan (arglist, type, false);
7023
7024 case BUILT_IN_FLOOR:
7025 case BUILT_IN_FLOORF:
7026 case BUILT_IN_FLOORL:
7027 return fold_builtin_floor (exp);
7028
7029 case BUILT_IN_CEIL:
7030 case BUILT_IN_CEILF:
7031 case BUILT_IN_CEILL:
7032 return fold_builtin_ceil (exp);
7033
7034 case BUILT_IN_TRUNC:
7035 case BUILT_IN_TRUNCF:
7036 case BUILT_IN_TRUNCL:
7037 return fold_builtin_trunc (exp);
7038
7039 case BUILT_IN_ROUND:
7040 case BUILT_IN_ROUNDF:
7041 case BUILT_IN_ROUNDL:
7042 return fold_builtin_round (exp);
7043
7044 case BUILT_IN_NEARBYINT:
7045 case BUILT_IN_NEARBYINTF:
7046 case BUILT_IN_NEARBYINTL:
7047 return fold_trunc_transparent_mathfn (exp);
7048
7049 case BUILT_IN_FFS:
7050 case BUILT_IN_FFSL:
7051 case BUILT_IN_FFSLL:
7052 case BUILT_IN_CLZ:
7053 case BUILT_IN_CLZL:
7054 case BUILT_IN_CLZLL:
7055 case BUILT_IN_CTZ:
7056 case BUILT_IN_CTZL:
7057 case BUILT_IN_CTZLL:
7058 case BUILT_IN_POPCOUNT:
7059 case BUILT_IN_POPCOUNTL:
7060 case BUILT_IN_POPCOUNTLL:
7061 case BUILT_IN_PARITY:
7062 case BUILT_IN_PARITYL:
7063 case BUILT_IN_PARITYLL:
7064 return fold_builtin_bitop (exp);
7065
7066 case BUILT_IN_MEMCPY:
7067 return fold_builtin_memcpy (exp);
7068
7069 case BUILT_IN_MEMPCPY:
7070 return fold_builtin_mempcpy (exp);
7071
7072 case BUILT_IN_MEMMOVE:
7073 return fold_builtin_memmove (exp);
7074
7075 case BUILT_IN_STRCPY:
7076 return fold_builtin_strcpy (exp);
7077
7078 case BUILT_IN_STRNCPY:
7079 return fold_builtin_strncpy (exp);
7080
7081 case BUILT_IN_MEMCMP:
7082 return fold_builtin_memcmp (exp);
7083
7084 case BUILT_IN_STRCMP:
7085 return fold_builtin_strcmp (exp);
7086
7087 case BUILT_IN_STRNCMP:
7088 return fold_builtin_strncmp (exp);
7089
7090 case BUILT_IN_SIGNBIT:
7091 case BUILT_IN_SIGNBITF:
7092 case BUILT_IN_SIGNBITL:
7093 return fold_builtin_signbit (exp);
7094
7095 default:
7096 break;
7097 }
7098
7099 return 0;
7100 }
7101
7102 /* Conveniently construct a function call expression. */
7103
7104 tree
7105 build_function_call_expr (tree fn, tree arglist)
7106 {
7107 tree call_expr;
7108
7109 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7110 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7111 call_expr, arglist);
7112 return fold (call_expr);
7113 }
7114
7115 /* This function validates the types of a function call argument list
7116 represented as a tree chain of parameters against a specified list
7117 of tree_codes. If the last specifier is a 0, that represents an
7118 ellipses, otherwise the last specifier must be a VOID_TYPE. */
7119
7120 static int
7121 validate_arglist (tree arglist, ...)
7122 {
7123 enum tree_code code;
7124 int res = 0;
7125 va_list ap;
7126
7127 va_start (ap, arglist);
7128
7129 do
7130 {
7131 code = va_arg (ap, enum tree_code);
7132 switch (code)
7133 {
7134 case 0:
7135 /* This signifies an ellipses, any further arguments are all ok. */
7136 res = 1;
7137 goto end;
7138 case VOID_TYPE:
7139 /* This signifies an endlink, if no arguments remain, return
7140 true, otherwise return false. */
7141 res = arglist == 0;
7142 goto end;
7143 default:
7144 /* If no parameters remain or the parameter's code does not
7145 match the specified code, return false. Otherwise continue
7146 checking any remaining arguments. */
7147 if (arglist == 0
7148 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7149 goto end;
7150 break;
7151 }
7152 arglist = TREE_CHAIN (arglist);
7153 }
7154 while (1);
7155
7156 /* We need gotos here since we can only have one VA_CLOSE in a
7157 function. */
7158 end: ;
7159 va_end (ap);
7160
7161 return res;
7162 }
7163
7164 /* Default target-specific builtin expander that does nothing. */
7165
7166 rtx
7167 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7168 rtx target ATTRIBUTE_UNUSED,
7169 rtx subtarget ATTRIBUTE_UNUSED,
7170 enum machine_mode mode ATTRIBUTE_UNUSED,
7171 int ignore ATTRIBUTE_UNUSED)
7172 {
7173 return NULL_RTX;
7174 }
7175
7176 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
7177
7178 void
7179 purge_builtin_constant_p (void)
7180 {
7181 rtx insn, set, arg, new, note;
7182
7183 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7184 if (INSN_P (insn)
7185 && (set = single_set (insn)) != NULL_RTX
7186 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
7187 || (GET_CODE (arg) == SUBREG
7188 && (GET_CODE (arg = SUBREG_REG (arg))
7189 == CONSTANT_P_RTX))))
7190 {
7191 arg = XEXP (arg, 0);
7192 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
7193 validate_change (insn, &SET_SRC (set), new, 0);
7194
7195 /* Remove the REG_EQUAL note from the insn. */
7196 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
7197 remove_note (insn, note);
7198 }
7199 }
7200
7201 /* Returns true is EXP represents data that would potentially reside
7202 in a readonly section. */
7203
7204 static bool
7205 readonly_data_expr (tree exp)
7206 {
7207 STRIP_NOPS (exp);
7208
7209 if (TREE_CODE (exp) == ADDR_EXPR)
7210 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7211 else
7212 return false;
7213 }