OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [builtins.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Expand builtin functions.
2
   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, 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 "tree-gimple.h"
31
#include "flags.h"
32
#include "regs.h"
33
#include "hard-reg-set.h"
34
#include "except.h"
35
#include "function.h"
36
#include "insn-config.h"
37
#include "expr.h"
38
#include "optabs.h"
39
#include "libfuncs.h"
40
#include "recog.h"
41
#include "output.h"
42
#include "typeclass.h"
43
#include "toplev.h"
44
#include "predict.h"
45
#include "tm_p.h"
46
#include "target.h"
47
#include "langhooks.h"
48
#include "basic-block.h"
49
#include "tree-mudflap.h"
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, COND) #X,
60
const char * 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 const char *c_getstr (tree);
76
static rtx c_readstr (const char *, enum machine_mode);
77
static int target_char_cast (tree, char *);
78
static rtx get_memory_rtx (tree, tree);
79
static tree build_string_literal (int, const char *);
80
static int apply_args_size (void);
81
static int apply_result_size (void);
82
#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83
static rtx result_vector (int, rtx);
84
#endif
85
static rtx expand_builtin_setjmp (tree, rtx);
86
static void expand_builtin_update_setjmp_buf (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_mathfn_3 (tree, rtx, rtx);
98
static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99
static rtx expand_builtin_args_info (tree);
100
static rtx expand_builtin_next_arg (void);
101
static rtx expand_builtin_va_start (tree);
102
static rtx expand_builtin_va_end (tree);
103
static rtx expand_builtin_va_copy (tree);
104
static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105
static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106
static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107
static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108
static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109
static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110
static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111
static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112
static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113
static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114
static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115
static rtx expand_builtin_bcopy (tree);
116
static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117
static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118
static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119
static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120
static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121
static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122
static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123
static rtx expand_builtin_bzero (tree);
124
static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125
static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126
static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127
static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128
static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129
static rtx expand_builtin_alloca (tree, rtx);
130
static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131
static rtx expand_builtin_frame_address (tree, tree);
132
static rtx expand_builtin_fputs (tree, rtx, bool);
133
static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134
static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135
static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136
static tree stabilize_va_list (tree, int);
137
static rtx expand_builtin_expect (tree, rtx);
138
static tree fold_builtin_constant_p (tree);
139
static tree fold_builtin_classify_type (tree);
140
static tree fold_builtin_strlen (tree);
141
static tree fold_builtin_inf (tree, int);
142
static tree fold_builtin_nan (tree, tree, int);
143
static int validate_arglist (tree, ...);
144
static bool integer_valued_real_p (tree);
145
static tree fold_trunc_transparent_mathfn (tree, tree);
146
static bool readonly_data_expr (tree);
147
static rtx expand_builtin_fabs (tree, rtx, rtx);
148
static rtx expand_builtin_signbit (tree, rtx);
149
static tree fold_builtin_cabs (tree, tree);
150
static tree fold_builtin_sqrt (tree, tree);
151
static tree fold_builtin_cbrt (tree, tree);
152
static tree fold_builtin_pow (tree, tree, tree);
153
static tree fold_builtin_powi (tree, tree, tree);
154
static tree fold_builtin_sin (tree);
155
static tree fold_builtin_cos (tree, tree, tree);
156
static tree fold_builtin_tan (tree);
157
static tree fold_builtin_atan (tree, tree);
158
static tree fold_builtin_trunc (tree, tree);
159
static tree fold_builtin_floor (tree, tree);
160
static tree fold_builtin_ceil (tree, tree);
161
static tree fold_builtin_round (tree, tree);
162
static tree fold_builtin_int_roundingfn (tree, tree);
163
static tree fold_builtin_bitop (tree, tree);
164
static tree fold_builtin_memcpy (tree, tree);
165
static tree fold_builtin_mempcpy (tree, tree, int);
166
static tree fold_builtin_memmove (tree, tree);
167
static tree fold_builtin_strchr (tree, tree);
168
static tree fold_builtin_memcmp (tree);
169
static tree fold_builtin_strcmp (tree);
170
static tree fold_builtin_strncmp (tree);
171
static tree fold_builtin_signbit (tree, tree);
172
static tree fold_builtin_copysign (tree, tree, tree);
173
static tree fold_builtin_isascii (tree);
174
static tree fold_builtin_toascii (tree);
175
static tree fold_builtin_isdigit (tree);
176
static tree fold_builtin_fabs (tree, tree);
177
static tree fold_builtin_abs (tree, tree);
178
static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179
                                        enum tree_code);
180
static tree fold_builtin_1 (tree, tree, bool);
181
 
182
static tree fold_builtin_strpbrk (tree, tree);
183
static tree fold_builtin_strstr (tree, tree);
184
static tree fold_builtin_strrchr (tree, tree);
185
static tree fold_builtin_strcat (tree);
186
static tree fold_builtin_strncat (tree);
187
static tree fold_builtin_strspn (tree);
188
static tree fold_builtin_strcspn (tree);
189
static tree fold_builtin_sprintf (tree, int);
190
 
191
static rtx expand_builtin_object_size (tree);
192
static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
193
                                      enum built_in_function);
194
static void maybe_emit_chk_warning (tree, enum built_in_function);
195
static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
196
static tree fold_builtin_object_size (tree);
197
static tree fold_builtin_strcat_chk (tree, tree);
198
static tree fold_builtin_strncat_chk (tree, tree);
199
static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
200
static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
201
static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
202
static bool init_target_chars (void);
203
 
204
static unsigned HOST_WIDE_INT target_newline;
205
static unsigned HOST_WIDE_INT target_percent;
206
static unsigned HOST_WIDE_INT target_c;
207
static unsigned HOST_WIDE_INT target_s;
208
static char target_percent_c[3];
209
static char target_percent_s[3];
210
static char target_percent_s_newline[4];
211
 
212
/* Return true if NODE should be considered for inline expansion regardless
213
   of the optimization level.  This means whenever a function is invoked with
214
   its "internal" name, which normally contains the prefix "__builtin".  */
215
 
216
static bool called_as_built_in (tree node)
217
{
218
  const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
219
  if (strncmp (name, "__builtin_", 10) == 0)
220
    return true;
221
  if (strncmp (name, "__sync_", 7) == 0)
222
    return true;
223
  return false;
224
}
225
 
226
/* Return the alignment in bits of EXP, a pointer valued expression.
227
   But don't return more than MAX_ALIGN no matter what.
228
   The alignment returned is, by default, the alignment of the thing that
229
   EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
230
 
231
   Otherwise, look at the expression to see if we can do better, i.e., if the
232
   expression is actually pointing at an object whose alignment is tighter.  */
233
 
234
static int
235
get_pointer_alignment (tree exp, unsigned int max_align)
236
{
237
  unsigned int align, inner;
238
 
239
  if (! POINTER_TYPE_P (TREE_TYPE (exp)))
240
    return 0;
241
 
242
  align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243
  align = MIN (align, max_align);
244
 
245
  while (1)
246
    {
247
      switch (TREE_CODE (exp))
248
        {
249
        case NOP_EXPR:
250
        case CONVERT_EXPR:
251
        case NON_LVALUE_EXPR:
252
          exp = TREE_OPERAND (exp, 0);
253
          if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254
            return align;
255
 
256
          inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257
          align = MIN (inner, max_align);
258
          break;
259
 
260
        case PLUS_EXPR:
261
          /* If sum of pointer + int, restrict our maximum alignment to that
262
             imposed by the integer.  If not, we can't do any better than
263
             ALIGN.  */
264
          if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265
            return align;
266
 
267
          while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268
                  & (max_align / BITS_PER_UNIT - 1))
269
                 != 0)
270
            max_align >>= 1;
271
 
272
          exp = TREE_OPERAND (exp, 0);
273
          break;
274
 
275
        case ADDR_EXPR:
276
          /* See what we are pointing at and look at its alignment.  */
277
          exp = TREE_OPERAND (exp, 0);
278
          inner = max_align;
279
          while (handled_component_p (exp))
280
            {
281
              /* Fields in a structure can be packed, honour DECL_ALIGN
282
                 of the FIELD_DECL.  For all other references the conservative
283
                 alignment is the element type alignment.  */
284
              if (TREE_CODE (exp) == COMPONENT_REF)
285
                inner = MIN (inner, DECL_ALIGN (TREE_OPERAND (exp, 1)));
286
              else
287
                inner = MIN (inner, TYPE_ALIGN (TREE_TYPE (exp)));
288
              exp = TREE_OPERAND (exp, 0);
289
            }
290
          if (TREE_CODE (exp) == FUNCTION_DECL)
291
            align = FUNCTION_BOUNDARY;
292
          else if (DECL_P (exp))
293
            align = MIN (inner, DECL_ALIGN (exp));
294
#ifdef CONSTANT_ALIGNMENT
295
          else if (CONSTANT_CLASS_P (exp))
296
            align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
297
#endif
298
          else
299
            align = MIN (align, inner);
300
          return MIN (align, max_align);
301
 
302
        default:
303
          return align;
304
        }
305
    }
306
}
307
 
308
/* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
309
   way, because it could contain a zero byte in the middle.
310
   TREE_STRING_LENGTH is the size of the character array, not the string.
311
 
312
   ONLY_VALUE should be nonzero if the result is not going to be emitted
313
   into the instruction stream and zero if it is going to be expanded.
314
   E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
315
   is returned, otherwise NULL, since
316
   len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
317
   evaluate the side-effects.
318
 
319
   The value returned is of type `ssizetype'.
320
 
321
   Unfortunately, string_constant can't access the values of const char
322
   arrays with initializers, so neither can we do so here.  */
323
 
324
tree
325
c_strlen (tree src, int only_value)
326
{
327
  tree offset_node;
328
  HOST_WIDE_INT offset;
329
  int max;
330
  const char *ptr;
331
 
332
  STRIP_NOPS (src);
333
  if (TREE_CODE (src) == COND_EXPR
334
      && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
335
    {
336
      tree len1, len2;
337
 
338
      len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
339
      len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
340
      if (tree_int_cst_equal (len1, len2))
341
        return len1;
342
    }
343
 
344
  if (TREE_CODE (src) == COMPOUND_EXPR
345
      && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
346
    return c_strlen (TREE_OPERAND (src, 1), only_value);
347
 
348
  src = string_constant (src, &offset_node);
349
  if (src == 0)
350
    return 0;
351
 
352
  max = TREE_STRING_LENGTH (src) - 1;
353
  ptr = TREE_STRING_POINTER (src);
354
 
355
  if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
356
    {
357
      /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
358
         compute the offset to the following null if we don't know where to
359
         start searching for it.  */
360
      int i;
361
 
362
      for (i = 0; i < max; i++)
363
        if (ptr[i] == 0)
364
          return 0;
365
 
366
      /* We don't know the starting offset, but we do know that the string
367
         has no internal zero bytes.  We can assume that the offset falls
368
         within the bounds of the string; otherwise, the programmer deserves
369
         what he gets.  Subtract the offset from the length of the string,
370
         and return that.  This would perhaps not be valid if we were dealing
371
         with named arrays in addition to literal string constants.  */
372
 
373
      return size_diffop (size_int (max), offset_node);
374
    }
375
 
376
  /* We have a known offset into the string.  Start searching there for
377
     a null character if we can represent it as a single HOST_WIDE_INT.  */
378
  if (offset_node == 0)
379
    offset = 0;
380
  else if (! host_integerp (offset_node, 0))
381
    offset = -1;
382
  else
383
    offset = tree_low_cst (offset_node, 0);
384
 
385
  /* If the offset is known to be out of bounds, warn, and call strlen at
386
     runtime.  */
387
  if (offset < 0 || offset > max)
388
    {
389
      warning (0, "offset outside bounds of constant string");
390
      return 0;
391
    }
392
 
393
  /* Use strlen to search for the first zero byte.  Since any strings
394
     constructed with build_string will have nulls appended, we win even
395
     if we get handed something like (char[4])"abcd".
396
 
397
     Since OFFSET is our starting index into the string, no further
398
     calculation is needed.  */
399
  return ssize_int (strlen (ptr + offset));
400
}
401
 
402
/* Return a char pointer for a C string if it is a string constant
403
   or sum of string constant and integer constant.  */
404
 
405
static const char *
406
c_getstr (tree src)
407
{
408
  tree offset_node;
409
 
410
  src = string_constant (src, &offset_node);
411
  if (src == 0)
412
    return 0;
413
 
414
  if (offset_node == 0)
415
    return TREE_STRING_POINTER (src);
416
  else if (!host_integerp (offset_node, 1)
417
           || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
418
    return 0;
419
 
420
  return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
421
}
422
 
423
/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
424
   GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
425
 
426
static rtx
427
c_readstr (const char *str, enum machine_mode mode)
428
{
429
  HOST_WIDE_INT c[2];
430
  HOST_WIDE_INT ch;
431
  unsigned int i, j;
432
 
433
  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
434
 
435
  c[0] = 0;
436
  c[1] = 0;
437
  ch = 1;
438
  for (i = 0; i < GET_MODE_SIZE (mode); i++)
439
    {
440
      j = i;
441
      if (WORDS_BIG_ENDIAN)
442
        j = GET_MODE_SIZE (mode) - i - 1;
443
      if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
444
          && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
445
        j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
446
      j *= BITS_PER_UNIT;
447
      gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
448
 
449
      if (ch)
450
        ch = (unsigned char) str[i];
451
      c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
452
    }
453
  return immed_double_const (c[0], c[1], mode);
454
}
455
 
456
/* Cast a target constant CST to target CHAR and if that value fits into
457
   host char type, return zero and put that value into variable pointed to by
458
   P.  */
459
 
460
static int
461
target_char_cast (tree cst, char *p)
462
{
463
  unsigned HOST_WIDE_INT val, hostval;
464
 
465
  if (!host_integerp (cst, 1)
466
      || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
467
    return 1;
468
 
469
  val = tree_low_cst (cst, 1);
470
  if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
471
    val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
472
 
473
  hostval = val;
474
  if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
475
    hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
476
 
477
  if (val != hostval)
478
    return 1;
479
 
480
  *p = hostval;
481
  return 0;
482
}
483
 
484
/* Similar to save_expr, but assumes that arbitrary code is not executed
485
   in between the multiple evaluations.  In particular, we assume that a
486
   non-addressable local variable will not be modified.  */
487
 
488
static tree
489
builtin_save_expr (tree exp)
490
{
491
  if (TREE_ADDRESSABLE (exp) == 0
492
      && (TREE_CODE (exp) == PARM_DECL
493
          || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
494
    return exp;
495
 
496
  return save_expr (exp);
497
}
498
 
499
/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
500
   times to get the address of either a higher stack frame, or a return
501
   address located within it (depending on FNDECL_CODE).  */
502
 
503
static rtx
504
expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
505
{
506
  int i;
507
 
508
#ifdef INITIAL_FRAME_ADDRESS_RTX
509
  rtx tem = INITIAL_FRAME_ADDRESS_RTX;
510
#else
511
  rtx tem;
512
 
513
  /* For a zero count, we don't care what frame address we return, so frame
514
     pointer elimination is OK, and using the soft frame pointer is OK.
515
     For a non-zero count, we require a stable offset from the current frame
516
     pointer to the previous one, so we must use the hard frame pointer, and
517
     we must disable frame pointer elimination.  */
518
  if (count == 0)
519
    tem = frame_pointer_rtx;
520
  else
521
    {
522
      tem = hard_frame_pointer_rtx;
523
 
524
      /* Tell reload not to eliminate the frame pointer.  */
525
      current_function_accesses_prior_frames = 1;
526
    }
527
#endif
528
 
529
  /* Some machines need special handling before we can access
530
     arbitrary frames.  For example, on the sparc, we must first flush
531
     all register windows to the stack.  */
532
#ifdef SETUP_FRAME_ADDRESSES
533
  if (count > 0)
534
    SETUP_FRAME_ADDRESSES ();
535
#endif
536
 
537
  /* On the sparc, the return address is not in the frame, it is in a
538
     register.  There is no way to access it off of the current frame
539
     pointer, but it can be accessed off the previous frame pointer by
540
     reading the value from the register window save area.  */
541
#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
542
  if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
543
    count--;
544
#endif
545
 
546
  /* Scan back COUNT frames to the specified frame.  */
547
  for (i = 0; i < count; i++)
548
    {
549
      /* Assume the dynamic chain pointer is in the word that the
550
         frame address points to, unless otherwise specified.  */
551
#ifdef DYNAMIC_CHAIN_ADDRESS
552
      tem = DYNAMIC_CHAIN_ADDRESS (tem);
553
#endif
554
      tem = memory_address (Pmode, tem);
555
      tem = gen_frame_mem (Pmode, tem);
556
      tem = copy_to_reg (tem);
557
    }
558
 
559
  /* For __builtin_frame_address, return what we've got.  */
560
  if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
561
    return tem;
562
 
563
  /* For __builtin_return_address, Get the return address from that
564
     frame.  */
565
#ifdef RETURN_ADDR_RTX
566
  tem = RETURN_ADDR_RTX (count, tem);
567
#else
568
  tem = memory_address (Pmode,
569
                        plus_constant (tem, GET_MODE_SIZE (Pmode)));
570
  tem = gen_frame_mem (Pmode, tem);
571
#endif
572
  return tem;
573
}
574
 
575
/* Alias set used for setjmp buffer.  */
576
static HOST_WIDE_INT setjmp_alias_set = -1;
577
 
578
/* Construct the leading half of a __builtin_setjmp call.  Control will
579
   return to RECEIVER_LABEL.  This is used directly by sjlj exception
580
   handling code.  */
581
 
582
void
583
expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
584
{
585
  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
586
  rtx stack_save;
587
  rtx mem;
588
 
589
  if (setjmp_alias_set == -1)
590
    setjmp_alias_set = new_alias_set ();
591
 
592
  buf_addr = convert_memory_address (Pmode, buf_addr);
593
 
594
  buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
595
 
596
  /* We store the frame pointer and the address of receiver_label in
597
     the buffer and use the rest of it for the stack save area, which
598
     is machine-dependent.  */
599
 
600
  mem = gen_rtx_MEM (Pmode, buf_addr);
601
  set_mem_alias_set (mem, setjmp_alias_set);
602
  emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
603
 
604
  mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
605
  set_mem_alias_set (mem, setjmp_alias_set);
606
 
607
  emit_move_insn (validize_mem (mem),
608
                  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
609
 
610
  stack_save = gen_rtx_MEM (sa_mode,
611
                            plus_constant (buf_addr,
612
                                           2 * GET_MODE_SIZE (Pmode)));
613
  set_mem_alias_set (stack_save, setjmp_alias_set);
614
  emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
615
 
616
  /* If there is further processing to do, do it.  */
617
#ifdef HAVE_builtin_setjmp_setup
618
  if (HAVE_builtin_setjmp_setup)
619
    emit_insn (gen_builtin_setjmp_setup (buf_addr));
620
#endif
621
 
622
  /* Tell optimize_save_area_alloca that extra work is going to
623
     need to go on during alloca.  */
624
  current_function_calls_setjmp = 1;
625
 
626
  /* Set this so all the registers get saved in our frame; we need to be
627
     able to copy the saved values for any registers from frames we unwind.  */
628
  current_function_has_nonlocal_label = 1;
629
}
630
 
631
/* Construct the trailing part of a __builtin_setjmp call.
632
   This is used directly by sjlj exception handling code.  */
633
 
634
void
635
expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
636
{
637
  /* Clobber the FP when we get here, so we have to make sure it's
638
     marked as used by this function.  */
639
  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
640
 
641
  /* Mark the static chain as clobbered here so life information
642
     doesn't get messed up for it.  */
643
  emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
644
 
645
  /* Now put in the code to restore the frame pointer, and argument
646
     pointer, if needed.  */
647
#ifdef HAVE_nonlocal_goto
648
  if (! HAVE_nonlocal_goto)
649
#endif
650
    emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
651
 
652
#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
653
  if (fixed_regs[ARG_POINTER_REGNUM])
654
    {
655
#ifdef ELIMINABLE_REGS
656
      size_t i;
657
      static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
658
 
659
      for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
660
        if (elim_regs[i].from == ARG_POINTER_REGNUM
661
            && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
662
          break;
663
 
664
      if (i == ARRAY_SIZE (elim_regs))
665
#endif
666
        {
667
          /* Now restore our arg pointer from the address at which it
668
             was saved in our stack frame.  */
669
          emit_move_insn (virtual_incoming_args_rtx,
670
                          copy_to_reg (get_arg_pointer_save_area (cfun)));
671
        }
672
    }
673
#endif
674
 
675
#ifdef HAVE_builtin_setjmp_receiver
676
  if (HAVE_builtin_setjmp_receiver)
677
    emit_insn (gen_builtin_setjmp_receiver (receiver_label));
678
  else
679
#endif
680
#ifdef HAVE_nonlocal_goto_receiver
681
    if (HAVE_nonlocal_goto_receiver)
682
      emit_insn (gen_nonlocal_goto_receiver ());
683
    else
684
#endif
685
      { /* Nothing */ }
686
 
687
  /* @@@ This is a kludge.  Not all machine descriptions define a blockage
688
     insn, but we must not allow the code we just generated to be reordered
689
     by scheduling.  Specifically, the update of the frame pointer must
690
     happen immediately, not later.  So emit an ASM_INPUT to act as blockage
691
     insn.  */
692
  emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
693
}
694
 
695
/* __builtin_setjmp is passed a pointer to an array of five words (not
696
   all will be used on all machines).  It operates similarly to the C
697
   library function of the same name, but is more efficient.  Much of
698
   the code below (and for longjmp) is copied from the handling of
699
   non-local gotos.
700
 
701
   NOTE: This is intended for use by GNAT and the exception handling
702
   scheme in the compiler and will only work in the method used by
703
   them.  */
704
 
705
static rtx
706
expand_builtin_setjmp (tree arglist, rtx target)
707
{
708
  rtx buf_addr, next_lab, cont_lab;
709
 
710
  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
711
    return NULL_RTX;
712
 
713
  if (target == 0 || !REG_P (target)
714
      || REGNO (target) < FIRST_PSEUDO_REGISTER)
715
    target = gen_reg_rtx (TYPE_MODE (integer_type_node));
716
 
717
  buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
718
 
719
  next_lab = gen_label_rtx ();
720
  cont_lab = gen_label_rtx ();
721
 
722
  expand_builtin_setjmp_setup (buf_addr, next_lab);
723
 
724
  /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
725
     ensure that pending stack adjustments are flushed.  */
726
  emit_move_insn (target, const0_rtx);
727
  emit_jump (cont_lab);
728
 
729
  emit_label (next_lab);
730
 
731
  expand_builtin_setjmp_receiver (next_lab);
732
 
733
  /* Set TARGET to one.  */
734
  emit_move_insn (target, const1_rtx);
735
  emit_label (cont_lab);
736
 
737
  /* Tell flow about the strange goings on.  Putting `next_lab' on
738
     `nonlocal_goto_handler_labels' to indicates that function
739
     calls may traverse the arc back to this label.  */
740
 
741
  current_function_has_nonlocal_label = 1;
742
  nonlocal_goto_handler_labels
743
    = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
744
 
745
  return target;
746
}
747
 
748
/* __builtin_longjmp is passed a pointer to an array of five words (not
749
   all will be used on all machines).  It operates similarly to the C
750
   library function of the same name, but is more efficient.  Much of
751
   the code below is copied from the handling of non-local gotos.
752
 
753
   NOTE: This is intended for use by GNAT and the exception handling
754
   scheme in the compiler and will only work in the method used by
755
   them.  */
756
 
757
static void
758
expand_builtin_longjmp (rtx buf_addr, rtx value)
759
{
760
  rtx fp, lab, stack, insn, last;
761
  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
762
 
763
  if (setjmp_alias_set == -1)
764
    setjmp_alias_set = new_alias_set ();
765
 
766
  buf_addr = convert_memory_address (Pmode, buf_addr);
767
 
768
  buf_addr = force_reg (Pmode, buf_addr);
769
 
770
  /* We used to store value in static_chain_rtx, but that fails if pointers
771
     are smaller than integers.  We instead require that the user must pass
772
     a second argument of 1, because that is what builtin_setjmp will
773
     return.  This also makes EH slightly more efficient, since we are no
774
     longer copying around a value that we don't care about.  */
775
  gcc_assert (value == const1_rtx);
776
 
777
  last = get_last_insn ();
778
#ifdef HAVE_builtin_longjmp
779
  if (HAVE_builtin_longjmp)
780
    emit_insn (gen_builtin_longjmp (buf_addr));
781
  else
782
#endif
783
    {
784
      fp = gen_rtx_MEM (Pmode, buf_addr);
785
      lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
786
                                               GET_MODE_SIZE (Pmode)));
787
 
788
      stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
789
                                                   2 * GET_MODE_SIZE (Pmode)));
790
      set_mem_alias_set (fp, setjmp_alias_set);
791
      set_mem_alias_set (lab, setjmp_alias_set);
792
      set_mem_alias_set (stack, setjmp_alias_set);
793
 
794
      /* Pick up FP, label, and SP from the block and jump.  This code is
795
         from expand_goto in stmt.c; see there for detailed comments.  */
796
#if HAVE_nonlocal_goto
797
      if (HAVE_nonlocal_goto)
798
        /* We have to pass a value to the nonlocal_goto pattern that will
799
           get copied into the static_chain pointer, but it does not matter
800
           what that value is, because builtin_setjmp does not use it.  */
801
        emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
802
      else
803
#endif
804
        {
805
          lab = copy_to_reg (lab);
806
 
807
          emit_insn (gen_rtx_CLOBBER (VOIDmode,
808
                                      gen_rtx_MEM (BLKmode,
809
                                                   gen_rtx_SCRATCH (VOIDmode))));
810
          emit_insn (gen_rtx_CLOBBER (VOIDmode,
811
                                      gen_rtx_MEM (BLKmode,
812
                                                   hard_frame_pointer_rtx)));
813
 
814
          emit_move_insn (hard_frame_pointer_rtx, fp);
815
          emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
816
 
817
          emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
818
          emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
819
          emit_indirect_jump (lab);
820
        }
821
    }
822
 
823
  /* Search backwards and mark the jump insn as a non-local goto.
824
     Note that this precludes the use of __builtin_longjmp to a
825
     __builtin_setjmp target in the same function.  However, we've
826
     already cautioned the user that these functions are for
827
     internal exception handling use only.  */
828
  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
829
    {
830
      gcc_assert (insn != last);
831
 
832
      if (JUMP_P (insn))
833
        {
834
          REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
835
                                              REG_NOTES (insn));
836
          break;
837
        }
838
      else if (CALL_P (insn))
839
        break;
840
    }
841
}
842
 
843
/* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
844
   and the address of the save area.  */
845
 
846
static rtx
847
expand_builtin_nonlocal_goto (tree arglist)
848
{
849
  tree t_label, t_save_area;
850
  rtx r_label, r_save_area, r_fp, r_sp, insn;
851
 
852
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
853
    return NULL_RTX;
854
 
855
  t_label = TREE_VALUE (arglist);
856
  arglist = TREE_CHAIN (arglist);
857
  t_save_area = TREE_VALUE (arglist);
858
 
859
  r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
860
  r_label = convert_memory_address (Pmode, r_label);
861
  r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
862
  r_save_area = convert_memory_address (Pmode, r_save_area);
863
  r_fp = gen_rtx_MEM (Pmode, r_save_area);
864
  r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
865
                      plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
866
 
867
  current_function_has_nonlocal_goto = 1;
868
 
869
#if HAVE_nonlocal_goto
870
  /* ??? We no longer need to pass the static chain value, afaik.  */
871
  if (HAVE_nonlocal_goto)
872
    emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
873
  else
874
#endif
875
    {
876
      r_label = copy_to_reg (r_label);
877
 
878
      emit_insn (gen_rtx_CLOBBER (VOIDmode,
879
                                  gen_rtx_MEM (BLKmode,
880
                                               gen_rtx_SCRATCH (VOIDmode))));
881
 
882
      emit_insn (gen_rtx_CLOBBER (VOIDmode,
883
                                  gen_rtx_MEM (BLKmode,
884
                                               hard_frame_pointer_rtx)));
885
 
886
      /* Restore frame pointer for containing function.
887
         This sets the actual hard register used for the frame pointer
888
         to the location of the function's incoming static chain info.
889
         The non-local goto handler will then adjust it to contain the
890
         proper value and reload the argument pointer, if needed.  */
891
      emit_move_insn (hard_frame_pointer_rtx, r_fp);
892
      emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
893
 
894
      /* USE of hard_frame_pointer_rtx added for consistency;
895
         not clear if really needed.  */
896
      emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
897
      emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
898
      emit_indirect_jump (r_label);
899
    }
900
 
901
  /* Search backwards to the jump insn and mark it as a
902
     non-local goto.  */
903
  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
904
    {
905
      if (JUMP_P (insn))
906
        {
907
          REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
908
                                              const0_rtx, REG_NOTES (insn));
909
          break;
910
        }
911
      else if (CALL_P (insn))
912
        break;
913
    }
914
 
915
  return const0_rtx;
916
}
917
 
918
/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
919
   (not all will be used on all machines) that was passed to __builtin_setjmp.
920
   It updates the stack pointer in that block to correspond to the current
921
   stack pointer.  */
922
 
923
static void
924
expand_builtin_update_setjmp_buf (rtx buf_addr)
925
{
926
  enum machine_mode sa_mode = Pmode;
927
  rtx stack_save;
928
 
929
 
930
#ifdef HAVE_save_stack_nonlocal
931
  if (HAVE_save_stack_nonlocal)
932
    sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
933
#endif
934
#ifdef STACK_SAVEAREA_MODE
935
  sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
936
#endif
937
 
938
  stack_save
939
    = gen_rtx_MEM (sa_mode,
940
                   memory_address
941
                   (sa_mode,
942
                    plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
943
 
944
#ifdef HAVE_setjmp
945
  if (HAVE_setjmp)
946
    emit_insn (gen_setjmp ());
947
#endif
948
 
949
  emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
950
}
951
 
952
/* Expand a call to __builtin_prefetch.  For a target that does not support
953
   data prefetch, evaluate the memory address argument in case it has side
954
   effects.  */
955
 
956
static void
957
expand_builtin_prefetch (tree arglist)
958
{
959
  tree arg0, arg1, arg2;
960
  rtx op0, op1, op2;
961
 
962
  if (!validate_arglist (arglist, POINTER_TYPE, 0))
963
    return;
964
 
965
  arg0 = TREE_VALUE (arglist);
966
  /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
967
     zero (read) and argument 2 (locality) defaults to 3 (high degree of
968
     locality).  */
969
  if (TREE_CHAIN (arglist))
970
    {
971
      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
972
      if (TREE_CHAIN (TREE_CHAIN (arglist)))
973
        arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
974
      else
975
        arg2 = build_int_cst (NULL_TREE, 3);
976
    }
977
  else
978
    {
979
      arg1 = integer_zero_node;
980
      arg2 = build_int_cst (NULL_TREE, 3);
981
    }
982
 
983
  /* Argument 0 is an address.  */
984
  op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
985
 
986
  /* Argument 1 (read/write flag) must be a compile-time constant int.  */
987
  if (TREE_CODE (arg1) != INTEGER_CST)
988
    {
989
      error ("second argument to %<__builtin_prefetch%> must be a constant");
990
      arg1 = integer_zero_node;
991
    }
992
  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
993
  /* Argument 1 must be either zero or one.  */
994
  if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
995
    {
996
      warning (0, "invalid second argument to %<__builtin_prefetch%>;"
997
               " using zero");
998
      op1 = const0_rtx;
999
    }
1000
 
1001
  /* Argument 2 (locality) must be a compile-time constant int.  */
1002
  if (TREE_CODE (arg2) != INTEGER_CST)
1003
    {
1004
      error ("third argument to %<__builtin_prefetch%> must be a constant");
1005
      arg2 = integer_zero_node;
1006
    }
1007
  op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1008
  /* Argument 2 must be 0, 1, 2, or 3.  */
1009
  if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1010
    {
1011
      warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1012
      op2 = const0_rtx;
1013
    }
1014
 
1015
#ifdef HAVE_prefetch
1016
  if (HAVE_prefetch)
1017
    {
1018
      if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1019
             (op0,
1020
              insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1021
          || (GET_MODE (op0) != Pmode))
1022
        {
1023
          op0 = convert_memory_address (Pmode, op0);
1024
          op0 = force_reg (Pmode, op0);
1025
        }
1026
      emit_insn (gen_prefetch (op0, op1, op2));
1027
    }
1028
#endif
1029
 
1030
  /* Don't do anything with direct references to volatile memory, but
1031
     generate code to handle other side effects.  */
1032
  if (!MEM_P (op0) && side_effects_p (op0))
1033
    emit_insn (op0);
1034
}
1035
 
1036
/* Get a MEM rtx for expression EXP which is the address of an operand
1037
   to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1038
   the maximum length of the block of memory that might be accessed or
1039
   NULL if unknown.  */
1040
 
1041
static rtx
1042
get_memory_rtx (tree exp, tree len)
1043
{
1044
  rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1045
  rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1046
 
1047
  /* Get an expression we can use to find the attributes to assign to MEM.
1048
     If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1049
     we can.  First remove any nops.  */
1050
  while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1051
          || TREE_CODE (exp) == NON_LVALUE_EXPR)
1052
         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1053
    exp = TREE_OPERAND (exp, 0);
1054
 
1055
  if (TREE_CODE (exp) == ADDR_EXPR)
1056
    exp = TREE_OPERAND (exp, 0);
1057
  else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1058
    exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1059
  else
1060
    exp = NULL;
1061
 
1062
  /* Honor attributes derived from exp, except for the alias set
1063
     (as builtin stringops may alias with anything) and the size
1064
     (as stringops may access multiple array elements).  */
1065
  if (exp)
1066
    {
1067
      set_mem_attributes (mem, exp, 0);
1068
 
1069
      /* Allow the string and memory builtins to overflow from one
1070
         field into another, see http://gcc.gnu.org/PR23561.
1071
         Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1072
         memory accessed by the string or memory builtin will fit
1073
         within the field.  */
1074
      if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1075
        {
1076
          tree mem_expr = MEM_EXPR (mem);
1077
          HOST_WIDE_INT offset = -1, length = -1;
1078
          tree inner = exp;
1079
 
1080
          while (TREE_CODE (inner) == ARRAY_REF
1081
                 || TREE_CODE (inner) == NOP_EXPR
1082
                 || TREE_CODE (inner) == CONVERT_EXPR
1083
                 || TREE_CODE (inner) == NON_LVALUE_EXPR
1084
                 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1085
                 || TREE_CODE (inner) == SAVE_EXPR)
1086
            inner = TREE_OPERAND (inner, 0);
1087
 
1088
          gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1089
 
1090
          if (MEM_OFFSET (mem)
1091
              && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1092
            offset = INTVAL (MEM_OFFSET (mem));
1093
 
1094
          if (offset >= 0 && len && host_integerp (len, 0))
1095
            length = tree_low_cst (len, 0);
1096
 
1097
          while (TREE_CODE (inner) == COMPONENT_REF)
1098
            {
1099
              tree field = TREE_OPERAND (inner, 1);
1100
              gcc_assert (! DECL_BIT_FIELD (field));
1101
              gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1102
              gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1103
 
1104
              if (length >= 0
1105
                  && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1106
                  && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1107
                {
1108
                  HOST_WIDE_INT size
1109
                    = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1110
                  /* If we can prove the memory starting at XEXP (mem, 0)
1111
                     and ending at XEXP (mem, 0) + LENGTH will fit into
1112
                     this field, we can keep that COMPONENT_REF in MEM_EXPR.  */
1113
                  if (offset <= size
1114
                      && length <= size
1115
                      && offset + length <= size)
1116
                    break;
1117
                }
1118
 
1119
              if (offset >= 0
1120
                  && host_integerp (DECL_FIELD_OFFSET (field), 0))
1121
                offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1122
                          + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1123
                            / BITS_PER_UNIT;
1124
              else
1125
                {
1126
                  offset = -1;
1127
                  length = -1;
1128
                }
1129
 
1130
              mem_expr = TREE_OPERAND (mem_expr, 0);
1131
              inner = TREE_OPERAND (inner, 0);
1132
            }
1133
 
1134
          if (mem_expr == NULL)
1135
            offset = -1;
1136
          if (mem_expr != MEM_EXPR (mem))
1137
            {
1138
              set_mem_expr (mem, mem_expr);
1139
              set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1140
            }
1141
        }
1142
      set_mem_alias_set (mem, 0);
1143
      set_mem_size (mem, NULL_RTX);
1144
    }
1145
 
1146
  return mem;
1147
}
1148
 
1149
/* Built-in functions to perform an untyped call and return.  */
1150
 
1151
/* For each register that may be used for calling a function, this
1152
   gives a mode used to copy the register's value.  VOIDmode indicates
1153
   the register is not used for calling a function.  If the machine
1154
   has register windows, this gives only the outbound registers.
1155
   INCOMING_REGNO gives the corresponding inbound register.  */
1156
static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1157
 
1158
/* For each register that may be used for returning values, this gives
1159
   a mode used to copy the register's value.  VOIDmode indicates the
1160
   register is not used for returning values.  If the machine has
1161
   register windows, this gives only the outbound registers.
1162
   INCOMING_REGNO gives the corresponding inbound register.  */
1163
static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1164
 
1165
/* For each register that may be used for calling a function, this
1166
   gives the offset of that register into the block returned by
1167
   __builtin_apply_args.  0 indicates that the register is not
1168
   used for calling a function.  */
1169
static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1170
 
1171
/* Return the size required for the block returned by __builtin_apply_args,
1172
   and initialize apply_args_mode.  */
1173
 
1174
static int
1175
apply_args_size (void)
1176
{
1177
  static int size = -1;
1178
  int align;
1179
  unsigned int regno;
1180
  enum machine_mode mode;
1181
 
1182
  /* The values computed by this function never change.  */
1183
  if (size < 0)
1184
    {
1185
      /* The first value is the incoming arg-pointer.  */
1186
      size = GET_MODE_SIZE (Pmode);
1187
 
1188
      /* The second value is the structure value address unless this is
1189
         passed as an "invisible" first argument.  */
1190
      if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1191
        size += GET_MODE_SIZE (Pmode);
1192
 
1193
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1194
        if (FUNCTION_ARG_REGNO_P (regno))
1195
          {
1196
            mode = reg_raw_mode[regno];
1197
 
1198
            gcc_assert (mode != VOIDmode);
1199
 
1200
            align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1201
            if (size % align != 0)
1202
              size = CEIL (size, align) * align;
1203
            apply_args_reg_offset[regno] = size;
1204
            size += GET_MODE_SIZE (mode);
1205
            apply_args_mode[regno] = mode;
1206
          }
1207
        else
1208
          {
1209
            apply_args_mode[regno] = VOIDmode;
1210
            apply_args_reg_offset[regno] = 0;
1211
          }
1212
    }
1213
  return size;
1214
}
1215
 
1216
/* Return the size required for the block returned by __builtin_apply,
1217
   and initialize apply_result_mode.  */
1218
 
1219
static int
1220
apply_result_size (void)
1221
{
1222
  static int size = -1;
1223
  int align, regno;
1224
  enum machine_mode mode;
1225
 
1226
  /* The values computed by this function never change.  */
1227
  if (size < 0)
1228
    {
1229
      size = 0;
1230
 
1231
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1232
        if (FUNCTION_VALUE_REGNO_P (regno))
1233
          {
1234
            mode = reg_raw_mode[regno];
1235
 
1236
            gcc_assert (mode != VOIDmode);
1237
 
1238
            align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1239
            if (size % align != 0)
1240
              size = CEIL (size, align) * align;
1241
            size += GET_MODE_SIZE (mode);
1242
            apply_result_mode[regno] = mode;
1243
          }
1244
        else
1245
          apply_result_mode[regno] = VOIDmode;
1246
 
1247
      /* Allow targets that use untyped_call and untyped_return to override
1248
         the size so that machine-specific information can be stored here.  */
1249
#ifdef APPLY_RESULT_SIZE
1250
      size = APPLY_RESULT_SIZE;
1251
#endif
1252
    }
1253
  return size;
1254
}
1255
 
1256
#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1257
/* Create a vector describing the result block RESULT.  If SAVEP is true,
1258
   the result block is used to save the values; otherwise it is used to
1259
   restore the values.  */
1260
 
1261
static rtx
1262
result_vector (int savep, rtx result)
1263
{
1264
  int regno, size, align, nelts;
1265
  enum machine_mode mode;
1266
  rtx reg, mem;
1267
  rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1268
 
1269
  size = nelts = 0;
1270
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1271
    if ((mode = apply_result_mode[regno]) != VOIDmode)
1272
      {
1273
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1274
        if (size % align != 0)
1275
          size = CEIL (size, align) * align;
1276
        reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1277
        mem = adjust_address (result, mode, size);
1278
        savevec[nelts++] = (savep
1279
                            ? gen_rtx_SET (VOIDmode, mem, reg)
1280
                            : gen_rtx_SET (VOIDmode, reg, mem));
1281
        size += GET_MODE_SIZE (mode);
1282
      }
1283
  return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1284
}
1285
#endif /* HAVE_untyped_call or HAVE_untyped_return */
1286
 
1287
/* Save the state required to perform an untyped call with the same
1288
   arguments as were passed to the current function.  */
1289
 
1290
static rtx
1291
expand_builtin_apply_args_1 (void)
1292
{
1293
  rtx registers, tem;
1294
  int size, align, regno;
1295
  enum machine_mode mode;
1296
  rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1297
 
1298
  /* Create a block where the arg-pointer, structure value address,
1299
     and argument registers can be saved.  */
1300
  registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1301
 
1302
  /* Walk past the arg-pointer and structure value address.  */
1303
  size = GET_MODE_SIZE (Pmode);
1304
  if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1305
    size += GET_MODE_SIZE (Pmode);
1306
 
1307
  /* Save each register used in calling a function to the block.  */
1308
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1309
    if ((mode = apply_args_mode[regno]) != VOIDmode)
1310
      {
1311
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1312
        if (size % align != 0)
1313
          size = CEIL (size, align) * align;
1314
 
1315
        tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1316
 
1317
        emit_move_insn (adjust_address (registers, mode, size), tem);
1318
        size += GET_MODE_SIZE (mode);
1319
      }
1320
 
1321
  /* Save the arg pointer to the block.  */
1322
  tem = copy_to_reg (virtual_incoming_args_rtx);
1323
#ifdef STACK_GROWS_DOWNWARD
1324
  /* We need the pointer as the caller actually passed them to us, not
1325
     as we might have pretended they were passed.  Make sure it's a valid
1326
     operand, as emit_move_insn isn't expected to handle a PLUS.  */
1327
  tem
1328
    = force_operand (plus_constant (tem, current_function_pretend_args_size),
1329
                     NULL_RTX);
1330
#endif
1331
  emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1332
 
1333
  size = GET_MODE_SIZE (Pmode);
1334
 
1335
  /* Save the structure value address unless this is passed as an
1336
     "invisible" first argument.  */
1337
  if (struct_incoming_value)
1338
    {
1339
      emit_move_insn (adjust_address (registers, Pmode, size),
1340
                      copy_to_reg (struct_incoming_value));
1341
      size += GET_MODE_SIZE (Pmode);
1342
    }
1343
 
1344
  /* Return the address of the block.  */
1345
  return copy_addr_to_reg (XEXP (registers, 0));
1346
}
1347
 
1348
/* __builtin_apply_args returns block of memory allocated on
1349
   the stack into which is stored the arg pointer, structure
1350
   value address, static chain, and all the registers that might
1351
   possibly be used in performing a function call.  The code is
1352
   moved to the start of the function so the incoming values are
1353
   saved.  */
1354
 
1355
static rtx
1356
expand_builtin_apply_args (void)
1357
{
1358
  /* Don't do __builtin_apply_args more than once in a function.
1359
     Save the result of the first call and reuse it.  */
1360
  if (apply_args_value != 0)
1361
    return apply_args_value;
1362
  {
1363
    /* When this function is called, it means that registers must be
1364
       saved on entry to this function.  So we migrate the
1365
       call to the first insn of this function.  */
1366
    rtx temp;
1367
    rtx seq;
1368
 
1369
    start_sequence ();
1370
    temp = expand_builtin_apply_args_1 ();
1371
    seq = get_insns ();
1372
    end_sequence ();
1373
 
1374
    apply_args_value = temp;
1375
 
1376
    /* Put the insns after the NOTE that starts the function.
1377
       If this is inside a start_sequence, make the outer-level insn
1378
       chain current, so the code is placed at the start of the
1379
       function.  */
1380
    push_topmost_sequence ();
1381
    emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1382
    pop_topmost_sequence ();
1383
    return temp;
1384
  }
1385
}
1386
 
1387
/* Perform an untyped call and save the state required to perform an
1388
   untyped return of whatever value was returned by the given function.  */
1389
 
1390
static rtx
1391
expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1392
{
1393
  int size, align, regno;
1394
  enum machine_mode mode;
1395
  rtx incoming_args, result, reg, dest, src, call_insn;
1396
  rtx old_stack_level = 0;
1397
  rtx call_fusage = 0;
1398
  rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1399
 
1400
  arguments = convert_memory_address (Pmode, arguments);
1401
 
1402
  /* Create a block where the return registers can be saved.  */
1403
  result = assign_stack_local (BLKmode, apply_result_size (), -1);
1404
 
1405
  /* Fetch the arg pointer from the ARGUMENTS block.  */
1406
  incoming_args = gen_reg_rtx (Pmode);
1407
  emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1408
#ifndef STACK_GROWS_DOWNWARD
1409
  incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1410
                                       incoming_args, 0, OPTAB_LIB_WIDEN);
1411
#endif
1412
 
1413
  /* Push a new argument block and copy the arguments.  Do not allow
1414
     the (potential) memcpy call below to interfere with our stack
1415
     manipulations.  */
1416
  do_pending_stack_adjust ();
1417
  NO_DEFER_POP;
1418
 
1419
  /* Save the stack with nonlocal if available.  */
1420
#ifdef HAVE_save_stack_nonlocal
1421
  if (HAVE_save_stack_nonlocal)
1422
    emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1423
  else
1424
#endif
1425
    emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1426
 
1427
  /* Allocate a block of memory onto the stack and copy the memory
1428
     arguments to the outgoing arguments address.  */
1429
  allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1430
  dest = virtual_outgoing_args_rtx;
1431
#ifndef STACK_GROWS_DOWNWARD
1432
  if (GET_CODE (argsize) == CONST_INT)
1433
    dest = plus_constant (dest, -INTVAL (argsize));
1434
  else
1435
    dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1436
#endif
1437
  dest = gen_rtx_MEM (BLKmode, dest);
1438
  set_mem_align (dest, PARM_BOUNDARY);
1439
  src = gen_rtx_MEM (BLKmode, incoming_args);
1440
  set_mem_align (src, PARM_BOUNDARY);
1441
  emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1442
 
1443
  /* Refer to the argument block.  */
1444
  apply_args_size ();
1445
  arguments = gen_rtx_MEM (BLKmode, arguments);
1446
  set_mem_align (arguments, PARM_BOUNDARY);
1447
 
1448
  /* Walk past the arg-pointer and structure value address.  */
1449
  size = GET_MODE_SIZE (Pmode);
1450
  if (struct_value)
1451
    size += GET_MODE_SIZE (Pmode);
1452
 
1453
  /* Restore each of the registers previously saved.  Make USE insns
1454
     for each of these registers for use in making the call.  */
1455
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1456
    if ((mode = apply_args_mode[regno]) != VOIDmode)
1457
      {
1458
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1459
        if (size % align != 0)
1460
          size = CEIL (size, align) * align;
1461
        reg = gen_rtx_REG (mode, regno);
1462
        emit_move_insn (reg, adjust_address (arguments, mode, size));
1463
        use_reg (&call_fusage, reg);
1464
        size += GET_MODE_SIZE (mode);
1465
      }
1466
 
1467
  /* Restore the structure value address unless this is passed as an
1468
     "invisible" first argument.  */
1469
  size = GET_MODE_SIZE (Pmode);
1470
  if (struct_value)
1471
    {
1472
      rtx value = gen_reg_rtx (Pmode);
1473
      emit_move_insn (value, adjust_address (arguments, Pmode, size));
1474
      emit_move_insn (struct_value, value);
1475
      if (REG_P (struct_value))
1476
        use_reg (&call_fusage, struct_value);
1477
      size += GET_MODE_SIZE (Pmode);
1478
    }
1479
 
1480
  /* All arguments and registers used for the call are set up by now!  */
1481
  function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1482
 
1483
  /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1484
     and we don't want to load it into a register as an optimization,
1485
     because prepare_call_address already did it if it should be done.  */
1486
  if (GET_CODE (function) != SYMBOL_REF)
1487
    function = memory_address (FUNCTION_MODE, function);
1488
 
1489
  /* Generate the actual call instruction and save the return value.  */
1490
#ifdef HAVE_untyped_call
1491
  if (HAVE_untyped_call)
1492
    emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1493
                                      result, result_vector (1, result)));
1494
  else
1495
#endif
1496
#ifdef HAVE_call_value
1497
  if (HAVE_call_value)
1498
    {
1499
      rtx valreg = 0;
1500
 
1501
      /* Locate the unique return register.  It is not possible to
1502
         express a call that sets more than one return register using
1503
         call_value; use untyped_call for that.  In fact, untyped_call
1504
         only needs to save the return registers in the given block.  */
1505
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1506
        if ((mode = apply_result_mode[regno]) != VOIDmode)
1507
          {
1508
            gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1509
 
1510
            valreg = gen_rtx_REG (mode, regno);
1511
          }
1512
 
1513
      emit_call_insn (GEN_CALL_VALUE (valreg,
1514
                                      gen_rtx_MEM (FUNCTION_MODE, function),
1515
                                      const0_rtx, NULL_RTX, const0_rtx));
1516
 
1517
      emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1518
    }
1519
  else
1520
#endif
1521
    gcc_unreachable ();
1522
 
1523
  /* Find the CALL insn we just emitted, and attach the register usage
1524
     information.  */
1525
  call_insn = last_call_insn ();
1526
  add_function_usage_to (call_insn, call_fusage);
1527
 
1528
  /* Restore the stack.  */
1529
#ifdef HAVE_save_stack_nonlocal
1530
  if (HAVE_save_stack_nonlocal)
1531
    emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1532
  else
1533
#endif
1534
    emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1535
 
1536
  OK_DEFER_POP;
1537
 
1538
  /* Return the address of the result block.  */
1539
  result = copy_addr_to_reg (XEXP (result, 0));
1540
  return convert_memory_address (ptr_mode, result);
1541
}
1542
 
1543
/* Perform an untyped return.  */
1544
 
1545
static void
1546
expand_builtin_return (rtx result)
1547
{
1548
  int size, align, regno;
1549
  enum machine_mode mode;
1550
  rtx reg;
1551
  rtx call_fusage = 0;
1552
 
1553
  result = convert_memory_address (Pmode, result);
1554
 
1555
  apply_result_size ();
1556
  result = gen_rtx_MEM (BLKmode, result);
1557
 
1558
#ifdef HAVE_untyped_return
1559
  if (HAVE_untyped_return)
1560
    {
1561
      emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1562
      emit_barrier ();
1563
      return;
1564
    }
1565
#endif
1566
 
1567
  /* Restore the return value and note that each value is used.  */
1568
  size = 0;
1569
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1570
    if ((mode = apply_result_mode[regno]) != VOIDmode)
1571
      {
1572
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1573
        if (size % align != 0)
1574
          size = CEIL (size, align) * align;
1575
        reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1576
        emit_move_insn (reg, adjust_address (result, mode, size));
1577
 
1578
        push_to_sequence (call_fusage);
1579
        emit_insn (gen_rtx_USE (VOIDmode, reg));
1580
        call_fusage = get_insns ();
1581
        end_sequence ();
1582
        size += GET_MODE_SIZE (mode);
1583
      }
1584
 
1585
  /* Put the USE insns before the return.  */
1586
  emit_insn (call_fusage);
1587
 
1588
  /* Return whatever values was restored by jumping directly to the end
1589
     of the function.  */
1590
  expand_naked_return ();
1591
}
1592
 
1593
/* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1594
 
1595
static enum type_class
1596
type_to_class (tree type)
1597
{
1598
  switch (TREE_CODE (type))
1599
    {
1600
    case VOID_TYPE:        return void_type_class;
1601
    case INTEGER_TYPE:     return integer_type_class;
1602
    case CHAR_TYPE:        return char_type_class;
1603
    case ENUMERAL_TYPE:    return enumeral_type_class;
1604
    case BOOLEAN_TYPE:     return boolean_type_class;
1605
    case POINTER_TYPE:     return pointer_type_class;
1606
    case REFERENCE_TYPE:   return reference_type_class;
1607
    case OFFSET_TYPE:      return offset_type_class;
1608
    case REAL_TYPE:        return real_type_class;
1609
    case COMPLEX_TYPE:     return complex_type_class;
1610
    case FUNCTION_TYPE:    return function_type_class;
1611
    case METHOD_TYPE:      return method_type_class;
1612
    case RECORD_TYPE:      return record_type_class;
1613
    case UNION_TYPE:
1614
    case QUAL_UNION_TYPE:  return union_type_class;
1615
    case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1616
                                   ? string_type_class : array_type_class);
1617
    case LANG_TYPE:        return lang_type_class;
1618
    default:               return no_type_class;
1619
    }
1620
}
1621
 
1622
/* Expand a call to __builtin_classify_type with arguments found in
1623
   ARGLIST.  */
1624
 
1625
static rtx
1626
expand_builtin_classify_type (tree arglist)
1627
{
1628
  if (arglist != 0)
1629
    return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1630
  return GEN_INT (no_type_class);
1631
}
1632
 
1633
/* This helper macro, meant to be used in mathfn_built_in below,
1634
   determines which among a set of three builtin math functions is
1635
   appropriate for a given type mode.  The `F' and `L' cases are
1636
   automatically generated from the `double' case.  */
1637
#define CASE_MATHFN(BUILT_IN_MATHFN) \
1638
  case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1639
  fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1640
  fcodel = BUILT_IN_MATHFN##L ; break;
1641
 
1642
/* Return mathematic function equivalent to FN but operating directly
1643
   on TYPE, if available.  If we can't do the conversion, return zero.  */
1644
tree
1645
mathfn_built_in (tree type, enum built_in_function fn)
1646
{
1647
  enum built_in_function fcode, fcodef, fcodel;
1648
 
1649
  switch (fn)
1650
    {
1651
      CASE_MATHFN (BUILT_IN_ACOS)
1652
      CASE_MATHFN (BUILT_IN_ACOSH)
1653
      CASE_MATHFN (BUILT_IN_ASIN)
1654
      CASE_MATHFN (BUILT_IN_ASINH)
1655
      CASE_MATHFN (BUILT_IN_ATAN)
1656
      CASE_MATHFN (BUILT_IN_ATAN2)
1657
      CASE_MATHFN (BUILT_IN_ATANH)
1658
      CASE_MATHFN (BUILT_IN_CBRT)
1659
      CASE_MATHFN (BUILT_IN_CEIL)
1660
      CASE_MATHFN (BUILT_IN_COPYSIGN)
1661
      CASE_MATHFN (BUILT_IN_COS)
1662
      CASE_MATHFN (BUILT_IN_COSH)
1663
      CASE_MATHFN (BUILT_IN_DREM)
1664
      CASE_MATHFN (BUILT_IN_ERF)
1665
      CASE_MATHFN (BUILT_IN_ERFC)
1666
      CASE_MATHFN (BUILT_IN_EXP)
1667
      CASE_MATHFN (BUILT_IN_EXP10)
1668
      CASE_MATHFN (BUILT_IN_EXP2)
1669
      CASE_MATHFN (BUILT_IN_EXPM1)
1670
      CASE_MATHFN (BUILT_IN_FABS)
1671
      CASE_MATHFN (BUILT_IN_FDIM)
1672
      CASE_MATHFN (BUILT_IN_FLOOR)
1673
      CASE_MATHFN (BUILT_IN_FMA)
1674
      CASE_MATHFN (BUILT_IN_FMAX)
1675
      CASE_MATHFN (BUILT_IN_FMIN)
1676
      CASE_MATHFN (BUILT_IN_FMOD)
1677
      CASE_MATHFN (BUILT_IN_FREXP)
1678
      CASE_MATHFN (BUILT_IN_GAMMA)
1679
      CASE_MATHFN (BUILT_IN_HUGE_VAL)
1680
      CASE_MATHFN (BUILT_IN_HYPOT)
1681
      CASE_MATHFN (BUILT_IN_ILOGB)
1682
      CASE_MATHFN (BUILT_IN_INF)
1683
      CASE_MATHFN (BUILT_IN_J0)
1684
      CASE_MATHFN (BUILT_IN_J1)
1685
      CASE_MATHFN (BUILT_IN_JN)
1686
      CASE_MATHFN (BUILT_IN_LCEIL)
1687
      CASE_MATHFN (BUILT_IN_LDEXP)
1688
      CASE_MATHFN (BUILT_IN_LFLOOR)
1689
      CASE_MATHFN (BUILT_IN_LGAMMA)
1690
      CASE_MATHFN (BUILT_IN_LLCEIL)
1691
      CASE_MATHFN (BUILT_IN_LLFLOOR)
1692
      CASE_MATHFN (BUILT_IN_LLRINT)
1693
      CASE_MATHFN (BUILT_IN_LLROUND)
1694
      CASE_MATHFN (BUILT_IN_LOG)
1695
      CASE_MATHFN (BUILT_IN_LOG10)
1696
      CASE_MATHFN (BUILT_IN_LOG1P)
1697
      CASE_MATHFN (BUILT_IN_LOG2)
1698
      CASE_MATHFN (BUILT_IN_LOGB)
1699
      CASE_MATHFN (BUILT_IN_LRINT)
1700
      CASE_MATHFN (BUILT_IN_LROUND)
1701
      CASE_MATHFN (BUILT_IN_MODF)
1702
      CASE_MATHFN (BUILT_IN_NAN)
1703
      CASE_MATHFN (BUILT_IN_NANS)
1704
      CASE_MATHFN (BUILT_IN_NEARBYINT)
1705
      CASE_MATHFN (BUILT_IN_NEXTAFTER)
1706
      CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1707
      CASE_MATHFN (BUILT_IN_POW)
1708
      CASE_MATHFN (BUILT_IN_POWI)
1709
      CASE_MATHFN (BUILT_IN_POW10)
1710
      CASE_MATHFN (BUILT_IN_REMAINDER)
1711
      CASE_MATHFN (BUILT_IN_REMQUO)
1712
      CASE_MATHFN (BUILT_IN_RINT)
1713
      CASE_MATHFN (BUILT_IN_ROUND)
1714
      CASE_MATHFN (BUILT_IN_SCALB)
1715
      CASE_MATHFN (BUILT_IN_SCALBLN)
1716
      CASE_MATHFN (BUILT_IN_SCALBN)
1717
      CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1718
      CASE_MATHFN (BUILT_IN_SIN)
1719
      CASE_MATHFN (BUILT_IN_SINCOS)
1720
      CASE_MATHFN (BUILT_IN_SINH)
1721
      CASE_MATHFN (BUILT_IN_SQRT)
1722
      CASE_MATHFN (BUILT_IN_TAN)
1723
      CASE_MATHFN (BUILT_IN_TANH)
1724
      CASE_MATHFN (BUILT_IN_TGAMMA)
1725
      CASE_MATHFN (BUILT_IN_TRUNC)
1726
      CASE_MATHFN (BUILT_IN_Y0)
1727
      CASE_MATHFN (BUILT_IN_Y1)
1728
      CASE_MATHFN (BUILT_IN_YN)
1729
 
1730
      default:
1731
        return 0;
1732
      }
1733
 
1734
  if (TYPE_MAIN_VARIANT (type) == double_type_node)
1735
    return implicit_built_in_decls[fcode];
1736
  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1737
    return implicit_built_in_decls[fcodef];
1738
  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1739
    return implicit_built_in_decls[fcodel];
1740
  else
1741
    return 0;
1742
}
1743
 
1744
/* If errno must be maintained, expand the RTL to check if the result,
1745
   TARGET, of a built-in function call, EXP, is NaN, and if so set
1746
   errno to EDOM.  */
1747
 
1748
static void
1749
expand_errno_check (tree exp, rtx target)
1750
{
1751
  rtx lab = gen_label_rtx ();
1752
 
1753
  /* Test the result; if it is NaN, set errno=EDOM because
1754
     the argument was not in the domain.  */
1755
  emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1756
                           0, lab);
1757
 
1758
#ifdef TARGET_EDOM
1759
  /* If this built-in doesn't throw an exception, set errno directly.  */
1760
  if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1761
    {
1762
#ifdef GEN_ERRNO_RTX
1763
      rtx errno_rtx = GEN_ERRNO_RTX;
1764
#else
1765
      rtx errno_rtx
1766
          = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1767
#endif
1768
      emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1769
      emit_label (lab);
1770
      return;
1771
    }
1772
#endif
1773
 
1774
  /* We can't set errno=EDOM directly; let the library call do it.
1775
     Pop the arguments right away in case the call gets deleted.  */
1776
  NO_DEFER_POP;
1777
  expand_call (exp, target, 0);
1778
  OK_DEFER_POP;
1779
  emit_label (lab);
1780
}
1781
 
1782
 
1783
/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1784
   Return 0 if a normal call should be emitted rather than expanding the
1785
   function in-line.  EXP is the expression that is a call to the builtin
1786
   function; if convenient, the result should be placed in TARGET.
1787
   SUBTARGET may be used as the target for computing one of EXP's operands.  */
1788
 
1789
static rtx
1790
expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1791
{
1792
  optab builtin_optab;
1793
  rtx op0, insns, before_call;
1794
  tree fndecl = get_callee_fndecl (exp);
1795
  tree arglist = TREE_OPERAND (exp, 1);
1796
  enum machine_mode mode;
1797
  bool errno_set = false;
1798
  tree arg, narg;
1799
 
1800
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1801
    return 0;
1802
 
1803
  arg = TREE_VALUE (arglist);
1804
 
1805
  switch (DECL_FUNCTION_CODE (fndecl))
1806
    {
1807
    case BUILT_IN_SQRT:
1808
    case BUILT_IN_SQRTF:
1809
    case BUILT_IN_SQRTL:
1810
      errno_set = ! tree_expr_nonnegative_p (arg);
1811
      builtin_optab = sqrt_optab;
1812
      break;
1813
    case BUILT_IN_EXP:
1814
    case BUILT_IN_EXPF:
1815
    case BUILT_IN_EXPL:
1816
      errno_set = true; builtin_optab = exp_optab; break;
1817
    case BUILT_IN_EXP10:
1818
    case BUILT_IN_EXP10F:
1819
    case BUILT_IN_EXP10L:
1820
    case BUILT_IN_POW10:
1821
    case BUILT_IN_POW10F:
1822
    case BUILT_IN_POW10L:
1823
      errno_set = true; builtin_optab = exp10_optab; break;
1824
    case BUILT_IN_EXP2:
1825
    case BUILT_IN_EXP2F:
1826
    case BUILT_IN_EXP2L:
1827
      errno_set = true; builtin_optab = exp2_optab; break;
1828
    case BUILT_IN_EXPM1:
1829
    case BUILT_IN_EXPM1F:
1830
    case BUILT_IN_EXPM1L:
1831
      errno_set = true; builtin_optab = expm1_optab; break;
1832
    case BUILT_IN_LOGB:
1833
    case BUILT_IN_LOGBF:
1834
    case BUILT_IN_LOGBL:
1835
      errno_set = true; builtin_optab = logb_optab; break;
1836
    case BUILT_IN_ILOGB:
1837
    case BUILT_IN_ILOGBF:
1838
    case BUILT_IN_ILOGBL:
1839
      errno_set = true; builtin_optab = ilogb_optab; break;
1840
    case BUILT_IN_LOG:
1841
    case BUILT_IN_LOGF:
1842
    case BUILT_IN_LOGL:
1843
      errno_set = true; builtin_optab = log_optab; break;
1844
    case BUILT_IN_LOG10:
1845
    case BUILT_IN_LOG10F:
1846
    case BUILT_IN_LOG10L:
1847
      errno_set = true; builtin_optab = log10_optab; break;
1848
    case BUILT_IN_LOG2:
1849
    case BUILT_IN_LOG2F:
1850
    case BUILT_IN_LOG2L:
1851
      errno_set = true; builtin_optab = log2_optab; break;
1852
    case BUILT_IN_LOG1P:
1853
    case BUILT_IN_LOG1PF:
1854
    case BUILT_IN_LOG1PL:
1855
      errno_set = true; builtin_optab = log1p_optab; break;
1856
    case BUILT_IN_ASIN:
1857
    case BUILT_IN_ASINF:
1858
    case BUILT_IN_ASINL:
1859
      builtin_optab = asin_optab; break;
1860
    case BUILT_IN_ACOS:
1861
    case BUILT_IN_ACOSF:
1862
    case BUILT_IN_ACOSL:
1863
      builtin_optab = acos_optab; break;
1864
    case BUILT_IN_TAN:
1865
    case BUILT_IN_TANF:
1866
    case BUILT_IN_TANL:
1867
      builtin_optab = tan_optab; break;
1868
    case BUILT_IN_ATAN:
1869
    case BUILT_IN_ATANF:
1870
    case BUILT_IN_ATANL:
1871
      builtin_optab = atan_optab; break;
1872
    case BUILT_IN_FLOOR:
1873
    case BUILT_IN_FLOORF:
1874
    case BUILT_IN_FLOORL:
1875
      builtin_optab = floor_optab; break;
1876
    case BUILT_IN_CEIL:
1877
    case BUILT_IN_CEILF:
1878
    case BUILT_IN_CEILL:
1879
      builtin_optab = ceil_optab; break;
1880
    case BUILT_IN_TRUNC:
1881
    case BUILT_IN_TRUNCF:
1882
    case BUILT_IN_TRUNCL:
1883
      builtin_optab = btrunc_optab; break;
1884
    case BUILT_IN_ROUND:
1885
    case BUILT_IN_ROUNDF:
1886
    case BUILT_IN_ROUNDL:
1887
      builtin_optab = round_optab; break;
1888
    case BUILT_IN_NEARBYINT:
1889
    case BUILT_IN_NEARBYINTF:
1890
    case BUILT_IN_NEARBYINTL:
1891
      builtin_optab = nearbyint_optab; break;
1892
    case BUILT_IN_RINT:
1893
    case BUILT_IN_RINTF:
1894
    case BUILT_IN_RINTL:
1895
      builtin_optab = rint_optab; break;
1896
    case BUILT_IN_LRINT:
1897
    case BUILT_IN_LRINTF:
1898
    case BUILT_IN_LRINTL:
1899
    case BUILT_IN_LLRINT:
1900
    case BUILT_IN_LLRINTF:
1901
    case BUILT_IN_LLRINTL:
1902
      builtin_optab = lrint_optab; break;
1903
    default:
1904
      gcc_unreachable ();
1905
    }
1906
 
1907
  /* Make a suitable register to place result in.  */
1908
  mode = TYPE_MODE (TREE_TYPE (exp));
1909
 
1910
  if (! flag_errno_math || ! HONOR_NANS (mode))
1911
    errno_set = false;
1912
 
1913
  /* Before working hard, check whether the instruction is available.  */
1914
  if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1915
    {
1916
      target = gen_reg_rtx (mode);
1917
 
1918
      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1919
         need to expand the argument again.  This way, we will not perform
1920
         side-effects more the once.  */
1921
      narg = builtin_save_expr (arg);
1922
      if (narg != arg)
1923
        {
1924
          arg = narg;
1925
          arglist = build_tree_list (NULL_TREE, arg);
1926
          exp = build_function_call_expr (fndecl, arglist);
1927
        }
1928
 
1929
      op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1930
 
1931
      start_sequence ();
1932
 
1933
      /* Compute into TARGET.
1934
         Set TARGET to wherever the result comes back.  */
1935
      target = expand_unop (mode, builtin_optab, op0, target, 0);
1936
 
1937
      if (target != 0)
1938
        {
1939
          if (errno_set)
1940
            expand_errno_check (exp, target);
1941
 
1942
          /* Output the entire sequence.  */
1943
          insns = get_insns ();
1944
          end_sequence ();
1945
          emit_insn (insns);
1946
          return target;
1947
        }
1948
 
1949
      /* If we were unable to expand via the builtin, stop the sequence
1950
         (without outputting the insns) and call to the library function
1951
         with the stabilized argument list.  */
1952
      end_sequence ();
1953
    }
1954
 
1955
  before_call = get_last_insn ();
1956
 
1957
  target = expand_call (exp, target, target == const0_rtx);
1958
 
1959
  /* If this is a sqrt operation and we don't care about errno, try to
1960
     attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1961
     This allows the semantics of the libcall to be visible to the RTL
1962
     optimizers.  */
1963
  if (builtin_optab == sqrt_optab && !errno_set)
1964
    {
1965
      /* Search backwards through the insns emitted by expand_call looking
1966
         for the instruction with the REG_RETVAL note.  */
1967
      rtx last = get_last_insn ();
1968
      while (last != before_call)
1969
        {
1970
          if (find_reg_note (last, REG_RETVAL, NULL))
1971
            {
1972
              rtx note = find_reg_note (last, REG_EQUAL, NULL);
1973
              /* Check that the REQ_EQUAL note is an EXPR_LIST with
1974
                 two elements, i.e. symbol_ref(sqrt) and the operand.  */
1975
              if (note
1976
                  && GET_CODE (note) == EXPR_LIST
1977
                  && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1978
                  && XEXP (XEXP (note, 0), 1) != NULL_RTX
1979
                  && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1980
                {
1981
                  rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1982
                  /* Check operand is a register with expected mode.  */
1983
                  if (operand
1984
                      && REG_P (operand)
1985
                      && GET_MODE (operand) == mode)
1986
                    {
1987
                      /* Replace the REG_EQUAL note with a SQRT rtx.  */
1988
                      rtx equiv = gen_rtx_SQRT (mode, operand);
1989
                      set_unique_reg_note (last, REG_EQUAL, equiv);
1990
                    }
1991
                }
1992
              break;
1993
            }
1994
          last = PREV_INSN (last);
1995
        }
1996
    }
1997
 
1998
  return target;
1999
}
2000
 
2001
/* Expand a call to the builtin binary math functions (pow and atan2).
2002
   Return 0 if a normal call should be emitted rather than expanding the
2003
   function in-line.  EXP is the expression that is a call to the builtin
2004
   function; if convenient, the result should be placed in TARGET.
2005
   SUBTARGET may be used as the target for computing one of EXP's
2006
   operands.  */
2007
 
2008
static rtx
2009
expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2010
{
2011
  optab builtin_optab;
2012
  rtx op0, op1, insns;
2013
  int op1_type = REAL_TYPE;
2014
  tree fndecl = get_callee_fndecl (exp);
2015
  tree arglist = TREE_OPERAND (exp, 1);
2016
  tree arg0, arg1, temp, narg;
2017
  enum machine_mode mode;
2018
  bool errno_set = true;
2019
  bool stable = true;
2020
 
2021
  if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
2022
      || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2023
      || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2024
    op1_type = INTEGER_TYPE;
2025
 
2026
  if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2027
    return 0;
2028
 
2029
  arg0 = TREE_VALUE (arglist);
2030
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2031
 
2032
  switch (DECL_FUNCTION_CODE (fndecl))
2033
    {
2034
    case BUILT_IN_POW:
2035
    case BUILT_IN_POWF:
2036
    case BUILT_IN_POWL:
2037
      builtin_optab = pow_optab; break;
2038
    case BUILT_IN_ATAN2:
2039
    case BUILT_IN_ATAN2F:
2040
    case BUILT_IN_ATAN2L:
2041
      builtin_optab = atan2_optab; break;
2042
    case BUILT_IN_LDEXP:
2043
    case BUILT_IN_LDEXPF:
2044
    case BUILT_IN_LDEXPL:
2045
      builtin_optab = ldexp_optab; break;
2046
    case BUILT_IN_FMOD:
2047
    case BUILT_IN_FMODF:
2048
    case BUILT_IN_FMODL:
2049
      builtin_optab = fmod_optab; break;
2050
    case BUILT_IN_DREM:
2051
    case BUILT_IN_DREMF:
2052
    case BUILT_IN_DREML:
2053
      builtin_optab = drem_optab; break;
2054
    default:
2055
      gcc_unreachable ();
2056
    }
2057
 
2058
  /* Make a suitable register to place result in.  */
2059
  mode = TYPE_MODE (TREE_TYPE (exp));
2060
 
2061
  /* Before working hard, check whether the instruction is available.  */
2062
  if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2063
    return 0;
2064
 
2065
  target = gen_reg_rtx (mode);
2066
 
2067
  if (! flag_errno_math || ! HONOR_NANS (mode))
2068
    errno_set = false;
2069
 
2070
  /* Always stabilize the argument list.  */
2071
  narg = builtin_save_expr (arg1);
2072
  if (narg != arg1)
2073
    {
2074
      arg1 = narg;
2075
      temp = build_tree_list (NULL_TREE, narg);
2076
      stable = false;
2077
    }
2078
  else
2079
    temp = TREE_CHAIN (arglist);
2080
 
2081
  narg = builtin_save_expr (arg0);
2082
  if (narg != arg0)
2083
    {
2084
      arg0 = narg;
2085
      arglist = tree_cons (NULL_TREE, narg, temp);
2086
      stable = false;
2087
    }
2088
  else if (! stable)
2089
    arglist = tree_cons (NULL_TREE, arg0, temp);
2090
 
2091
  if (! stable)
2092
    exp = build_function_call_expr (fndecl, arglist);
2093
 
2094
  op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2095
  op1 = expand_expr (arg1, 0, VOIDmode, 0);
2096
 
2097
  start_sequence ();
2098
 
2099
  /* Compute into TARGET.
2100
     Set TARGET to wherever the result comes back.  */
2101
  target = expand_binop (mode, builtin_optab, op0, op1,
2102
                         target, 0, OPTAB_DIRECT);
2103
 
2104
  /* If we were unable to expand via the builtin, stop the sequence
2105
     (without outputting the insns) and call to the library function
2106
     with the stabilized argument list.  */
2107
  if (target == 0)
2108
    {
2109
      end_sequence ();
2110
      return expand_call (exp, target, target == const0_rtx);
2111
    }
2112
 
2113
  if (errno_set)
2114
    expand_errno_check (exp, target);
2115
 
2116
  /* Output the entire sequence.  */
2117
  insns = get_insns ();
2118
  end_sequence ();
2119
  emit_insn (insns);
2120
 
2121
  return target;
2122
}
2123
 
2124
/* Expand a call to the builtin sin and cos math functions.
2125
   Return 0 if a normal call should be emitted rather than expanding the
2126
   function in-line.  EXP is the expression that is a call to the builtin
2127
   function; if convenient, the result should be placed in TARGET.
2128
   SUBTARGET may be used as the target for computing one of EXP's
2129
   operands.  */
2130
 
2131
static rtx
2132
expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2133
{
2134
  optab builtin_optab;
2135
  rtx op0, insns;
2136
  tree fndecl = get_callee_fndecl (exp);
2137
  tree arglist = TREE_OPERAND (exp, 1);
2138
  enum machine_mode mode;
2139
  bool errno_set = false;
2140
  tree arg, narg;
2141
 
2142
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2143
    return 0;
2144
 
2145
  arg = TREE_VALUE (arglist);
2146
 
2147
  switch (DECL_FUNCTION_CODE (fndecl))
2148
    {
2149
    case BUILT_IN_SIN:
2150
    case BUILT_IN_SINF:
2151
    case BUILT_IN_SINL:
2152
    case BUILT_IN_COS:
2153
    case BUILT_IN_COSF:
2154
    case BUILT_IN_COSL:
2155
      builtin_optab = sincos_optab; break;
2156
    default:
2157
      gcc_unreachable ();
2158
    }
2159
 
2160
  /* Make a suitable register to place result in.  */
2161
  mode = TYPE_MODE (TREE_TYPE (exp));
2162
 
2163
  if (! flag_errno_math || ! HONOR_NANS (mode))
2164
    errno_set = false;
2165
 
2166
  /* Check if sincos insn is available, otherwise fallback
2167
     to sin or cos insn.  */
2168
  if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2169
    switch (DECL_FUNCTION_CODE (fndecl))
2170
      {
2171
      case BUILT_IN_SIN:
2172
      case BUILT_IN_SINF:
2173
      case BUILT_IN_SINL:
2174
        builtin_optab = sin_optab; break;
2175
      case BUILT_IN_COS:
2176
      case BUILT_IN_COSF:
2177
      case BUILT_IN_COSL:
2178
        builtin_optab = cos_optab; break;
2179
      default:
2180
        gcc_unreachable ();
2181
      }
2182
  }
2183
 
2184
  /* Before working hard, check whether the instruction is available.  */
2185
  if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2186
    {
2187
      target = gen_reg_rtx (mode);
2188
 
2189
      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2190
         need to expand the argument again.  This way, we will not perform
2191
         side-effects more the once.  */
2192
      narg = save_expr (arg);
2193
      if (narg != arg)
2194
        {
2195
          arg = narg;
2196
          arglist = build_tree_list (NULL_TREE, arg);
2197
          exp = build_function_call_expr (fndecl, arglist);
2198
        }
2199
 
2200
      op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2201
 
2202
      start_sequence ();
2203
 
2204
      /* Compute into TARGET.
2205
         Set TARGET to wherever the result comes back.  */
2206
      if (builtin_optab == sincos_optab)
2207
        {
2208
          int result;
2209
 
2210
          switch (DECL_FUNCTION_CODE (fndecl))
2211
            {
2212
            case BUILT_IN_SIN:
2213
            case BUILT_IN_SINF:
2214
            case BUILT_IN_SINL:
2215
              result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2216
              break;
2217
            case BUILT_IN_COS:
2218
            case BUILT_IN_COSF:
2219
            case BUILT_IN_COSL:
2220
              result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2221
              break;
2222
            default:
2223
              gcc_unreachable ();
2224
            }
2225
          gcc_assert (result);
2226
        }
2227
      else
2228
        {
2229
          target = expand_unop (mode, builtin_optab, op0, target, 0);
2230
        }
2231
 
2232
      if (target != 0)
2233
        {
2234
          if (errno_set)
2235
            expand_errno_check (exp, target);
2236
 
2237
          /* Output the entire sequence.  */
2238
          insns = get_insns ();
2239
          end_sequence ();
2240
          emit_insn (insns);
2241
          return target;
2242
        }
2243
 
2244
      /* If we were unable to expand via the builtin, stop the sequence
2245
         (without outputting the insns) and call to the library function
2246
         with the stabilized argument list.  */
2247
      end_sequence ();
2248
    }
2249
 
2250
  target = expand_call (exp, target, target == const0_rtx);
2251
 
2252
  return target;
2253
}
2254
 
2255
/* Expand a call to one of the builtin rounding functions (lfloor).
2256
   If expanding via optab fails, lower expression to (int)(floor(x)).
2257
   EXP is the expression that is a call to the builtin function;
2258
   if convenient, the result should be placed in TARGET.  SUBTARGET may
2259
   be used as the target for computing one of EXP's operands.  */
2260
 
2261
static rtx
2262
expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2263
{
2264
  optab builtin_optab;
2265
  rtx op0, insns, tmp;
2266
  tree fndecl = get_callee_fndecl (exp);
2267
  tree arglist = TREE_OPERAND (exp, 1);
2268
  enum built_in_function fallback_fn;
2269
  tree fallback_fndecl;
2270
  enum machine_mode mode;
2271
  tree arg, narg;
2272
 
2273
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2274
    gcc_unreachable ();
2275
 
2276
  arg = TREE_VALUE (arglist);
2277
 
2278
  switch (DECL_FUNCTION_CODE (fndecl))
2279
    {
2280
    case BUILT_IN_LCEIL:
2281
    case BUILT_IN_LCEILF:
2282
    case BUILT_IN_LCEILL:
2283
    case BUILT_IN_LLCEIL:
2284
    case BUILT_IN_LLCEILF:
2285
    case BUILT_IN_LLCEILL:
2286
      builtin_optab = lceil_optab;
2287
      fallback_fn = BUILT_IN_CEIL;
2288
      break;
2289
 
2290
    case BUILT_IN_LFLOOR:
2291
    case BUILT_IN_LFLOORF:
2292
    case BUILT_IN_LFLOORL:
2293
    case BUILT_IN_LLFLOOR:
2294
    case BUILT_IN_LLFLOORF:
2295
    case BUILT_IN_LLFLOORL:
2296
      builtin_optab = lfloor_optab;
2297
      fallback_fn = BUILT_IN_FLOOR;
2298
      break;
2299
 
2300
    default:
2301
      gcc_unreachable ();
2302
    }
2303
 
2304
  /* Make a suitable register to place result in.  */
2305
  mode = TYPE_MODE (TREE_TYPE (exp));
2306
 
2307
  /* Before working hard, check whether the instruction is available.  */
2308
  if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2309
    {
2310
      target = gen_reg_rtx (mode);
2311
 
2312
      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2313
         need to expand the argument again.  This way, we will not perform
2314
         side-effects more the once.  */
2315
      narg = builtin_save_expr (arg);
2316
      if (narg != arg)
2317
        {
2318
          arg = narg;
2319
          arglist = build_tree_list (NULL_TREE, arg);
2320
          exp = build_function_call_expr (fndecl, arglist);
2321
        }
2322
 
2323
      op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2324
 
2325
      start_sequence ();
2326
 
2327
      /* Compute into TARGET.
2328
         Set TARGET to wherever the result comes back.  */
2329
      target = expand_unop (mode, builtin_optab, op0, target, 0);
2330
 
2331
      if (target != 0)
2332
        {
2333
          /* Output the entire sequence.  */
2334
          insns = get_insns ();
2335
          end_sequence ();
2336
          emit_insn (insns);
2337
          return target;
2338
        }
2339
 
2340
      /* If we were unable to expand via the builtin, stop the sequence
2341
         (without outputting the insns).  */
2342
      end_sequence ();
2343
    }
2344
 
2345
  /* Fall back to floating point rounding optab.  */
2346
  fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2347
  /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2348
     ??? Perhaps convert (int)floorf(x) into (int)floor((double)x).  */
2349
  gcc_assert (fallback_fndecl != NULL_TREE);
2350
  exp = build_function_call_expr (fallback_fndecl, arglist);
2351
 
2352
  tmp = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2353
 
2354
  /* Truncate the result of floating point optab to integer
2355
     via expand_fix ().  */
2356
  target = gen_reg_rtx (mode);
2357
  expand_fix (target, tmp, 0);
2358
 
2359
  return target;
2360
}
2361
 
2362
/* To evaluate powi(x,n), the floating point value x raised to the
2363
   constant integer exponent n, we use a hybrid algorithm that
2364
   combines the "window method" with look-up tables.  For an
2365
   introduction to exponentiation algorithms and "addition chains",
2366
   see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2367
   "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2368
   3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2369
   Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2370
 
2371
/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2372
   multiplications to inline before calling the system library's pow
2373
   function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2374
   so this default never requires calling pow, powf or powl.  */
2375
 
2376
#ifndef POWI_MAX_MULTS
2377
#define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2378
#endif
2379
 
2380
/* The size of the "optimal power tree" lookup table.  All
2381
   exponents less than this value are simply looked up in the
2382
   powi_table below.  This threshold is also used to size the
2383
   cache of pseudo registers that hold intermediate results.  */
2384
#define POWI_TABLE_SIZE 256
2385
 
2386
/* The size, in bits of the window, used in the "window method"
2387
   exponentiation algorithm.  This is equivalent to a radix of
2388
   (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2389
#define POWI_WINDOW_SIZE 3
2390
 
2391
/* The following table is an efficient representation of an
2392
   "optimal power tree".  For each value, i, the corresponding
2393
   value, j, in the table states than an optimal evaluation
2394
   sequence for calculating pow(x,i) can be found by evaluating
2395
   pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2396
   100 integers is given in Knuth's "Seminumerical algorithms".  */
2397
 
2398
static const unsigned char powi_table[POWI_TABLE_SIZE] =
2399
  {
2400
      0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2401
      4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2402
      8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2403
     12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2404
     16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2405
     20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2406
     24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2407
     28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2408
     32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2409
     36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2410
     40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2411
     44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2412
     48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2413
     52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2414
     56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2415
     60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2416
     64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2417
     68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2418
     72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2419
     76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2420
     80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2421
     84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2422
     88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2423
     92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2424
     96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2425
    100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2426
    104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2427
    108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2428
    112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2429
    116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2430
    120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2431
    124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2432
  };
2433
 
2434
 
2435
/* Return the number of multiplications required to calculate
2436
   powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2437
   subroutine of powi_cost.  CACHE is an array indicating
2438
   which exponents have already been calculated.  */
2439
 
2440
static int
2441
powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2442
{
2443
  /* If we've already calculated this exponent, then this evaluation
2444
     doesn't require any additional multiplications.  */
2445
  if (cache[n])
2446
    return 0;
2447
 
2448
  cache[n] = true;
2449
  return powi_lookup_cost (n - powi_table[n], cache)
2450
         + powi_lookup_cost (powi_table[n], cache) + 1;
2451
}
2452
 
2453
/* Return the number of multiplications required to calculate
2454
   powi(x,n) for an arbitrary x, given the exponent N.  This
2455
   function needs to be kept in sync with expand_powi below.  */
2456
 
2457
static int
2458
powi_cost (HOST_WIDE_INT n)
2459
{
2460
  bool cache[POWI_TABLE_SIZE];
2461
  unsigned HOST_WIDE_INT digit;
2462
  unsigned HOST_WIDE_INT val;
2463
  int result;
2464
 
2465
  if (n == 0)
2466
    return 0;
2467
 
2468
  /* Ignore the reciprocal when calculating the cost.  */
2469
  val = (n < 0) ? -n : n;
2470
 
2471
  /* Initialize the exponent cache.  */
2472
  memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2473
  cache[1] = true;
2474
 
2475
  result = 0;
2476
 
2477
  while (val >= POWI_TABLE_SIZE)
2478
    {
2479
      if (val & 1)
2480
        {
2481
          digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2482
          result += powi_lookup_cost (digit, cache)
2483
                    + POWI_WINDOW_SIZE + 1;
2484
          val >>= POWI_WINDOW_SIZE;
2485
        }
2486
      else
2487
        {
2488
          val >>= 1;
2489
          result++;
2490
        }
2491
    }
2492
 
2493
  return result + powi_lookup_cost (val, cache);
2494
}
2495
 
2496
/* Recursive subroutine of expand_powi.  This function takes the array,
2497
   CACHE, of already calculated exponents and an exponent N and returns
2498
   an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2499
 
2500
static rtx
2501
expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2502
{
2503
  unsigned HOST_WIDE_INT digit;
2504
  rtx target, result;
2505
  rtx op0, op1;
2506
 
2507
  if (n < POWI_TABLE_SIZE)
2508
    {
2509
      if (cache[n])
2510
        return cache[n];
2511
 
2512
      target = gen_reg_rtx (mode);
2513
      cache[n] = target;
2514
 
2515
      op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2516
      op1 = expand_powi_1 (mode, powi_table[n], cache);
2517
    }
2518
  else if (n & 1)
2519
    {
2520
      target = gen_reg_rtx (mode);
2521
      digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2522
      op0 = expand_powi_1 (mode, n - digit, cache);
2523
      op1 = expand_powi_1 (mode, digit, cache);
2524
    }
2525
  else
2526
    {
2527
      target = gen_reg_rtx (mode);
2528
      op0 = expand_powi_1 (mode, n >> 1, cache);
2529
      op1 = op0;
2530
    }
2531
 
2532
  result = expand_mult (mode, op0, op1, target, 0);
2533
  if (result != target)
2534
    emit_move_insn (target, result);
2535
  return target;
2536
}
2537
 
2538
/* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2539
   floating point operand in mode MODE, and N is the exponent.  This
2540
   function needs to be kept in sync with powi_cost above.  */
2541
 
2542
static rtx
2543
expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2544
{
2545
  unsigned HOST_WIDE_INT val;
2546
  rtx cache[POWI_TABLE_SIZE];
2547
  rtx result;
2548
 
2549
  if (n == 0)
2550
    return CONST1_RTX (mode);
2551
 
2552
  val = (n < 0) ? -n : n;
2553
 
2554
  memset (cache, 0, sizeof (cache));
2555
  cache[1] = x;
2556
 
2557
  result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2558
 
2559
  /* If the original exponent was negative, reciprocate the result.  */
2560
  if (n < 0)
2561
    result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2562
                           result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2563
 
2564
  return result;
2565
}
2566
 
2567
/* Expand a call to the pow built-in mathematical function.  Return 0 if
2568
   a normal call should be emitted rather than expanding the function
2569
   in-line.  EXP is the expression that is a call to the builtin
2570
   function; if convenient, the result should be placed in TARGET.  */
2571
 
2572
static rtx
2573
expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2574
{
2575
  tree arglist = TREE_OPERAND (exp, 1);
2576
  tree arg0, arg1;
2577
 
2578
  if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2579
    return 0;
2580
 
2581
  arg0 = TREE_VALUE (arglist);
2582
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2583
 
2584
  if (TREE_CODE (arg1) == REAL_CST
2585
      && ! TREE_CONSTANT_OVERFLOW (arg1))
2586
    {
2587
      REAL_VALUE_TYPE cint;
2588
      REAL_VALUE_TYPE c;
2589
      HOST_WIDE_INT n;
2590
 
2591
      c = TREE_REAL_CST (arg1);
2592
      n = real_to_integer (&c);
2593
      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2594
      if (real_identical (&c, &cint))
2595
        {
2596
          /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2597
             Otherwise, check the number of multiplications required.
2598
             Note that pow never sets errno for an integer exponent.  */
2599
          if ((n >= -1 && n <= 2)
2600
              || (flag_unsafe_math_optimizations
2601
                  && ! optimize_size
2602
                  && powi_cost (n) <= POWI_MAX_MULTS))
2603
            {
2604
              enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2605
              rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2606
              op = force_reg (mode, op);
2607
              return expand_powi (op, mode, n);
2608
            }
2609
        }
2610
    }
2611
 
2612
  if (! flag_unsafe_math_optimizations)
2613
    return NULL_RTX;
2614
  return expand_builtin_mathfn_2 (exp, target, subtarget);
2615
}
2616
 
2617
/* Expand a call to the powi built-in mathematical function.  Return 0 if
2618
   a normal call should be emitted rather than expanding the function
2619
   in-line.  EXP is the expression that is a call to the builtin
2620
   function; if convenient, the result should be placed in TARGET.  */
2621
 
2622
static rtx
2623
expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2624
{
2625
  tree arglist = TREE_OPERAND (exp, 1);
2626
  tree arg0, arg1;
2627
  rtx op0, op1;
2628
  enum machine_mode mode;
2629
  enum machine_mode mode2;
2630
 
2631
  if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2632
    return 0;
2633
 
2634
  arg0 = TREE_VALUE (arglist);
2635
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2636
  mode = TYPE_MODE (TREE_TYPE (exp));
2637
 
2638
  /* Handle constant power.  */
2639
 
2640
  if (TREE_CODE (arg1) == INTEGER_CST
2641
      && ! TREE_CONSTANT_OVERFLOW (arg1))
2642
    {
2643
      HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2644
 
2645
      /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2646
         Otherwise, check the number of multiplications required.  */
2647
      if ((TREE_INT_CST_HIGH (arg1) == 0
2648
           || TREE_INT_CST_HIGH (arg1) == -1)
2649
          && ((n >= -1 && n <= 2)
2650
              || (! optimize_size
2651
                  && powi_cost (n) <= POWI_MAX_MULTS)))
2652
        {
2653
          op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2654
          op0 = force_reg (mode, op0);
2655
          return expand_powi (op0, mode, n);
2656
        }
2657
    }
2658
 
2659
  /* Emit a libcall to libgcc.  */
2660
 
2661
  /* Mode of the 2nd argument must match that of an int. */
2662
  mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2663
 
2664
  if (target == NULL_RTX)
2665
    target = gen_reg_rtx (mode);
2666
 
2667
  op0 = expand_expr (arg0, subtarget, mode, 0);
2668
  if (GET_MODE (op0) != mode)
2669
    op0 = convert_to_mode (mode, op0, 0);
2670
  op1 = expand_expr (arg1, 0, mode2, 0);
2671
  if (GET_MODE (op1) != mode2)
2672
    op1 = convert_to_mode (mode2, op1, 0);
2673
 
2674
  target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2675
                                    target, LCT_CONST_MAKE_BLOCK, mode, 2,
2676
                                    op0, mode, op1, mode2);
2677
 
2678
  return target;
2679
}
2680
 
2681
/* Expand expression EXP which is a call to the strlen builtin.  Return 0
2682
   if we failed the caller should emit a normal call, otherwise
2683
   try to get the result in TARGET, if convenient.  */
2684
 
2685
static rtx
2686
expand_builtin_strlen (tree arglist, rtx target,
2687
                       enum machine_mode target_mode)
2688
{
2689
  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2690
    return 0;
2691
  else
2692
    {
2693
      rtx pat;
2694
      tree len, src = TREE_VALUE (arglist);
2695
      rtx result, src_reg, char_rtx, before_strlen;
2696
      enum machine_mode insn_mode = target_mode, char_mode;
2697
      enum insn_code icode = CODE_FOR_nothing;
2698
      int align;
2699
 
2700
      /* If the length can be computed at compile-time, return it.  */
2701
      len = c_strlen (src, 0);
2702
      if (len)
2703
        return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2704
 
2705
      /* If the length can be computed at compile-time and is constant
2706
         integer, but there are side-effects in src, evaluate
2707
         src for side-effects, then return len.
2708
         E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2709
         can be optimized into: i++; x = 3;  */
2710
      len = c_strlen (src, 1);
2711
      if (len && TREE_CODE (len) == INTEGER_CST)
2712
        {
2713
          expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2714
          return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2715
        }
2716
 
2717
      align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2718
 
2719
      /* If SRC is not a pointer type, don't do this operation inline.  */
2720
      if (align == 0)
2721
        return 0;
2722
 
2723
      /* Bail out if we can't compute strlen in the right mode.  */
2724
      while (insn_mode != VOIDmode)
2725
        {
2726
          icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2727
          if (icode != CODE_FOR_nothing)
2728
            break;
2729
 
2730
          insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2731
        }
2732
      if (insn_mode == VOIDmode)
2733
        return 0;
2734
 
2735
      /* Make a place to write the result of the instruction.  */
2736
      result = target;
2737
      if (! (result != 0
2738
             && REG_P (result)
2739
             && GET_MODE (result) == insn_mode
2740
             && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2741
        result = gen_reg_rtx (insn_mode);
2742
 
2743
      /* Make a place to hold the source address.  We will not expand
2744
         the actual source until we are sure that the expansion will
2745
         not fail -- there are trees that cannot be expanded twice.  */
2746
      src_reg = gen_reg_rtx (Pmode);
2747
 
2748
      /* Mark the beginning of the strlen sequence so we can emit the
2749
         source operand later.  */
2750
      before_strlen = get_last_insn ();
2751
 
2752
      char_rtx = const0_rtx;
2753
      char_mode = insn_data[(int) icode].operand[2].mode;
2754
      if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2755
                                                            char_mode))
2756
        char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2757
 
2758
      pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2759
                             char_rtx, GEN_INT (align));
2760
      if (! pat)
2761
        return 0;
2762
      emit_insn (pat);
2763
 
2764
      /* Now that we are assured of success, expand the source.  */
2765
      start_sequence ();
2766
      pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2767
      if (pat != src_reg)
2768
        emit_move_insn (src_reg, pat);
2769
      pat = get_insns ();
2770
      end_sequence ();
2771
 
2772
      if (before_strlen)
2773
        emit_insn_after (pat, before_strlen);
2774
      else
2775
        emit_insn_before (pat, get_insns ());
2776
 
2777
      /* Return the value in the proper mode for this function.  */
2778
      if (GET_MODE (result) == target_mode)
2779
        target = result;
2780
      else if (target != 0)
2781
        convert_move (target, result, 0);
2782
      else
2783
        target = convert_to_mode (target_mode, result, 0);
2784
 
2785
      return target;
2786
    }
2787
}
2788
 
2789
/* Expand a call to the strstr builtin.  Return 0 if we failed the
2790
   caller should emit a normal call, otherwise try to get the result
2791
   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2792
 
2793
static rtx
2794
expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2795
{
2796
  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2797
    {
2798
      tree result = fold_builtin_strstr (arglist, type);
2799
      if (result)
2800
        return expand_expr (result, target, mode, EXPAND_NORMAL);
2801
    }
2802
  return 0;
2803
}
2804
 
2805
/* Expand a call to the strchr builtin.  Return 0 if we failed the
2806
   caller should emit a normal call, otherwise try to get the result
2807
   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2808
 
2809
static rtx
2810
expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2811
{
2812
  if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2813
    {
2814
      tree result = fold_builtin_strchr (arglist, type);
2815
      if (result)
2816
        return expand_expr (result, target, mode, EXPAND_NORMAL);
2817
 
2818
      /* FIXME: Should use strchrM optab so that ports can optimize this.  */
2819
    }
2820
  return 0;
2821
}
2822
 
2823
/* Expand a call to the strrchr builtin.  Return 0 if we failed the
2824
   caller should emit a normal call, otherwise try to get the result
2825
   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2826
 
2827
static rtx
2828
expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2829
{
2830
  if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2831
    {
2832
      tree result = fold_builtin_strrchr (arglist, type);
2833
      if (result)
2834
        return expand_expr (result, target, mode, EXPAND_NORMAL);
2835
    }
2836
  return 0;
2837
}
2838
 
2839
/* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2840
   caller should emit a normal call, otherwise try to get the result
2841
   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2842
 
2843
static rtx
2844
expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2845
{
2846
  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2847
    {
2848
      tree result = fold_builtin_strpbrk (arglist, type);
2849
      if (result)
2850
        return expand_expr (result, target, mode, EXPAND_NORMAL);
2851
    }
2852
  return 0;
2853
}
2854
 
2855
/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2856
   bytes from constant string DATA + OFFSET and return it as target
2857
   constant.  */
2858
 
2859
static rtx
2860
builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2861
                         enum machine_mode mode)
2862
{
2863
  const char *str = (const char *) data;
2864
 
2865
  gcc_assert (offset >= 0
2866
              && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2867
                  <= strlen (str) + 1));
2868
 
2869
  return c_readstr (str + offset, mode);
2870
}
2871
 
2872
/* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2873
   Return 0 if we failed, the caller should emit a normal call,
2874
   otherwise try to get the result in TARGET, if convenient (and in
2875
   mode MODE if that's convenient).  */
2876
static rtx
2877
expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2878
{
2879
  tree fndecl = get_callee_fndecl (exp);
2880
  tree arglist = TREE_OPERAND (exp, 1);
2881
  if (!validate_arglist (arglist,
2882
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2883
    return 0;
2884
  else
2885
    {
2886
      tree dest = TREE_VALUE (arglist);
2887
      tree src = TREE_VALUE (TREE_CHAIN (arglist));
2888
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2889
      const char *src_str;
2890
      unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2891
      unsigned int dest_align
2892
        = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2893
      rtx dest_mem, src_mem, dest_addr, len_rtx;
2894
      tree result = fold_builtin_memcpy (fndecl, arglist);
2895
 
2896
      if (result)
2897
        return expand_expr (result, target, mode, EXPAND_NORMAL);
2898
 
2899
      /* If DEST is not a pointer type, call the normal function.  */
2900
      if (dest_align == 0)
2901
        return 0;
2902
 
2903
      /* If either SRC is not a pointer type, don't do this
2904
         operation in-line.  */
2905
      if (src_align == 0)
2906
        return 0;
2907
 
2908
      dest_mem = get_memory_rtx (dest, len);
2909
      set_mem_align (dest_mem, dest_align);
2910
      len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2911
      src_str = c_getstr (src);
2912
 
2913
      /* If SRC is a string constant and block move would be done
2914
         by pieces, we can avoid loading the string from memory
2915
         and only stored the computed constants.  */
2916
      if (src_str
2917
          && GET_CODE (len_rtx) == CONST_INT
2918
          && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2919
          && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2920
                                  (void *) src_str, dest_align))
2921
        {
2922
          dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2923
                                      builtin_memcpy_read_str,
2924
                                      (void *) src_str, dest_align, 0);
2925
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2926
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
2927
          return dest_mem;
2928
        }
2929
 
2930
      src_mem = get_memory_rtx (src, len);
2931
      set_mem_align (src_mem, src_align);
2932
 
2933
      /* Copy word part most expediently.  */
2934
      dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2935
                                   CALL_EXPR_TAILCALL (exp)
2936
                                   ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2937
 
2938
      if (dest_addr == 0)
2939
        {
2940
          dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2941
          dest_addr = convert_memory_address (ptr_mode, dest_addr);
2942
        }
2943
      return dest_addr;
2944
    }
2945
}
2946
 
2947
/* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2948
   Return 0 if we failed; the caller should emit a normal call,
2949
   otherwise try to get the result in TARGET, if convenient (and in
2950
   mode MODE if that's convenient).  If ENDP is 0 return the
2951
   destination pointer, if ENDP is 1 return the end pointer ala
2952
   mempcpy, and if ENDP is 2 return the end pointer minus one ala
2953
   stpcpy.  */
2954
 
2955
static rtx
2956
expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2957
                        int endp)
2958
{
2959
  if (!validate_arglist (arglist,
2960
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2961
    return 0;
2962
  /* If return value is ignored, transform mempcpy into memcpy.  */
2963
  else if (target == const0_rtx)
2964
    {
2965
      tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2966
 
2967
      if (!fn)
2968
        return 0;
2969
 
2970
      return expand_expr (build_function_call_expr (fn, arglist),
2971
                          target, mode, EXPAND_NORMAL);
2972
    }
2973
  else
2974
    {
2975
      tree dest = TREE_VALUE (arglist);
2976
      tree src = TREE_VALUE (TREE_CHAIN (arglist));
2977
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2978
      const char *src_str;
2979
      unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2980
      unsigned int dest_align
2981
        = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2982
      rtx dest_mem, src_mem, len_rtx;
2983
      tree result = fold_builtin_mempcpy (arglist, type, endp);
2984
 
2985
      if (result)
2986
        return expand_expr (result, target, mode, EXPAND_NORMAL);
2987
 
2988
      /* If either SRC or DEST is not a pointer type, don't do this
2989
         operation in-line.  */
2990
      if (dest_align == 0 || src_align == 0)
2991
        return 0;
2992
 
2993
      /* If LEN is not constant, call the normal function.  */
2994
      if (! host_integerp (len, 1))
2995
        return 0;
2996
 
2997
      len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2998
      src_str = c_getstr (src);
2999
 
3000
      /* If SRC is a string constant and block move would be done
3001
         by pieces, we can avoid loading the string from memory
3002
         and only stored the computed constants.  */
3003
      if (src_str
3004
          && GET_CODE (len_rtx) == CONST_INT
3005
          && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3006
          && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3007
                                  (void *) src_str, dest_align))
3008
        {
3009
          dest_mem = get_memory_rtx (dest, len);
3010
          set_mem_align (dest_mem, dest_align);
3011
          dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3012
                                      builtin_memcpy_read_str,
3013
                                      (void *) src_str, dest_align, endp);
3014
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3015
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3016
          return dest_mem;
3017
        }
3018
 
3019
      if (GET_CODE (len_rtx) == CONST_INT
3020
          && can_move_by_pieces (INTVAL (len_rtx),
3021
                                 MIN (dest_align, src_align)))
3022
        {
3023
          dest_mem = get_memory_rtx (dest, len);
3024
          set_mem_align (dest_mem, dest_align);
3025
          src_mem = get_memory_rtx (src, len);
3026
          set_mem_align (src_mem, src_align);
3027
          dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3028
                                     MIN (dest_align, src_align), endp);
3029
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3030
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3031
          return dest_mem;
3032
        }
3033
 
3034
      return 0;
3035
    }
3036
}
3037
 
3038
/* Expand expression EXP, which is a call to the memmove builtin.  Return 0
3039
   if we failed; the caller should emit a normal call.  */
3040
 
3041
static rtx
3042
expand_builtin_memmove (tree arglist, tree type, rtx target,
3043
                        enum machine_mode mode, tree orig_exp)
3044
{
3045
  if (!validate_arglist (arglist,
3046
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3047
    return 0;
3048
  else
3049
    {
3050
      tree dest = TREE_VALUE (arglist);
3051
      tree src = TREE_VALUE (TREE_CHAIN (arglist));
3052
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3053
 
3054
      unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3055
      unsigned int dest_align
3056
        = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3057
      tree result = fold_builtin_memmove (arglist, type);
3058
 
3059
      if (result)
3060
        return expand_expr (result, target, mode, EXPAND_NORMAL);
3061
 
3062
      /* If DEST is not a pointer type, call the normal function.  */
3063
      if (dest_align == 0)
3064
        return 0;
3065
 
3066
      /* If either SRC is not a pointer type, don't do this
3067
         operation in-line.  */
3068
      if (src_align == 0)
3069
        return 0;
3070
 
3071
      /* If src is categorized for a readonly section we can use
3072
         normal memcpy.  */
3073
      if (readonly_data_expr (src))
3074
        {
3075
          tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3076
          if (!fn)
3077
            return 0;
3078
          fn = build_function_call_expr (fn, arglist);
3079
          if (TREE_CODE (fn) == CALL_EXPR)
3080
            CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3081
          return expand_expr (fn, target, mode, EXPAND_NORMAL);
3082
        }
3083
 
3084
      /* If length is 1 and we can expand memcpy call inline,
3085
         it is ok to use memcpy as well.  */
3086
      if (integer_onep (len))
3087
        {
3088
          rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3089
                                            /*endp=*/0);
3090
          if (ret)
3091
            return ret;
3092
        }
3093
 
3094
      /* Otherwise, call the normal function.  */
3095
      return 0;
3096
   }
3097
}
3098
 
3099
/* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
3100
   if we failed the caller should emit a normal call.  */
3101
 
3102
static rtx
3103
expand_builtin_bcopy (tree exp)
3104
{
3105
  tree arglist = TREE_OPERAND (exp, 1);
3106
  tree type = TREE_TYPE (exp);
3107
  tree src, dest, size, newarglist;
3108
 
3109
  if (!validate_arglist (arglist,
3110
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3111
    return NULL_RTX;
3112
 
3113
  src = TREE_VALUE (arglist);
3114
  dest = TREE_VALUE (TREE_CHAIN (arglist));
3115
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3116
 
3117
  /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3118
     memmove(ptr y, ptr x, size_t z).   This is done this way
3119
     so that if it isn't expanded inline, we fallback to
3120
     calling bcopy instead of memmove.  */
3121
 
3122
  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3123
  newarglist = tree_cons (NULL_TREE, src, newarglist);
3124
  newarglist = tree_cons (NULL_TREE, dest, newarglist);
3125
 
3126
  return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3127
}
3128
 
3129
#ifndef HAVE_movstr
3130
# define HAVE_movstr 0
3131
# define CODE_FOR_movstr CODE_FOR_nothing
3132
#endif
3133
 
3134
/* Expand into a movstr instruction, if one is available.  Return 0 if
3135
   we failed, the caller should emit a normal call, otherwise try to
3136
   get the result in TARGET, if convenient.  If ENDP is 0 return the
3137
   destination pointer, if ENDP is 1 return the end pointer ala
3138
   mempcpy, and if ENDP is 2 return the end pointer minus one ala
3139
   stpcpy.  */
3140
 
3141
static rtx
3142
expand_movstr (tree dest, tree src, rtx target, int endp)
3143
{
3144
  rtx end;
3145
  rtx dest_mem;
3146
  rtx src_mem;
3147
  rtx insn;
3148
  const struct insn_data * data;
3149
 
3150
  if (!HAVE_movstr)
3151
    return 0;
3152
 
3153
  dest_mem = get_memory_rtx (dest, NULL);
3154
  src_mem = get_memory_rtx (src, NULL);
3155
  if (!endp)
3156
    {
3157
      target = force_reg (Pmode, XEXP (dest_mem, 0));
3158
      dest_mem = replace_equiv_address (dest_mem, target);
3159
      end = gen_reg_rtx (Pmode);
3160
    }
3161
  else
3162
    {
3163
      if (target == 0 || target == const0_rtx)
3164
        {
3165
          end = gen_reg_rtx (Pmode);
3166
          if (target == 0)
3167
            target = end;
3168
        }
3169
      else
3170
        end = target;
3171
    }
3172
 
3173
  data = insn_data + CODE_FOR_movstr;
3174
 
3175
  if (data->operand[0].mode != VOIDmode)
3176
    end = gen_lowpart (data->operand[0].mode, end);
3177
 
3178
  insn = data->genfun (end, dest_mem, src_mem);
3179
 
3180
  gcc_assert (insn);
3181
 
3182
  emit_insn (insn);
3183
 
3184
  /* movstr is supposed to set end to the address of the NUL
3185
     terminator.  If the caller requested a mempcpy-like return value,
3186
     adjust it.  */
3187
  if (endp == 1 && target != const0_rtx)
3188
    {
3189
      rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3190
      emit_move_insn (target, force_operand (tem, NULL_RTX));
3191
    }
3192
 
3193
  return target;
3194
}
3195
 
3196
/* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
3197
   if we failed the caller should emit a normal call, otherwise try to get
3198
   the result in TARGET, if convenient (and in mode MODE if that's
3199
   convenient).  */
3200
 
3201
static rtx
3202
expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3203
{
3204
  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3205
    {
3206
      tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3207
      if (result)
3208
        return expand_expr (result, target, mode, EXPAND_NORMAL);
3209
 
3210
      return expand_movstr (TREE_VALUE (arglist),
3211
                            TREE_VALUE (TREE_CHAIN (arglist)),
3212
                            target, /*endp=*/0);
3213
    }
3214
  return 0;
3215
}
3216
 
3217
/* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3218
   Return 0 if we failed the caller should emit a normal call,
3219
   otherwise try to get the result in TARGET, if convenient (and in
3220
   mode MODE if that's convenient).  */
3221
 
3222
static rtx
3223
expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3224
{
3225
  tree arglist = TREE_OPERAND (exp, 1);
3226
  /* If return value is ignored, transform stpcpy into strcpy.  */
3227
  if (target == const0_rtx)
3228
    {
3229
      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3230
      if (!fn)
3231
        return 0;
3232
 
3233
      return expand_expr (build_function_call_expr (fn, arglist),
3234
                          target, mode, EXPAND_NORMAL);
3235
    }
3236
 
3237
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3238
    return 0;
3239
  else
3240
    {
3241
      tree dst, src, len, lenp1;
3242
      tree narglist;
3243
      rtx ret;
3244
 
3245
      /* Ensure we get an actual string whose length can be evaluated at
3246
         compile-time, not an expression containing a string.  This is
3247
         because the latter will potentially produce pessimized code
3248
         when used to produce the return value.  */
3249
      src = TREE_VALUE (TREE_CHAIN (arglist));
3250
      if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3251
        return expand_movstr (TREE_VALUE (arglist),
3252
                              TREE_VALUE (TREE_CHAIN (arglist)),
3253
                              target, /*endp=*/2);
3254
 
3255
      dst = TREE_VALUE (arglist);
3256
      lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3257
      narglist = build_tree_list (NULL_TREE, lenp1);
3258
      narglist = tree_cons (NULL_TREE, src, narglist);
3259
      narglist = tree_cons (NULL_TREE, dst, narglist);
3260
      ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3261
                                    target, mode, /*endp=*/2);
3262
 
3263
      if (ret)
3264
        return ret;
3265
 
3266
      if (TREE_CODE (len) == INTEGER_CST)
3267
        {
3268
          rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3269
 
3270
          if (GET_CODE (len_rtx) == CONST_INT)
3271
            {
3272
              ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3273
                                           arglist, target, mode);
3274
 
3275
              if (ret)
3276
                {
3277
                  if (! target)
3278
                    {
3279
                      if (mode != VOIDmode)
3280
                        target = gen_reg_rtx (mode);
3281
                      else
3282
                        target = gen_reg_rtx (GET_MODE (ret));
3283
                    }
3284
                  if (GET_MODE (target) != GET_MODE (ret))
3285
                    ret = gen_lowpart (GET_MODE (target), ret);
3286
 
3287
                  ret = plus_constant (ret, INTVAL (len_rtx));
3288
                  ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3289
                  gcc_assert (ret);
3290
 
3291
                  return target;
3292
                }
3293
            }
3294
        }
3295
 
3296
      return expand_movstr (TREE_VALUE (arglist),
3297
                            TREE_VALUE (TREE_CHAIN (arglist)),
3298
                            target, /*endp=*/2);
3299
    }
3300
}
3301
 
3302
/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3303
   bytes from constant string DATA + OFFSET and return it as target
3304
   constant.  */
3305
 
3306
static rtx
3307
builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3308
                          enum machine_mode mode)
3309
{
3310
  const char *str = (const char *) data;
3311
 
3312
  if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3313
    return const0_rtx;
3314
 
3315
  return c_readstr (str + offset, mode);
3316
}
3317
 
3318
/* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
3319
   if we failed the caller should emit a normal call.  */
3320
 
3321
static rtx
3322
expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3323
{
3324
  tree fndecl = get_callee_fndecl (exp);
3325
  tree arglist = TREE_OPERAND (exp, 1);
3326
  if (validate_arglist (arglist,
3327
                        POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3328
    {
3329
      tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3330
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3331
      tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3332
 
3333
      if (result)
3334
        return expand_expr (result, target, mode, EXPAND_NORMAL);
3335
 
3336
      /* We must be passed a constant len and src parameter.  */
3337
      if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3338
        return 0;
3339
 
3340
      slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3341
 
3342
      /* We're required to pad with trailing zeros if the requested
3343
         len is greater than strlen(s2)+1.  In that case try to
3344
         use store_by_pieces, if it fails, punt.  */
3345
      if (tree_int_cst_lt (slen, len))
3346
        {
3347
          tree dest = TREE_VALUE (arglist);
3348
          unsigned int dest_align
3349
            = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3350
          const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3351
          rtx dest_mem;
3352
 
3353
          if (!p || dest_align == 0 || !host_integerp (len, 1)
3354
              || !can_store_by_pieces (tree_low_cst (len, 1),
3355
                                       builtin_strncpy_read_str,
3356
                                       (void *) p, dest_align))
3357
            return 0;
3358
 
3359
          dest_mem = get_memory_rtx (dest, len);
3360
          store_by_pieces (dest_mem, tree_low_cst (len, 1),
3361
                           builtin_strncpy_read_str,
3362
                           (void *) p, dest_align, 0);
3363
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3364
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3365
          return dest_mem;
3366
        }
3367
    }
3368
  return 0;
3369
}
3370
 
3371
/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3372
   bytes from constant string DATA + OFFSET and return it as target
3373
   constant.  */
3374
 
3375
static rtx
3376
builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3377
                         enum machine_mode mode)
3378
{
3379
  const char *c = (const char *) data;
3380
  char *p = alloca (GET_MODE_SIZE (mode));
3381
 
3382
  memset (p, *c, GET_MODE_SIZE (mode));
3383
 
3384
  return c_readstr (p, mode);
3385
}
3386
 
3387
/* Callback routine for store_by_pieces.  Return the RTL of a register
3388
   containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3389
   char value given in the RTL register data.  For example, if mode is
3390
   4 bytes wide, return the RTL for 0x01010101*data.  */
3391
 
3392
static rtx
3393
builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3394
                        enum machine_mode mode)
3395
{
3396
  rtx target, coeff;
3397
  size_t size;
3398
  char *p;
3399
 
3400
  size = GET_MODE_SIZE (mode);
3401
  if (size == 1)
3402
    return (rtx) data;
3403
 
3404
  p = alloca (size);
3405
  memset (p, 1, size);
3406
  coeff = c_readstr (p, mode);
3407
 
3408
  target = convert_to_mode (mode, (rtx) data, 1);
3409
  target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3410
  return force_reg (mode, target);
3411
}
3412
 
3413
/* Expand expression EXP, which is a call to the memset builtin.  Return 0
3414
   if we failed the caller should emit a normal call, otherwise try to get
3415
   the result in TARGET, if convenient (and in mode MODE if that's
3416
   convenient).  */
3417
 
3418
static rtx
3419
expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3420
                       tree orig_exp)
3421
{
3422
  if (!validate_arglist (arglist,
3423
                         POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3424
    return 0;
3425
  else
3426
    {
3427
      tree dest = TREE_VALUE (arglist);
3428
      tree val = TREE_VALUE (TREE_CHAIN (arglist));
3429
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3430
      tree fndecl, fn;
3431
      enum built_in_function fcode;
3432
      char c;
3433
      unsigned int dest_align;
3434
      rtx dest_mem, dest_addr, len_rtx;
3435
 
3436
      dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3437
 
3438
      /* If DEST is not a pointer type, don't do this
3439
         operation in-line.  */
3440
      if (dest_align == 0)
3441
        return 0;
3442
 
3443
      /* If the LEN parameter is zero, return DEST.  */
3444
      if (integer_zerop (len))
3445
        {
3446
          /* Evaluate and ignore VAL in case it has side-effects.  */
3447
          expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3448
          return expand_expr (dest, target, mode, EXPAND_NORMAL);
3449
        }
3450
 
3451
      /* Stabilize the arguments in case we fail.  */
3452
      dest = builtin_save_expr (dest);
3453
      val = builtin_save_expr (val);
3454
      len = builtin_save_expr (len);
3455
 
3456
      len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3457
      dest_mem = get_memory_rtx (dest, len);
3458
 
3459
      if (TREE_CODE (val) != INTEGER_CST)
3460
        {
3461
          rtx val_rtx;
3462
 
3463
          val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3464
          val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3465
                                     val_rtx, 0);
3466
 
3467
          /* Assume that we can memset by pieces if we can store the
3468
           * the coefficients by pieces (in the required modes).
3469
           * We can't pass builtin_memset_gen_str as that emits RTL.  */
3470
          c = 1;
3471
          if (host_integerp (len, 1)
3472
              && !(optimize_size && tree_low_cst (len, 1) > 1)
3473
              && can_store_by_pieces (tree_low_cst (len, 1),
3474
                                      builtin_memset_read_str, &c, dest_align))
3475
            {
3476
              val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3477
                                   val_rtx);
3478
              store_by_pieces (dest_mem, tree_low_cst (len, 1),
3479
                               builtin_memset_gen_str, val_rtx, dest_align, 0);
3480
            }
3481
          else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3482
                                            dest_align))
3483
            goto do_libcall;
3484
 
3485
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3486
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3487
          return dest_mem;
3488
        }
3489
 
3490
      if (target_char_cast (val, &c))
3491
        goto do_libcall;
3492
 
3493
      if (c)
3494
        {
3495
          if (host_integerp (len, 1)
3496
              && !(optimize_size && tree_low_cst (len, 1) > 1)
3497
              && can_store_by_pieces (tree_low_cst (len, 1),
3498
                                      builtin_memset_read_str, &c, dest_align))
3499
            store_by_pieces (dest_mem, tree_low_cst (len, 1),
3500
                             builtin_memset_read_str, &c, dest_align, 0);
3501
          else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3502
                                            dest_align))
3503
            goto do_libcall;
3504
 
3505
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3506
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3507
          return dest_mem;
3508
        }
3509
 
3510
      set_mem_align (dest_mem, dest_align);
3511
      dest_addr = clear_storage (dest_mem, len_rtx,
3512
                                 CALL_EXPR_TAILCALL (orig_exp)
3513
                                 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3514
 
3515
      if (dest_addr == 0)
3516
        {
3517
          dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3518
          dest_addr = convert_memory_address (ptr_mode, dest_addr);
3519
        }
3520
 
3521
      return dest_addr;
3522
 
3523
    do_libcall:
3524
      fndecl = get_callee_fndecl (orig_exp);
3525
      fcode = DECL_FUNCTION_CODE (fndecl);
3526
      gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3527
      arglist = build_tree_list (NULL_TREE, len);
3528
      if (fcode == BUILT_IN_MEMSET)
3529
        arglist = tree_cons (NULL_TREE, val, arglist);
3530
      arglist = tree_cons (NULL_TREE, dest, arglist);
3531
      fn = build_function_call_expr (fndecl, arglist);
3532
      if (TREE_CODE (fn) == CALL_EXPR)
3533
        CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3534
      return expand_call (fn, target, target == const0_rtx);
3535
    }
3536
}
3537
 
3538
/* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3539
   if we failed the caller should emit a normal call.  */
3540
 
3541
static rtx
3542
expand_builtin_bzero (tree exp)
3543
{
3544
  tree arglist = TREE_OPERAND (exp, 1);
3545
  tree dest, size, newarglist;
3546
 
3547
  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3548
    return NULL_RTX;
3549
 
3550
  dest = TREE_VALUE (arglist);
3551
  size = TREE_VALUE (TREE_CHAIN (arglist));
3552
 
3553
  /* New argument list transforming bzero(ptr x, int y) to
3554
     memset(ptr x, int 0, size_t y).   This is done this way
3555
     so that if it isn't expanded inline, we fallback to
3556
     calling bzero instead of memset.  */
3557
 
3558
  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3559
  newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3560
  newarglist = tree_cons (NULL_TREE, dest, newarglist);
3561
 
3562
  return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3563
}
3564
 
3565
/* Expand expression EXP, which is a call to the memcmp built-in function.
3566
   ARGLIST is the argument list for this call.  Return 0 if we failed and the
3567
   caller should emit a normal call, otherwise try to get the result in
3568
   TARGET, if convenient (and in mode MODE, if that's convenient).  */
3569
 
3570
static rtx
3571
expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3572
                       enum machine_mode mode)
3573
{
3574
  if (!validate_arglist (arglist,
3575
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3576
    return 0;
3577
  else
3578
    {
3579
      tree result = fold_builtin_memcmp (arglist);
3580
      if (result)
3581
        return expand_expr (result, target, mode, EXPAND_NORMAL);
3582
    }
3583
 
3584
#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3585
  {
3586
    tree arg1 = TREE_VALUE (arglist);
3587
    tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3588
    tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3589
    rtx arg1_rtx, arg2_rtx, arg3_rtx;
3590
    rtx result;
3591
    rtx insn;
3592
 
3593
    int arg1_align
3594
      = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3595
    int arg2_align
3596
      = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3597
    enum machine_mode insn_mode;
3598
 
3599
#ifdef HAVE_cmpmemsi
3600
    if (HAVE_cmpmemsi)
3601
      insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3602
    else
3603
#endif
3604
#ifdef HAVE_cmpstrnsi
3605
    if (HAVE_cmpstrnsi)
3606
      insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3607
    else
3608
#endif
3609
      return 0;
3610
 
3611
    /* If we don't have POINTER_TYPE, call the function.  */
3612
    if (arg1_align == 0 || arg2_align == 0)
3613
      return 0;
3614
 
3615
    /* Make a place to write the result of the instruction.  */
3616
    result = target;
3617
    if (! (result != 0
3618
           && REG_P (result) && GET_MODE (result) == insn_mode
3619
           && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3620
      result = gen_reg_rtx (insn_mode);
3621
 
3622
    arg1_rtx = get_memory_rtx (arg1, len);
3623
    arg2_rtx = get_memory_rtx (arg2, len);
3624
    arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3625
 
3626
    /* Set MEM_SIZE as appropriate.  */
3627
    if (GET_CODE (arg3_rtx) == CONST_INT)
3628
      {
3629
        set_mem_size (arg1_rtx, arg3_rtx);
3630
        set_mem_size (arg2_rtx, arg3_rtx);
3631
      }
3632
 
3633
#ifdef HAVE_cmpmemsi
3634
    if (HAVE_cmpmemsi)
3635
      insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3636
                           GEN_INT (MIN (arg1_align, arg2_align)));
3637
    else
3638
#endif
3639
#ifdef HAVE_cmpstrnsi
3640
    if (HAVE_cmpstrnsi)
3641
      insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3642
                            GEN_INT (MIN (arg1_align, arg2_align)));
3643
    else
3644
#endif
3645
      gcc_unreachable ();
3646
 
3647
    if (insn)
3648
      emit_insn (insn);
3649
    else
3650
      emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3651
                               TYPE_MODE (integer_type_node), 3,
3652
                               XEXP (arg1_rtx, 0), Pmode,
3653
                               XEXP (arg2_rtx, 0), Pmode,
3654
                               convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3655
                                                TYPE_UNSIGNED (sizetype)),
3656
                               TYPE_MODE (sizetype));
3657
 
3658
    /* Return the value in the proper mode for this function.  */
3659
    mode = TYPE_MODE (TREE_TYPE (exp));
3660
    if (GET_MODE (result) == mode)
3661
      return result;
3662
    else if (target != 0)
3663
      {
3664
        convert_move (target, result, 0);
3665
        return target;
3666
      }
3667
    else
3668
      return convert_to_mode (mode, result, 0);
3669
  }
3670
#endif
3671
 
3672
  return 0;
3673
}
3674
 
3675
/* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3676
   if we failed the caller should emit a normal call, otherwise try to get
3677
   the result in TARGET, if convenient.  */
3678
 
3679
static rtx
3680
expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3681
{
3682
  tree arglist = TREE_OPERAND (exp, 1);
3683
 
3684
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3685
    return 0;
3686
  else
3687
    {
3688
      tree result = fold_builtin_strcmp (arglist);
3689
      if (result)
3690
        return expand_expr (result, target, mode, EXPAND_NORMAL);
3691
    }
3692
 
3693
#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3694
  if (cmpstr_optab[SImode] != CODE_FOR_nothing
3695
      || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3696
    {
3697
      rtx arg1_rtx, arg2_rtx;
3698
      rtx result, insn = NULL_RTX;
3699
      tree fndecl, fn;
3700
 
3701
      tree arg1 = TREE_VALUE (arglist);
3702
      tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3703
      int arg1_align
3704
        = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3705
      int arg2_align
3706
        = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3707
 
3708
      /* If we don't have POINTER_TYPE, call the function.  */
3709
      if (arg1_align == 0 || arg2_align == 0)
3710
        return 0;
3711
 
3712
      /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3713
      arg1 = builtin_save_expr (arg1);
3714
      arg2 = builtin_save_expr (arg2);
3715
 
3716
      arg1_rtx = get_memory_rtx (arg1, NULL);
3717
      arg2_rtx = get_memory_rtx (arg2, NULL);
3718
 
3719
#ifdef HAVE_cmpstrsi
3720
      /* Try to call cmpstrsi.  */
3721
      if (HAVE_cmpstrsi)
3722
        {
3723
          enum machine_mode insn_mode
3724
            = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3725
 
3726
          /* Make a place to write the result of the instruction.  */
3727
          result = target;
3728
          if (! (result != 0
3729
                 && REG_P (result) && GET_MODE (result) == insn_mode
3730
                 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3731
            result = gen_reg_rtx (insn_mode);
3732
 
3733
          insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3734
                               GEN_INT (MIN (arg1_align, arg2_align)));
3735
        }
3736
#endif
3737
#if HAVE_cmpstrnsi 
3738
      /* Try to determine at least one length and call cmpstrnsi.  */
3739
      if (!insn && HAVE_cmpstrnsi)
3740
        {
3741
          tree len;
3742
          rtx arg3_rtx;
3743
 
3744
          enum machine_mode insn_mode
3745
            = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3746
          tree len1 = c_strlen (arg1, 1);
3747
          tree len2 = c_strlen (arg2, 1);
3748
 
3749
          if (len1)
3750
            len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3751
          if (len2)
3752
            len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3753
 
3754
          /* If we don't have a constant length for the first, use the length
3755
             of the second, if we know it.  We don't require a constant for
3756
             this case; some cost analysis could be done if both are available
3757
             but neither is constant.  For now, assume they're equally cheap,
3758
             unless one has side effects.  If both strings have constant lengths,
3759
             use the smaller.  */
3760
 
3761
          if (!len1)
3762
            len = len2;
3763
          else if (!len2)
3764
            len = len1;
3765
          else if (TREE_SIDE_EFFECTS (len1))
3766
            len = len2;
3767
          else if (TREE_SIDE_EFFECTS (len2))
3768
            len = len1;
3769
          else if (TREE_CODE (len1) != INTEGER_CST)
3770
            len = len2;
3771
          else if (TREE_CODE (len2) != INTEGER_CST)
3772
            len = len1;
3773
          else if (tree_int_cst_lt (len1, len2))
3774
            len = len1;
3775
          else
3776
            len = len2;
3777
 
3778
          /* If both arguments have side effects, we cannot optimize.  */
3779
          if (!len || TREE_SIDE_EFFECTS (len))
3780
            goto do_libcall;
3781
 
3782
          arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3783
 
3784
          /* Make a place to write the result of the instruction.  */
3785
          result = target;
3786
          if (! (result != 0
3787
                 && REG_P (result) && GET_MODE (result) == insn_mode
3788
                 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3789
            result = gen_reg_rtx (insn_mode);
3790
 
3791
          insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3792
                                GEN_INT (MIN (arg1_align, arg2_align)));
3793
        }
3794
#endif
3795
 
3796
      if (insn)
3797
        {
3798
          emit_insn (insn);
3799
 
3800
          /* Return the value in the proper mode for this function.  */
3801
          mode = TYPE_MODE (TREE_TYPE (exp));
3802
          if (GET_MODE (result) == mode)
3803
            return result;
3804
          if (target == 0)
3805
            return convert_to_mode (mode, result, 0);
3806
          convert_move (target, result, 0);
3807
          return target;
3808
        }
3809
 
3810
      /* Expand the library call ourselves using a stabilized argument
3811
         list to avoid re-evaluating the function's arguments twice.  */
3812
#if HAVE_cmpstrnsi 
3813
    do_libcall:
3814
#endif
3815
      arglist = build_tree_list (NULL_TREE, arg2);
3816
      arglist = tree_cons (NULL_TREE, arg1, arglist);
3817
      fndecl = get_callee_fndecl (exp);
3818
      fn = build_function_call_expr (fndecl, arglist);
3819
      if (TREE_CODE (fn) == CALL_EXPR)
3820
        CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3821
      return expand_call (fn, target, target == const0_rtx);
3822
    }
3823
#endif
3824
  return 0;
3825
}
3826
 
3827
/* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3828
   if we failed the caller should emit a normal call, otherwise try to get
3829
   the result in TARGET, if convenient.  */
3830
 
3831
static rtx
3832
expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3833
{
3834
  tree arglist = TREE_OPERAND (exp, 1);
3835
 
3836
  if (!validate_arglist (arglist,
3837
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3838
    return 0;
3839
  else
3840
    {
3841
      tree result = fold_builtin_strncmp (arglist);
3842
      if (result)
3843
        return expand_expr (result, target, mode, EXPAND_NORMAL);
3844
    }
3845
 
3846
  /* If c_strlen can determine an expression for one of the string
3847
     lengths, and it doesn't have side effects, then emit cmpstrnsi
3848
     using length MIN(strlen(string)+1, arg3).  */
3849
#ifdef HAVE_cmpstrnsi
3850
  if (HAVE_cmpstrnsi)
3851
  {
3852
    tree arg1 = TREE_VALUE (arglist);
3853
    tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3854
    tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3855
    tree len, len1, len2;
3856
    rtx arg1_rtx, arg2_rtx, arg3_rtx;
3857
    rtx result, insn;
3858
    tree fndecl, fn;
3859
 
3860
    int arg1_align
3861
      = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3862
    int arg2_align
3863
      = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3864
    enum machine_mode insn_mode
3865
      = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3866
 
3867
    len1 = c_strlen (arg1, 1);
3868
    len2 = c_strlen (arg2, 1);
3869
 
3870
    if (len1)
3871
      len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3872
    if (len2)
3873
      len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3874
 
3875
    /* If we don't have a constant length for the first, use the length
3876
       of the second, if we know it.  We don't require a constant for
3877
       this case; some cost analysis could be done if both are available
3878
       but neither is constant.  For now, assume they're equally cheap,
3879
       unless one has side effects.  If both strings have constant lengths,
3880
       use the smaller.  */
3881
 
3882
    if (!len1)
3883
      len = len2;
3884
    else if (!len2)
3885
      len = len1;
3886
    else if (TREE_SIDE_EFFECTS (len1))
3887
      len = len2;
3888
    else if (TREE_SIDE_EFFECTS (len2))
3889
      len = len1;
3890
    else if (TREE_CODE (len1) != INTEGER_CST)
3891
      len = len2;
3892
    else if (TREE_CODE (len2) != INTEGER_CST)
3893
      len = len1;
3894
    else if (tree_int_cst_lt (len1, len2))
3895
      len = len1;
3896
    else
3897
      len = len2;
3898
 
3899
    /* If both arguments have side effects, we cannot optimize.  */
3900
    if (!len || TREE_SIDE_EFFECTS (len))
3901
      return 0;
3902
 
3903
    /* The actual new length parameter is MIN(len,arg3).  */
3904
    len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3905
                       fold_convert (TREE_TYPE (len), arg3));
3906
 
3907
    /* If we don't have POINTER_TYPE, call the function.  */
3908
    if (arg1_align == 0 || arg2_align == 0)
3909
      return 0;
3910
 
3911
    /* Make a place to write the result of the instruction.  */
3912
    result = target;
3913
    if (! (result != 0
3914
           && REG_P (result) && GET_MODE (result) == insn_mode
3915
           && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3916
      result = gen_reg_rtx (insn_mode);
3917
 
3918
    /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
3919
    arg1 = builtin_save_expr (arg1);
3920
    arg2 = builtin_save_expr (arg2);
3921
    len = builtin_save_expr (len);
3922
 
3923
    arg1_rtx = get_memory_rtx (arg1, len);
3924
    arg2_rtx = get_memory_rtx (arg2, len);
3925
    arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3926
    insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3927
                          GEN_INT (MIN (arg1_align, arg2_align)));
3928
    if (insn)
3929
      {
3930
        emit_insn (insn);
3931
 
3932
        /* Return the value in the proper mode for this function.  */
3933
        mode = TYPE_MODE (TREE_TYPE (exp));
3934
        if (GET_MODE (result) == mode)
3935
          return result;
3936
        if (target == 0)
3937
          return convert_to_mode (mode, result, 0);
3938
        convert_move (target, result, 0);
3939
        return target;
3940
      }
3941
 
3942
    /* Expand the library call ourselves using a stabilized argument
3943
       list to avoid re-evaluating the function's arguments twice.  */
3944
    arglist = build_tree_list (NULL_TREE, len);
3945
    arglist = tree_cons (NULL_TREE, arg2, arglist);
3946
    arglist = tree_cons (NULL_TREE, arg1, arglist);
3947
    fndecl = get_callee_fndecl (exp);
3948
    fn = build_function_call_expr (fndecl, arglist);
3949
    if (TREE_CODE (fn) == CALL_EXPR)
3950
      CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3951
    return expand_call (fn, target, target == const0_rtx);
3952
  }
3953
#endif
3954
  return 0;
3955
}
3956
 
3957
/* Expand expression EXP, which is a call to the strcat builtin.
3958
   Return 0 if we failed the caller should emit a normal call,
3959
   otherwise try to get the result in TARGET, if convenient.  */
3960
 
3961
static rtx
3962
expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3963
{
3964
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3965
    return 0;
3966
  else
3967
    {
3968
      tree dst = TREE_VALUE (arglist),
3969
      src = TREE_VALUE (TREE_CHAIN (arglist));
3970
      const char *p = c_getstr (src);
3971
 
3972
      /* If the string length is zero, return the dst parameter.  */
3973
      if (p && *p == '\0')
3974
        return expand_expr (dst, target, mode, EXPAND_NORMAL);
3975
 
3976
      if (!optimize_size)
3977
        {
3978
          /* See if we can store by pieces into (dst + strlen(dst)).  */
3979
          tree newsrc, newdst,
3980
            strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3981
          rtx insns;
3982
 
3983
          /* Stabilize the argument list.  */
3984
          newsrc = builtin_save_expr (src);
3985
          if (newsrc != src)
3986
            arglist = build_tree_list (NULL_TREE, newsrc);
3987
          else
3988
            arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe.  */
3989
 
3990
          dst = builtin_save_expr (dst);
3991
 
3992
          start_sequence ();
3993
 
3994
          /* Create strlen (dst).  */
3995
          newdst =
3996
            build_function_call_expr (strlen_fn,
3997
                                      build_tree_list (NULL_TREE, dst));
3998
          /* Create (dst + (cast) strlen (dst)).  */
3999
          newdst = fold_convert (TREE_TYPE (dst), newdst);
4000
          newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4001
 
4002
          newdst = builtin_save_expr (newdst);
4003
          arglist = tree_cons (NULL_TREE, newdst, arglist);
4004
 
4005
          if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4006
            {
4007
              end_sequence (); /* Stop sequence.  */
4008
              return 0;
4009
            }
4010
 
4011
          /* Output the entire sequence.  */
4012
          insns = get_insns ();
4013
          end_sequence ();
4014
          emit_insn (insns);
4015
 
4016
          return expand_expr (dst, target, mode, EXPAND_NORMAL);
4017
        }
4018
 
4019
      return 0;
4020
    }
4021
}
4022
 
4023
/* Expand expression EXP, which is a call to the strncat builtin.
4024
   Return 0 if we failed the caller should emit a normal call,
4025
   otherwise try to get the result in TARGET, if convenient.  */
4026
 
4027
static rtx
4028
expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4029
{
4030
  if (validate_arglist (arglist,
4031
                        POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4032
    {
4033
      tree result = fold_builtin_strncat (arglist);
4034
      if (result)
4035
        return expand_expr (result, target, mode, EXPAND_NORMAL);
4036
    }
4037
  return 0;
4038
}
4039
 
4040
/* Expand expression EXP, which is a call to the strspn builtin.
4041
   Return 0 if we failed the caller should emit a normal call,
4042
   otherwise try to get the result in TARGET, if convenient.  */
4043
 
4044
static rtx
4045
expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4046
{
4047
  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4048
    {
4049
      tree result = fold_builtin_strspn (arglist);
4050
      if (result)
4051
        return expand_expr (result, target, mode, EXPAND_NORMAL);
4052
    }
4053
  return 0;
4054
}
4055
 
4056
/* Expand expression EXP, which is a call to the strcspn builtin.
4057
   Return 0 if we failed the caller should emit a normal call,
4058
   otherwise try to get the result in TARGET, if convenient.  */
4059
 
4060
static rtx
4061
expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4062
{
4063
  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4064
    {
4065
      tree result = fold_builtin_strcspn (arglist);
4066
      if (result)
4067
        return expand_expr (result, target, mode, EXPAND_NORMAL);
4068
    }
4069
  return 0;
4070
}
4071
 
4072
/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4073
   if that's convenient.  */
4074
 
4075
rtx
4076
expand_builtin_saveregs (void)
4077
{
4078
  rtx val, seq;
4079
 
4080
  /* Don't do __builtin_saveregs more than once in a function.
4081
     Save the result of the first call and reuse it.  */
4082
  if (saveregs_value != 0)
4083
    return saveregs_value;
4084
 
4085
  /* When this function is called, it means that registers must be
4086
     saved on entry to this function.  So we migrate the call to the
4087
     first insn of this function.  */
4088
 
4089
  start_sequence ();
4090
 
4091
  /* Do whatever the machine needs done in this case.  */
4092
  val = targetm.calls.expand_builtin_saveregs ();
4093
 
4094
  seq = get_insns ();
4095
  end_sequence ();
4096
 
4097
  saveregs_value = val;
4098
 
4099
  /* Put the insns after the NOTE that starts the function.  If this
4100
     is inside a start_sequence, make the outer-level insn chain current, so
4101
     the code is placed at the start of the function.  */
4102
  push_topmost_sequence ();
4103
  emit_insn_after (seq, entry_of_function ());
4104
  pop_topmost_sequence ();
4105
 
4106
  return val;
4107
}
4108
 
4109
/* __builtin_args_info (N) returns word N of the arg space info
4110
   for the current function.  The number and meanings of words
4111
   is controlled by the definition of CUMULATIVE_ARGS.  */
4112
 
4113
static rtx
4114
expand_builtin_args_info (tree arglist)
4115
{
4116
  int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4117
  int *word_ptr = (int *) &current_function_args_info;
4118
 
4119
  gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4120
 
4121
  if (arglist != 0)
4122
    {
4123
      if (!host_integerp (TREE_VALUE (arglist), 0))
4124
        error ("argument of %<__builtin_args_info%> must be constant");
4125
      else
4126
        {
4127
          HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4128
 
4129
          if (wordnum < 0 || wordnum >= nwords)
4130
            error ("argument of %<__builtin_args_info%> out of range");
4131
          else
4132
            return GEN_INT (word_ptr[wordnum]);
4133
        }
4134
    }
4135
  else
4136
    error ("missing argument in %<__builtin_args_info%>");
4137
 
4138
  return const0_rtx;
4139
}
4140
 
4141
/* Expand a call to __builtin_next_arg.  */
4142
 
4143
static rtx
4144
expand_builtin_next_arg (void)
4145
{
4146
  /* Checking arguments is already done in fold_builtin_next_arg
4147
     that must be called before this function.  */
4148
  return expand_binop (Pmode, add_optab,
4149
                       current_function_internal_arg_pointer,
4150
                       current_function_arg_offset_rtx,
4151
                       NULL_RTX, 0, OPTAB_LIB_WIDEN);
4152
}
4153
 
4154
/* Make it easier for the backends by protecting the valist argument
4155
   from multiple evaluations.  */
4156
 
4157
static tree
4158
stabilize_va_list (tree valist, int needs_lvalue)
4159
{
4160
  if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4161
    {
4162
      if (TREE_SIDE_EFFECTS (valist))
4163
        valist = save_expr (valist);
4164
 
4165
      /* For this case, the backends will be expecting a pointer to
4166
         TREE_TYPE (va_list_type_node), but it's possible we've
4167
         actually been given an array (an actual va_list_type_node).
4168
         So fix it.  */
4169
      if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4170
        {
4171
          tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4172
          valist = build_fold_addr_expr_with_type (valist, p1);
4173
        }
4174
    }
4175
  else
4176
    {
4177
      tree pt;
4178
 
4179
      if (! needs_lvalue)
4180
        {
4181
          if (! TREE_SIDE_EFFECTS (valist))
4182
            return valist;
4183
 
4184
          pt = build_pointer_type (va_list_type_node);
4185
          valist = fold_build1 (ADDR_EXPR, pt, valist);
4186
          TREE_SIDE_EFFECTS (valist) = 1;
4187
        }
4188
 
4189
      if (TREE_SIDE_EFFECTS (valist))
4190
        valist = save_expr (valist);
4191
      valist = build_fold_indirect_ref (valist);
4192
    }
4193
 
4194
  return valist;
4195
}
4196
 
4197
/* The "standard" definition of va_list is void*.  */
4198
 
4199
tree
4200
std_build_builtin_va_list (void)
4201
{
4202
  return ptr_type_node;
4203
}
4204
 
4205
/* The "standard" implementation of va_start: just assign `nextarg' to
4206
   the variable.  */
4207
 
4208
void
4209
std_expand_builtin_va_start (tree valist, rtx nextarg)
4210
{
4211
  tree t;
4212
 
4213
  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4214
              make_tree (ptr_type_node, nextarg));
4215
  TREE_SIDE_EFFECTS (t) = 1;
4216
 
4217
  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4218
}
4219
 
4220
/* Expand ARGLIST, from a call to __builtin_va_start.  */
4221
 
4222
static rtx
4223
expand_builtin_va_start (tree arglist)
4224
{
4225
  rtx nextarg;
4226
  tree chain, valist;
4227
 
4228
  chain = TREE_CHAIN (arglist);
4229
 
4230
  if (!chain)
4231
    {
4232
      error ("too few arguments to function %<va_start%>");
4233
      return const0_rtx;
4234
    }
4235
 
4236
  if (fold_builtin_next_arg (chain))
4237
    return const0_rtx;
4238
 
4239
  nextarg = expand_builtin_next_arg ();
4240
  valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4241
 
4242
#ifdef EXPAND_BUILTIN_VA_START
4243
  EXPAND_BUILTIN_VA_START (valist, nextarg);
4244
#else
4245
  std_expand_builtin_va_start (valist, nextarg);
4246
#endif
4247
 
4248
  return const0_rtx;
4249
}
4250
 
4251
/* The "standard" implementation of va_arg: read the value from the
4252
   current (padded) address and increment by the (padded) size.  */
4253
 
4254
tree
4255
std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4256
{
4257
  tree addr, t, type_size, rounded_size, valist_tmp;
4258
  unsigned HOST_WIDE_INT align, boundary;
4259
  bool indirect;
4260
 
4261
#ifdef ARGS_GROW_DOWNWARD
4262
  /* All of the alignment and movement below is for args-grow-up machines.
4263
     As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4264
     implement their own specialized gimplify_va_arg_expr routines.  */
4265
  gcc_unreachable ();
4266
#endif
4267
 
4268
  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4269
  if (indirect)
4270
    type = build_pointer_type (type);
4271
 
4272
  align = PARM_BOUNDARY / BITS_PER_UNIT;
4273
  boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4274
 
4275
  /* Hoist the valist value into a temporary for the moment.  */
4276
  valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4277
 
4278
  /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4279
     requires greater alignment, we must perform dynamic alignment.  */
4280
  if (boundary > align
4281
      && !integer_zerop (TYPE_SIZE (type)))
4282
    {
4283
      t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4284
      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4285
                  build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4286
      gimplify_and_add (t, pre_p);
4287
 
4288
      t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4289
      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4290
                  build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4291
      gimplify_and_add (t, pre_p);
4292
    }
4293
  else
4294
    boundary = align;
4295
 
4296
  /* If the actual alignment is less than the alignment of the type,
4297
     adjust the type accordingly so that we don't assume strict alignment
4298
     when deferencing the pointer.  */
4299
  boundary *= BITS_PER_UNIT;
4300
  if (boundary < TYPE_ALIGN (type))
4301
    {
4302
      type = build_variant_type_copy (type);
4303
      TYPE_ALIGN (type) = boundary;
4304
    }
4305
 
4306
  /* Compute the rounded size of the type.  */
4307
  type_size = size_in_bytes (type);
4308
  rounded_size = round_up (type_size, align);
4309
 
4310
  /* Reduce rounded_size so it's sharable with the postqueue.  */
4311
  gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4312
 
4313
  /* Get AP.  */
4314
  addr = valist_tmp;
4315
  if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4316
    {
4317
      /* Small args are padded downward.  */
4318
      t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4319
      t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4320
                       size_binop (MINUS_EXPR, rounded_size, type_size));
4321
      t = fold_convert (TREE_TYPE (addr), t);
4322
      addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4323
    }
4324
 
4325
  /* Compute new value for AP.  */
4326
  t = fold_convert (TREE_TYPE (valist), rounded_size);
4327
  t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4328
  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4329
  gimplify_and_add (t, pre_p);
4330
 
4331
  addr = fold_convert (build_pointer_type (type), addr);
4332
 
4333
  if (indirect)
4334
    addr = build_va_arg_indirect_ref (addr);
4335
 
4336
  return build_va_arg_indirect_ref (addr);
4337
}
4338
 
4339
/* Build an indirect-ref expression over the given TREE, which represents a
4340
   piece of a va_arg() expansion.  */
4341
tree
4342
build_va_arg_indirect_ref (tree addr)
4343
{
4344
  addr = build_fold_indirect_ref (addr);
4345
 
4346
  if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4347
    mf_mark (addr);
4348
 
4349
  return addr;
4350
}
4351
 
4352
/* Return a dummy expression of type TYPE in order to keep going after an
4353
   error.  */
4354
 
4355
static tree
4356
dummy_object (tree type)
4357
{
4358
  tree t = convert (build_pointer_type (type), null_pointer_node);
4359
  return build1 (INDIRECT_REF, type, t);
4360
}
4361
 
4362
/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4363
   builtin function, but a very special sort of operator.  */
4364
 
4365
enum gimplify_status
4366
gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4367
{
4368
  tree promoted_type, want_va_type, have_va_type;
4369
  tree valist = TREE_OPERAND (*expr_p, 0);
4370
  tree type = TREE_TYPE (*expr_p);
4371
  tree t;
4372
 
4373
  /* Verify that valist is of the proper type.  */
4374
  want_va_type = va_list_type_node;
4375
  have_va_type = TREE_TYPE (valist);
4376
 
4377
  if (have_va_type == error_mark_node)
4378
    return GS_ERROR;
4379
 
4380
  if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4381
    {
4382
      /* If va_list is an array type, the argument may have decayed
4383
         to a pointer type, e.g. by being passed to another function.
4384
         In that case, unwrap both types so that we can compare the
4385
         underlying records.  */
4386
      if (TREE_CODE (have_va_type) == ARRAY_TYPE
4387
          || POINTER_TYPE_P (have_va_type))
4388
        {
4389
          want_va_type = TREE_TYPE (want_va_type);
4390
          have_va_type = TREE_TYPE (have_va_type);
4391
        }
4392
    }
4393
 
4394
  if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4395
    {
4396
      error ("first argument to %<va_arg%> not of type %<va_list%>");
4397
      return GS_ERROR;
4398
    }
4399
 
4400
  /* Generate a diagnostic for requesting data of a type that cannot
4401
     be passed through `...' due to type promotion at the call site.  */
4402
  else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4403
           != type)
4404
    {
4405
      static bool gave_help;
4406
 
4407
      /* Unfortunately, this is merely undefined, rather than a constraint
4408
         violation, so we cannot make this an error.  If this call is never
4409
         executed, the program is still strictly conforming.  */
4410
      warning (0, "%qT is promoted to %qT when passed through %<...%>",
4411
               type, promoted_type);
4412
      if (! gave_help)
4413
        {
4414
          gave_help = true;
4415
          warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4416
                   promoted_type, type);
4417
        }
4418
 
4419
      /* We can, however, treat "undefined" any way we please.
4420
         Call abort to encourage the user to fix the program.  */
4421
      inform ("if this code is reached, the program will abort");
4422
      t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4423
                                    NULL);
4424
      append_to_statement_list (t, pre_p);
4425
 
4426
      /* This is dead code, but go ahead and finish so that the
4427
         mode of the result comes out right.  */
4428
      *expr_p = dummy_object (type);
4429
      return GS_ALL_DONE;
4430
    }
4431
  else
4432
    {
4433
      /* Make it easier for the backends by protecting the valist argument
4434
         from multiple evaluations.  */
4435
      if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4436
        {
4437
          /* For this case, the backends will be expecting a pointer to
4438
             TREE_TYPE (va_list_type_node), but it's possible we've
4439
             actually been given an array (an actual va_list_type_node).
4440
             So fix it.  */
4441
          if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4442
            {
4443
              tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4444
              valist = build_fold_addr_expr_with_type (valist, p1);
4445
            }
4446
          gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4447
        }
4448
      else
4449
        gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4450
 
4451
      if (!targetm.gimplify_va_arg_expr)
4452
        /* FIXME:Once most targets are converted we should merely
4453
           assert this is non-null.  */
4454
        return GS_ALL_DONE;
4455
 
4456
      *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4457
      return GS_OK;
4458
    }
4459
}
4460
 
4461
/* Expand ARGLIST, from a call to __builtin_va_end.  */
4462
 
4463
static rtx
4464
expand_builtin_va_end (tree arglist)
4465
{
4466
  tree valist = TREE_VALUE (arglist);
4467
 
4468
  /* Evaluate for side effects, if needed.  I hate macros that don't
4469
     do that.  */
4470
  if (TREE_SIDE_EFFECTS (valist))
4471
    expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4472
 
4473
  return const0_rtx;
4474
}
4475
 
4476
/* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4477
   builtin rather than just as an assignment in stdarg.h because of the
4478
   nastiness of array-type va_list types.  */
4479
 
4480
static rtx
4481
expand_builtin_va_copy (tree arglist)
4482
{
4483
  tree dst, src, t;
4484
 
4485
  dst = TREE_VALUE (arglist);
4486
  src = TREE_VALUE (TREE_CHAIN (arglist));
4487
 
4488
  dst = stabilize_va_list (dst, 1);
4489
  src = stabilize_va_list (src, 0);
4490
 
4491
  if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4492
    {
4493
      t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4494
      TREE_SIDE_EFFECTS (t) = 1;
4495
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4496
    }
4497
  else
4498
    {
4499
      rtx dstb, srcb, size;
4500
 
4501
      /* Evaluate to pointers.  */
4502
      dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4503
      srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4504
      size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4505
                          VOIDmode, EXPAND_NORMAL);
4506
 
4507
      dstb = convert_memory_address (Pmode, dstb);
4508
      srcb = convert_memory_address (Pmode, srcb);
4509
 
4510
      /* "Dereference" to BLKmode memories.  */
4511
      dstb = gen_rtx_MEM (BLKmode, dstb);
4512
      set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4513
      set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4514
      srcb = gen_rtx_MEM (BLKmode, srcb);
4515
      set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4516
      set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4517
 
4518
      /* Copy.  */
4519
      emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4520
    }
4521
 
4522
  return const0_rtx;
4523
}
4524
 
4525
/* Expand a call to one of the builtin functions __builtin_frame_address or
4526
   __builtin_return_address.  */
4527
 
4528
static rtx
4529
expand_builtin_frame_address (tree fndecl, tree arglist)
4530
{
4531
  /* The argument must be a nonnegative integer constant.
4532
     It counts the number of frames to scan up the stack.
4533
     The value is the return address saved in that frame.  */
4534
  if (arglist == 0)
4535
    /* Warning about missing arg was already issued.  */
4536
    return const0_rtx;
4537
  else if (! host_integerp (TREE_VALUE (arglist), 1))
4538
    {
4539
      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4540
        error ("invalid argument to %<__builtin_frame_address%>");
4541
      else
4542
        error ("invalid argument to %<__builtin_return_address%>");
4543
      return const0_rtx;
4544
    }
4545
  else
4546
    {
4547
      rtx tem
4548
        = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4549
                                      tree_low_cst (TREE_VALUE (arglist), 1));
4550
 
4551
      /* Some ports cannot access arbitrary stack frames.  */
4552
      if (tem == NULL)
4553
        {
4554
          if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4555
            warning (0, "unsupported argument to %<__builtin_frame_address%>");
4556
          else
4557
            warning (0, "unsupported argument to %<__builtin_return_address%>");
4558
          return const0_rtx;
4559
        }
4560
 
4561
      /* For __builtin_frame_address, return what we've got.  */
4562
      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4563
        return tem;
4564
 
4565
      if (!REG_P (tem)
4566
          && ! CONSTANT_P (tem))
4567
        tem = copy_to_mode_reg (Pmode, tem);
4568
      return tem;
4569
    }
4570
}
4571
 
4572
/* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4573
   we failed and the caller should emit a normal call, otherwise try to get
4574
   the result in TARGET, if convenient.  */
4575
 
4576
static rtx
4577
expand_builtin_alloca (tree arglist, rtx target)
4578
{
4579
  rtx op0;
4580
  rtx result;
4581
 
4582
  /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4583
     should always expand to function calls.  These can be intercepted
4584
     in libmudflap.  */
4585
  if (flag_mudflap)
4586
    return 0;
4587
 
4588
  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4589
    return 0;
4590
 
4591
  /* Compute the argument.  */
4592
  op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4593
 
4594
  /* Allocate the desired space.  */
4595
  result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4596
  result = convert_memory_address (ptr_mode, result);
4597
 
4598
  return result;
4599
}
4600
 
4601
/* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4602
   Return 0 if a normal call should be emitted rather than expanding the
4603
   function in-line.  If convenient, the result should be placed in TARGET.
4604
   SUBTARGET may be used as the target for computing one of EXP's operands.  */
4605
 
4606
static rtx
4607
expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4608
                     rtx subtarget, optab op_optab)
4609
{
4610
  rtx op0;
4611
  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4612
    return 0;
4613
 
4614
  /* Compute the argument.  */
4615
  op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4616
  /* Compute op, into TARGET if possible.
4617
     Set TARGET to wherever the result comes back.  */
4618
  target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4619
                        op_optab, op0, target, 1);
4620
  gcc_assert (target);
4621
 
4622
  return convert_to_mode (target_mode, target, 0);
4623
}
4624
 
4625
/* If the string passed to fputs is a constant and is one character
4626
   long, we attempt to transform this call into __builtin_fputc().  */
4627
 
4628
static rtx
4629
expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4630
{
4631
  /* Verify the arguments in the original call.  */
4632
  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4633
    {
4634
      tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4635
                                        unlocked, NULL_TREE);
4636
      if (result)
4637
        return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4638
    }
4639
  return 0;
4640
}
4641
 
4642
/* Expand a call to __builtin_expect.  We return our argument and emit a
4643
   NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4644
   a non-jump context.  */
4645
 
4646
static rtx
4647
expand_builtin_expect (tree arglist, rtx target)
4648
{
4649
  tree exp, c;
4650
  rtx note, rtx_c;
4651
 
4652
  if (arglist == NULL_TREE
4653
      || TREE_CHAIN (arglist) == NULL_TREE)
4654
    return const0_rtx;
4655
  exp = TREE_VALUE (arglist);
4656
  c = TREE_VALUE (TREE_CHAIN (arglist));
4657
 
4658
  if (TREE_CODE (c) != INTEGER_CST)
4659
    {
4660
      error ("second argument to %<__builtin_expect%> must be a constant");
4661
      c = integer_zero_node;
4662
    }
4663
 
4664
  target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4665
 
4666
  /* Don't bother with expected value notes for integral constants.  */
4667
  if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4668
    {
4669
      /* We do need to force this into a register so that we can be
4670
         moderately sure to be able to correctly interpret the branch
4671
         condition later.  */
4672
      target = force_reg (GET_MODE (target), target);
4673
 
4674
      rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4675
 
4676
      note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4677
      NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4678
    }
4679
 
4680
  return target;
4681
}
4682
 
4683
/* Like expand_builtin_expect, except do this in a jump context.  This is
4684
   called from do_jump if the conditional is a __builtin_expect.  Return either
4685
   a list of insns to emit the jump or NULL if we cannot optimize
4686
   __builtin_expect.  We need to optimize this at jump time so that machines
4687
   like the PowerPC don't turn the test into a SCC operation, and then jump
4688
   based on the test being 0/1.  */
4689
 
4690
rtx
4691
expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4692
{
4693
  tree arglist = TREE_OPERAND (exp, 1);
4694
  tree arg0 = TREE_VALUE (arglist);
4695
  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4696
  rtx ret = NULL_RTX;
4697
 
4698
  /* Only handle __builtin_expect (test, 0) and
4699
     __builtin_expect (test, 1).  */
4700
  if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4701
      && (integer_zerop (arg1) || integer_onep (arg1)))
4702
    {
4703
      rtx insn, drop_through_label, temp;
4704
 
4705
      /* Expand the jump insns.  */
4706
      start_sequence ();
4707
      do_jump (arg0, if_false_label, if_true_label);
4708
      ret = get_insns ();
4709
 
4710
      drop_through_label = get_last_insn ();
4711
      if (drop_through_label && NOTE_P (drop_through_label))
4712
        drop_through_label = prev_nonnote_insn (drop_through_label);
4713
      if (drop_through_label && !LABEL_P (drop_through_label))
4714
        drop_through_label = NULL_RTX;
4715
      end_sequence ();
4716
 
4717
      if (! if_true_label)
4718
        if_true_label = drop_through_label;
4719
      if (! if_false_label)
4720
        if_false_label = drop_through_label;
4721
 
4722
      /* Go through and add the expect's to each of the conditional jumps.  */
4723
      insn = ret;
4724
      while (insn != NULL_RTX)
4725
        {
4726
          rtx next = NEXT_INSN (insn);
4727
 
4728
          if (JUMP_P (insn) && any_condjump_p (insn))
4729
            {
4730
              rtx ifelse = SET_SRC (pc_set (insn));
4731
              rtx then_dest = XEXP (ifelse, 1);
4732
              rtx else_dest = XEXP (ifelse, 2);
4733
              int taken = -1;
4734
 
4735
              /* First check if we recognize any of the labels.  */
4736
              if (GET_CODE (then_dest) == LABEL_REF
4737
                  && XEXP (then_dest, 0) == if_true_label)
4738
                taken = 1;
4739
              else if (GET_CODE (then_dest) == LABEL_REF
4740
                       && XEXP (then_dest, 0) == if_false_label)
4741
                taken = 0;
4742
              else if (GET_CODE (else_dest) == LABEL_REF
4743
                       && XEXP (else_dest, 0) == if_false_label)
4744
                taken = 1;
4745
              else if (GET_CODE (else_dest) == LABEL_REF
4746
                       && XEXP (else_dest, 0) == if_true_label)
4747
                taken = 0;
4748
              /* Otherwise check where we drop through.  */
4749
              else if (else_dest == pc_rtx)
4750
                {
4751
                  if (next && NOTE_P (next))
4752
                    next = next_nonnote_insn (next);
4753
 
4754
                  if (next && JUMP_P (next)
4755
                      && any_uncondjump_p (next))
4756
                    temp = XEXP (SET_SRC (pc_set (next)), 0);
4757
                  else
4758
                    temp = next;
4759
 
4760
                  /* TEMP is either a CODE_LABEL, NULL_RTX or something
4761
                     else that can't possibly match either target label.  */
4762
                  if (temp == if_false_label)
4763
                    taken = 1;
4764
                  else if (temp == if_true_label)
4765
                    taken = 0;
4766
                }
4767
              else if (then_dest == pc_rtx)
4768
                {
4769
                  if (next && NOTE_P (next))
4770
                    next = next_nonnote_insn (next);
4771
 
4772
                  if (next && JUMP_P (next)
4773
                      && any_uncondjump_p (next))
4774
                    temp = XEXP (SET_SRC (pc_set (next)), 0);
4775
                  else
4776
                    temp = next;
4777
 
4778
                  if (temp == if_false_label)
4779
                    taken = 0;
4780
                  else if (temp == if_true_label)
4781
                    taken = 1;
4782
                }
4783
 
4784
              if (taken != -1)
4785
                {
4786
                  /* If the test is expected to fail, reverse the
4787
                     probabilities.  */
4788
                  if (integer_zerop (arg1))
4789
                    taken = 1 - taken;
4790
                  predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4791
                }
4792
            }
4793
 
4794
          insn = next;
4795
        }
4796
    }
4797
 
4798
  return ret;
4799
}
4800
 
4801
void
4802
expand_builtin_trap (void)
4803
{
4804
#ifdef HAVE_trap
4805
  if (HAVE_trap)
4806
    emit_insn (gen_trap ());
4807
  else
4808
#endif
4809
    emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4810
  emit_barrier ();
4811
}
4812
 
4813
/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4814
   Return 0 if a normal call should be emitted rather than expanding
4815
   the function inline.  If convenient, the result should be placed
4816
   in TARGET.  SUBTARGET may be used as the target for computing
4817
   the operand.  */
4818
 
4819
static rtx
4820
expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4821
{
4822
  enum machine_mode mode;
4823
  tree arg;
4824
  rtx op0;
4825
 
4826
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4827
    return 0;
4828
 
4829
  arg = TREE_VALUE (arglist);
4830
  mode = TYPE_MODE (TREE_TYPE (arg));
4831
  op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4832
  return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4833
}
4834
 
4835
/* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4836
   Return NULL is a normal call should be emitted rather than expanding the
4837
   function inline.  If convenient, the result should be placed in TARGET.
4838
   SUBTARGET may be used as the target for computing the operand.  */
4839
 
4840
static rtx
4841
expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4842
{
4843
  rtx op0, op1;
4844
  tree arg;
4845
 
4846
  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4847
    return 0;
4848
 
4849
  arg = TREE_VALUE (arglist);
4850
  op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4851
 
4852
  arg = TREE_VALUE (TREE_CHAIN (arglist));
4853
  op1 = expand_expr (arg, NULL, VOIDmode, 0);
4854
 
4855
  return expand_copysign (op0, op1, target);
4856
}
4857
 
4858
/* Create a new constant string literal and return a char* pointer to it.
4859
   The STRING_CST value is the LEN characters at STR.  */
4860
static tree
4861
build_string_literal (int len, const char *str)
4862
{
4863
  tree t, elem, index, type;
4864
 
4865
  t = build_string (len, str);
4866
  elem = build_type_variant (char_type_node, 1, 0);
4867
  index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4868
  type = build_array_type (elem, index);
4869
  TREE_TYPE (t) = type;
4870
  TREE_CONSTANT (t) = 1;
4871
  TREE_INVARIANT (t) = 1;
4872
  TREE_READONLY (t) = 1;
4873
  TREE_STATIC (t) = 1;
4874
 
4875
  type = build_pointer_type (type);
4876
  t = build1 (ADDR_EXPR, type, t);
4877
 
4878
  type = build_pointer_type (elem);
4879
  t = build1 (NOP_EXPR, type, t);
4880
  return t;
4881
}
4882
 
4883
/* Expand EXP, a call to printf or printf_unlocked.
4884
   Return 0 if a normal call should be emitted rather than transforming
4885
   the function inline.  If convenient, the result should be placed in
4886
   TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4887
   call.  */
4888
static rtx
4889
expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4890
                       bool unlocked)
4891
{
4892
  tree arglist = TREE_OPERAND (exp, 1);
4893
  /* If we're using an unlocked function, assume the other unlocked
4894
     functions exist explicitly.  */
4895
  tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4896
    : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4897
  tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4898
    : implicit_built_in_decls[BUILT_IN_PUTS];
4899
  const char *fmt_str;
4900
  tree fn, fmt, arg;
4901
 
4902
  /* If the return value is used, don't do the transformation.  */
4903
  if (target != const0_rtx)
4904
    return 0;
4905
 
4906
  /* Verify the required arguments in the original call.  */
4907
  if (! arglist)
4908
    return 0;
4909
  fmt = TREE_VALUE (arglist);
4910
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4911
    return 0;
4912
  arglist = TREE_CHAIN (arglist);
4913
 
4914
  /* Check whether the format is a literal string constant.  */
4915
  fmt_str = c_getstr (fmt);
4916
  if (fmt_str == NULL)
4917
    return 0;
4918
 
4919
  if (!init_target_chars())
4920
    return 0;
4921
 
4922
  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4923
  if (strcmp (fmt_str, target_percent_s_newline) == 0)
4924
    {
4925
      if (! arglist
4926
          || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4927
          || TREE_CHAIN (arglist))
4928
        return 0;
4929
      fn = fn_puts;
4930
    }
4931
  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4932
  else if (strcmp (fmt_str, target_percent_c) == 0)
4933
    {
4934
      if (! arglist
4935
          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4936
          || TREE_CHAIN (arglist))
4937
        return 0;
4938
      fn = fn_putchar;
4939
    }
4940
  else
4941
    {
4942
      /* We can't handle anything else with % args or %% ... yet.  */
4943
      if (strchr (fmt_str, target_percent))
4944
        return 0;
4945
 
4946
      if (arglist)
4947
        return 0;
4948
 
4949
      /* If the format specifier was "", printf does nothing.  */
4950
      if (fmt_str[0] == '\0')
4951
        return const0_rtx;
4952
      /* If the format specifier has length of 1, call putchar.  */
4953
      if (fmt_str[1] == '\0')
4954
        {
4955
          /* Given printf("c"), (where c is any one character,)
4956
             convert "c"[0] to an int and pass that to the replacement
4957
             function.  */
4958
          arg = build_int_cst (NULL_TREE, fmt_str[0]);
4959
          arglist = build_tree_list (NULL_TREE, arg);
4960
          fn = fn_putchar;
4961
        }
4962
      else
4963
        {
4964
          /* If the format specifier was "string\n", call puts("string").  */
4965
          size_t len = strlen (fmt_str);
4966
          if ((unsigned char)fmt_str[len - 1] == target_newline)
4967
            {
4968
              /* Create a NUL-terminated string that's one char shorter
4969
                 than the original, stripping off the trailing '\n'.  */
4970
              char *newstr = alloca (len);
4971
              memcpy (newstr, fmt_str, len - 1);
4972
              newstr[len - 1] = 0;
4973
 
4974
              arg = build_string_literal (len, newstr);
4975
              arglist = build_tree_list (NULL_TREE, arg);
4976
              fn = fn_puts;
4977
            }
4978
          else
4979
            /* We'd like to arrange to call fputs(string,stdout) here,
4980
               but we need stdout and don't have a way to get it yet.  */
4981
            return 0;
4982
        }
4983
    }
4984
 
4985
  if (!fn)
4986
    return 0;
4987
  fn = build_function_call_expr (fn, arglist);
4988
  if (TREE_CODE (fn) == CALL_EXPR)
4989
    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4990
  return expand_expr (fn, target, mode, EXPAND_NORMAL);
4991
}
4992
 
4993
/* Expand EXP, a call to fprintf or fprintf_unlocked.
4994
   Return 0 if a normal call should be emitted rather than transforming
4995
   the function inline.  If convenient, the result should be placed in
4996
   TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4997
   call.  */
4998
static rtx
4999
expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5000
                        bool unlocked)
5001
{
5002
  tree arglist = TREE_OPERAND (exp, 1);
5003
  /* If we're using an unlocked function, assume the other unlocked
5004
     functions exist explicitly.  */
5005
  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5006
    : implicit_built_in_decls[BUILT_IN_FPUTC];
5007
  tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5008
    : implicit_built_in_decls[BUILT_IN_FPUTS];
5009
  const char *fmt_str;
5010
  tree fn, fmt, fp, arg;
5011
 
5012
  /* If the return value is used, don't do the transformation.  */
5013
  if (target != const0_rtx)
5014
    return 0;
5015
 
5016
  /* Verify the required arguments in the original call.  */
5017
  if (! arglist)
5018
    return 0;
5019
  fp = TREE_VALUE (arglist);
5020
  if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5021
    return 0;
5022
  arglist = TREE_CHAIN (arglist);
5023
  if (! arglist)
5024
    return 0;
5025
  fmt = TREE_VALUE (arglist);
5026
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5027
    return 0;
5028
  arglist = TREE_CHAIN (arglist);
5029
 
5030
  /* Check whether the format is a literal string constant.  */
5031
  fmt_str = c_getstr (fmt);
5032
  if (fmt_str == NULL)
5033
    return 0;
5034
 
5035
  if (!init_target_chars())
5036
    return 0;
5037
 
5038
  /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5039
  if (strcmp (fmt_str, target_percent_s) == 0)
5040
    {
5041
      if (! arglist
5042
          || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5043
          || TREE_CHAIN (arglist))
5044
        return 0;
5045
      arg = TREE_VALUE (arglist);
5046
      arglist = build_tree_list (NULL_TREE, fp);
5047
      arglist = tree_cons (NULL_TREE, arg, arglist);
5048
      fn = fn_fputs;
5049
    }
5050
  /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5051
  else if (strcmp (fmt_str, target_percent_c) == 0)
5052
    {
5053
      if (! arglist
5054
          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5055
          || TREE_CHAIN (arglist))
5056
        return 0;
5057
      arg = TREE_VALUE (arglist);
5058
      arglist = build_tree_list (NULL_TREE, fp);
5059
      arglist = tree_cons (NULL_TREE, arg, arglist);
5060
      fn = fn_fputc;
5061
    }
5062
  else
5063
    {
5064
      /* We can't handle anything else with % args or %% ... yet.  */
5065
      if (strchr (fmt_str, target_percent))
5066
        return 0;
5067
 
5068
      if (arglist)
5069
        return 0;
5070
 
5071
      /* If the format specifier was "", fprintf does nothing.  */
5072
      if (fmt_str[0] == '\0')
5073
        {
5074
          /* Evaluate and ignore FILE* argument for side-effects.  */
5075
          expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5076
          return const0_rtx;
5077
        }
5078
 
5079
      /* When "string" doesn't contain %, replace all cases of
5080
         fprintf(stream,string) with fputs(string,stream).  The fputs
5081
         builtin will take care of special cases like length == 1.  */
5082
      arglist = build_tree_list (NULL_TREE, fp);
5083
      arglist = tree_cons (NULL_TREE, fmt, arglist);
5084
      fn = fn_fputs;
5085
    }
5086
 
5087
  if (!fn)
5088
    return 0;
5089
  fn = build_function_call_expr (fn, arglist);
5090
  if (TREE_CODE (fn) == CALL_EXPR)
5091
    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5092
  return expand_expr (fn, target, mode, EXPAND_NORMAL);
5093
}
5094
 
5095
/* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5096
   a normal call should be emitted rather than expanding the function
5097
   inline.  If convenient, the result should be placed in TARGET with
5098
   mode MODE.  */
5099
 
5100
static rtx
5101
expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5102
{
5103
  tree orig_arglist, dest, fmt;
5104
  const char *fmt_str;
5105
 
5106
  orig_arglist = arglist;
5107
 
5108
  /* Verify the required arguments in the original call.  */
5109
  if (! arglist)
5110
    return 0;
5111
  dest = TREE_VALUE (arglist);
5112
  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5113
    return 0;
5114
  arglist = TREE_CHAIN (arglist);
5115
  if (! arglist)
5116
    return 0;
5117
  fmt = TREE_VALUE (arglist);
5118
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5119
    return 0;
5120
  arglist = TREE_CHAIN (arglist);
5121
 
5122
  /* Check whether the format is a literal string constant.  */
5123
  fmt_str = c_getstr (fmt);
5124
  if (fmt_str == NULL)
5125
    return 0;
5126
 
5127
  if (!init_target_chars())
5128
    return 0;
5129
 
5130
  /* If the format doesn't contain % args or %%, use strcpy.  */
5131
  if (strchr (fmt_str, target_percent) == 0)
5132
    {
5133
      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5134
      tree exp;
5135
 
5136
      if (arglist || ! fn)
5137
        return 0;
5138
      expand_expr (build_function_call_expr (fn, orig_arglist),
5139
                   const0_rtx, VOIDmode, EXPAND_NORMAL);
5140
      if (target == const0_rtx)
5141
        return const0_rtx;
5142
      exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5143
      return expand_expr (exp, target, mode, EXPAND_NORMAL);
5144
    }
5145
  /* If the format is "%s", use strcpy if the result isn't used.  */
5146
  else if (strcmp (fmt_str, target_percent_s) == 0)
5147
    {
5148
      tree fn, arg, len;
5149
      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5150
 
5151
      if (! fn)
5152
        return 0;
5153
 
5154
      if (! arglist || TREE_CHAIN (arglist))
5155
        return 0;
5156
      arg = TREE_VALUE (arglist);
5157
      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5158
        return 0;
5159
 
5160
      if (target != const0_rtx)
5161
        {
5162
          len = c_strlen (arg, 1);
5163
          if (! len || TREE_CODE (len) != INTEGER_CST)
5164
            return 0;
5165
        }
5166
      else
5167
        len = NULL_TREE;
5168
 
5169
      arglist = build_tree_list (NULL_TREE, arg);
5170
      arglist = tree_cons (NULL_TREE, dest, arglist);
5171
      expand_expr (build_function_call_expr (fn, arglist),
5172
                   const0_rtx, VOIDmode, EXPAND_NORMAL);
5173
 
5174
      if (target == const0_rtx)
5175
        return const0_rtx;
5176
      return expand_expr (len, target, mode, EXPAND_NORMAL);
5177
    }
5178
 
5179
  return 0;
5180
}
5181
 
5182
/* Expand a call to either the entry or exit function profiler.  */
5183
 
5184
static rtx
5185
expand_builtin_profile_func (bool exitp)
5186
{
5187
  rtx this, which;
5188
 
5189
  this = DECL_RTL (current_function_decl);
5190
  gcc_assert (MEM_P (this));
5191
  this = XEXP (this, 0);
5192
 
5193
  if (exitp)
5194
    which = profile_function_exit_libfunc;
5195
  else
5196
    which = profile_function_entry_libfunc;
5197
 
5198
  emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5199
                     expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5200
                                                 0),
5201
                     Pmode);
5202
 
5203
  return const0_rtx;
5204
}
5205
 
5206
/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5207
 
5208
static rtx
5209
round_trampoline_addr (rtx tramp)
5210
{
5211
  rtx temp, addend, mask;
5212
 
5213
  /* If we don't need too much alignment, we'll have been guaranteed
5214
     proper alignment by get_trampoline_type.  */
5215
  if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5216
    return tramp;
5217
 
5218
  /* Round address up to desired boundary.  */
5219
  temp = gen_reg_rtx (Pmode);
5220
  addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5221
  mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5222
 
5223
  temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5224
                               temp, 0, OPTAB_LIB_WIDEN);
5225
  tramp = expand_simple_binop (Pmode, AND, temp, mask,
5226
                               temp, 0, OPTAB_LIB_WIDEN);
5227
 
5228
  return tramp;
5229
}
5230
 
5231
static rtx
5232
expand_builtin_init_trampoline (tree arglist)
5233
{
5234
  tree t_tramp, t_func, t_chain;
5235
  rtx r_tramp, r_func, r_chain;
5236
#ifdef TRAMPOLINE_TEMPLATE
5237
  rtx blktramp;
5238
#endif
5239
 
5240
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5241
                         POINTER_TYPE, VOID_TYPE))
5242
    return NULL_RTX;
5243
 
5244
  t_tramp = TREE_VALUE (arglist);
5245
  arglist = TREE_CHAIN (arglist);
5246
  t_func = TREE_VALUE (arglist);
5247
  arglist = TREE_CHAIN (arglist);
5248
  t_chain = TREE_VALUE (arglist);
5249
 
5250
  r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5251
  r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5252
  r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5253
 
5254
  /* Generate insns to initialize the trampoline.  */
5255
  r_tramp = round_trampoline_addr (r_tramp);
5256
#ifdef TRAMPOLINE_TEMPLATE
5257
  blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5258
  set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5259
  emit_block_move (blktramp, assemble_trampoline_template (),
5260
                   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5261
#endif
5262
  trampolines_created = 1;
5263
  INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5264
 
5265
  return const0_rtx;
5266
}
5267
 
5268
static rtx
5269
expand_builtin_adjust_trampoline (tree arglist)
5270
{
5271
  rtx tramp;
5272
 
5273
  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5274
    return NULL_RTX;
5275
 
5276
  tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5277
  tramp = round_trampoline_addr (tramp);
5278
#ifdef TRAMPOLINE_ADJUST_ADDRESS
5279
  TRAMPOLINE_ADJUST_ADDRESS (tramp);
5280
#endif
5281
 
5282
  return tramp;
5283
}
5284
 
5285
/* Expand a call to the built-in signbit, signbitf or signbitl function.
5286
   Return NULL_RTX if a normal call should be emitted rather than expanding
5287
   the function in-line.  EXP is the expression that is a call to the builtin
5288
   function; if convenient, the result should be placed in TARGET.  */
5289
 
5290
static rtx
5291
expand_builtin_signbit (tree exp, rtx target)
5292
{
5293
  const struct real_format *fmt;
5294
  enum machine_mode fmode, imode, rmode;
5295
  HOST_WIDE_INT hi, lo;
5296
  tree arg, arglist;
5297
  int word, bitpos;
5298
  rtx temp;
5299
 
5300
  arglist = TREE_OPERAND (exp, 1);
5301
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5302
    return 0;
5303
 
5304
  arg = TREE_VALUE (arglist);
5305
  fmode = TYPE_MODE (TREE_TYPE (arg));
5306
  rmode = TYPE_MODE (TREE_TYPE (exp));
5307
  fmt = REAL_MODE_FORMAT (fmode);
5308
 
5309
  /* For floating point formats without a sign bit, implement signbit
5310
     as "ARG < 0.0".  */
5311
  bitpos = fmt->signbit_ro;
5312
  if (bitpos < 0)
5313
  {
5314
    /* But we can't do this if the format supports signed zero.  */
5315
    if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5316
      return 0;
5317
 
5318
    arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5319
                       build_real (TREE_TYPE (arg), dconst0));
5320
    return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5321
  }
5322
 
5323
  temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5324
  if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5325
    {
5326
      imode = int_mode_for_mode (fmode);
5327
      if (imode == BLKmode)
5328
        return 0;
5329
      temp = gen_lowpart (imode, temp);
5330
    }
5331
  else
5332
    {
5333
      imode = word_mode;
5334
      /* Handle targets with different FP word orders.  */
5335
      if (FLOAT_WORDS_BIG_ENDIAN)
5336
        word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5337
      else
5338
        word = bitpos / BITS_PER_WORD;
5339
      temp = operand_subword_force (temp, word, fmode);
5340
      bitpos = bitpos % BITS_PER_WORD;
5341
    }
5342
 
5343
  /* Force the intermediate word_mode (or narrower) result into a
5344
     register.  This avoids attempting to create paradoxical SUBREGs
5345
     of floating point modes below.  */
5346
  temp = force_reg (imode, temp);
5347
 
5348
  /* If the bitpos is within the "result mode" lowpart, the operation
5349
     can be implement with a single bitwise AND.  Otherwise, we need
5350
     a right shift and an AND.  */
5351
 
5352
  if (bitpos < GET_MODE_BITSIZE (rmode))
5353
    {
5354
      if (bitpos < HOST_BITS_PER_WIDE_INT)
5355
        {
5356
          hi = 0;
5357
          lo = (HOST_WIDE_INT) 1 << bitpos;
5358
        }
5359
      else
5360
        {
5361
          hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5362
          lo = 0;
5363
        }
5364
 
5365
      if (imode != rmode)
5366
        temp = gen_lowpart (rmode, temp);
5367
      temp = expand_binop (rmode, and_optab, temp,
5368
                           immed_double_const (lo, hi, rmode),
5369
                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
5370
    }
5371
  else
5372
    {
5373
      /* Perform a logical right shift to place the signbit in the least
5374
         significant bit, then truncate the result to the desired mode
5375
         and mask just this bit.  */
5376
      temp = expand_shift (RSHIFT_EXPR, imode, temp,
5377
                           build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5378
      temp = gen_lowpart (rmode, temp);
5379
      temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5380
                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
5381
    }
5382
 
5383
  return temp;
5384
}
5385
 
5386
/* Expand fork or exec calls.  TARGET is the desired target of the
5387
   call.  ARGLIST is the list of arguments of the call.  FN is the
5388
   identificator of the actual function.  IGNORE is nonzero if the
5389
   value is to be ignored.  */
5390
 
5391
static rtx
5392
expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5393
{
5394
  tree id, decl;
5395
  tree call;
5396
 
5397
  /* If we are not profiling, just call the function.  */
5398
  if (!profile_arc_flag)
5399
    return NULL_RTX;
5400
 
5401
  /* Otherwise call the wrapper.  This should be equivalent for the rest of
5402
     compiler, so the code does not diverge, and the wrapper may run the
5403
     code necessary for keeping the profiling sane.  */
5404
 
5405
  switch (DECL_FUNCTION_CODE (fn))
5406
    {
5407
    case BUILT_IN_FORK:
5408
      id = get_identifier ("__gcov_fork");
5409
      break;
5410
 
5411
    case BUILT_IN_EXECL:
5412
      id = get_identifier ("__gcov_execl");
5413
      break;
5414
 
5415
    case BUILT_IN_EXECV:
5416
      id = get_identifier ("__gcov_execv");
5417
      break;
5418
 
5419
    case BUILT_IN_EXECLP:
5420
      id = get_identifier ("__gcov_execlp");
5421
      break;
5422
 
5423
    case BUILT_IN_EXECLE:
5424
      id = get_identifier ("__gcov_execle");
5425
      break;
5426
 
5427
    case BUILT_IN_EXECVP:
5428
      id = get_identifier ("__gcov_execvp");
5429
      break;
5430
 
5431
    case BUILT_IN_EXECVE:
5432
      id = get_identifier ("__gcov_execve");
5433
      break;
5434
 
5435
    default:
5436
      gcc_unreachable ();
5437
    }
5438
 
5439
  decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5440
  DECL_EXTERNAL (decl) = 1;
5441
  TREE_PUBLIC (decl) = 1;
5442
  DECL_ARTIFICIAL (decl) = 1;
5443
  TREE_NOTHROW (decl) = 1;
5444
  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5445
  DECL_VISIBILITY_SPECIFIED (decl) = 1;
5446
  call = build_function_call_expr (decl, arglist);
5447
 
5448
  return expand_call (call, target, ignore);
5449
}
5450
 
5451
 
5452
/* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5453
   the pointer in these functions is void*, the tree optimizers may remove
5454
   casts.  The mode computed in expand_builtin isn't reliable either, due
5455
   to __sync_bool_compare_and_swap.
5456
 
5457
   FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5458
   group of builtins.  This gives us log2 of the mode size.  */
5459
 
5460
static inline enum machine_mode
5461
get_builtin_sync_mode (int fcode_diff)
5462
{
5463
  /* The size is not negotiable, so ask not to get BLKmode in return
5464
     if the target indicates that a smaller size would be better.  */
5465
  return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5466
}
5467
 
5468
/* Expand the memory expression LOC and return the appropriate memory operand
5469
   for the builtin_sync operations.  */
5470
 
5471
static rtx
5472
get_builtin_sync_mem (tree loc, enum machine_mode mode)
5473
{
5474
  rtx addr, mem;
5475
 
5476
  addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5477
 
5478
  /* Note that we explicitly do not want any alias information for this
5479
     memory, so that we kill all other live memories.  Otherwise we don't
5480
     satisfy the full barrier semantics of the intrinsic.  */
5481
  mem = validize_mem (gen_rtx_MEM (mode, addr));
5482
 
5483
  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5484
  set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5485
  MEM_VOLATILE_P (mem) = 1;
5486
 
5487
  return mem;
5488
}
5489
 
5490
/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5491
   ARGLIST is the operands list to the function.  CODE is the rtx code
5492
   that corresponds to the arithmetic or logical operation from the name;
5493
   an exception here is that NOT actually means NAND.  TARGET is an optional
5494
   place for us to store the results; AFTER is true if this is the
5495
   fetch_and_xxx form.  IGNORE is true if we don't actually care about
5496
   the result of the operation at all.  */
5497
 
5498
static rtx
5499
expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5500
                               enum rtx_code code, bool after,
5501
                               rtx target, bool ignore)
5502
{
5503
  rtx val, mem;
5504
 
5505
  /* Expand the operands.  */
5506
  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5507
 
5508
  arglist = TREE_CHAIN (arglist);
5509
  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5510
 
5511
  if (ignore)
5512
    return expand_sync_operation (mem, val, code);
5513
  else
5514
    return expand_sync_fetch_operation (mem, val, code, after, target);
5515
}
5516
 
5517
/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5518
   intrinsics.  ARGLIST is the operands list to the function.  IS_BOOL is
5519
   true if this is the boolean form.  TARGET is a place for us to store the
5520
   results; this is NOT optional if IS_BOOL is true.  */
5521
 
5522
static rtx
5523
expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5524
                                 bool is_bool, rtx target)
5525
{
5526
  rtx old_val, new_val, mem;
5527
 
5528
  /* Expand the operands.  */
5529
  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5530
 
5531
  arglist = TREE_CHAIN (arglist);
5532
  old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5533
 
5534
  arglist = TREE_CHAIN (arglist);
5535
  new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5536
 
5537
  if (is_bool)
5538
    return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5539
  else
5540
    return expand_val_compare_and_swap (mem, old_val, new_val, target);
5541
}
5542
 
5543
/* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5544
   general form is actually an atomic exchange, and some targets only
5545
   support a reduced form with the second argument being a constant 1.
5546
   ARGLIST is the operands list to the function; TARGET is an optional
5547
   place for us to store the results.  */
5548
 
5549
static rtx
5550
expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5551
                                  rtx target)
5552
{
5553
  rtx val, mem;
5554
 
5555
  /* Expand the operands.  */
5556
  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5557
 
5558
  arglist = TREE_CHAIN (arglist);
5559
  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5560
 
5561
  return expand_sync_lock_test_and_set (mem, val, target);
5562
}
5563
 
5564
/* Expand the __sync_synchronize intrinsic.  */
5565
 
5566
static void
5567
expand_builtin_synchronize (void)
5568
{
5569
  tree x;
5570
 
5571
#ifdef HAVE_memory_barrier
5572
  if (HAVE_memory_barrier)
5573
    {
5574
      emit_insn (gen_memory_barrier ());
5575
      return;
5576
    }
5577
#endif
5578
 
5579
  /* If no explicit memory barrier instruction is available, create an
5580
     empty asm stmt with a memory clobber.  */
5581
  x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5582
              tree_cons (NULL, build_string (6, "memory"), NULL));
5583
  ASM_VOLATILE_P (x) = 1;
5584
  expand_asm_expr (x);
5585
}
5586
 
5587
/* Expand the __sync_lock_release intrinsic.  ARGLIST is the operands list
5588
   to the function.  */
5589
 
5590
static void
5591
expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5592
{
5593
  enum insn_code icode;
5594
  rtx mem, insn;
5595
  rtx val = const0_rtx;
5596
 
5597
  /* Expand the operands.  */
5598
  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5599
 
5600
  /* If there is an explicit operation in the md file, use it.  */
5601
  icode = sync_lock_release[mode];
5602
  if (icode != CODE_FOR_nothing)
5603
    {
5604
      if (!insn_data[icode].operand[1].predicate (val, mode))
5605
        val = force_reg (mode, val);
5606
 
5607
      insn = GEN_FCN (icode) (mem, val);
5608
      if (insn)
5609
        {
5610
          emit_insn (insn);
5611
          return;
5612
        }
5613
    }
5614
 
5615
  /* Otherwise we can implement this operation by emitting a barrier
5616
     followed by a store of zero.  */
5617
  expand_builtin_synchronize ();
5618
  emit_move_insn (mem, val);
5619
}
5620
 
5621
/* Expand an expression EXP that calls a built-in function,
5622
   with result going to TARGET if that's convenient
5623
   (and in mode MODE if that's convenient).
5624
   SUBTARGET may be used as the target for computing one of EXP's operands.
5625
   IGNORE is nonzero if the value is to be ignored.  */
5626
 
5627
rtx
5628
expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5629
                int ignore)
5630
{
5631
  tree fndecl = get_callee_fndecl (exp);
5632
  tree arglist = TREE_OPERAND (exp, 1);
5633
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5634
  enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5635
 
5636
  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5637
    return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5638
 
5639
  /* When not optimizing, generate calls to library functions for a certain
5640
     set of builtins.  */
5641
  if (!optimize
5642
      && !called_as_built_in (fndecl)
5643
      && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5644
      && fcode != BUILT_IN_ALLOCA)
5645
    return expand_call (exp, target, ignore);
5646
 
5647
  /* The built-in function expanders test for target == const0_rtx
5648
     to determine whether the function's result will be ignored.  */
5649
  if (ignore)
5650
    target = const0_rtx;
5651
 
5652
  /* If the result of a pure or const built-in function is ignored, and
5653
     none of its arguments are volatile, we can avoid expanding the
5654
     built-in call and just evaluate the arguments for side-effects.  */
5655
  if (target == const0_rtx
5656
      && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5657
    {
5658
      bool volatilep = false;
5659
      tree arg;
5660
 
5661
      for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5662
        if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5663
          {
5664
            volatilep = true;
5665
            break;
5666
          }
5667
 
5668
      if (! volatilep)
5669
        {
5670
          for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5671
            expand_expr (TREE_VALUE (arg), const0_rtx,
5672
                         VOIDmode, EXPAND_NORMAL);
5673
          return const0_rtx;
5674
        }
5675
    }
5676
 
5677
  switch (fcode)
5678
    {
5679
    case BUILT_IN_FABS:
5680
    case BUILT_IN_FABSF:
5681
    case BUILT_IN_FABSL:
5682
      target = expand_builtin_fabs (arglist, target, subtarget);
5683
      if (target)
5684
        return target;
5685
      break;
5686
 
5687
    case BUILT_IN_COPYSIGN:
5688
    case BUILT_IN_COPYSIGNF:
5689
    case BUILT_IN_COPYSIGNL:
5690
      target = expand_builtin_copysign (arglist, target, subtarget);
5691
      if (target)
5692
        return target;
5693
      break;
5694
 
5695
      /* Just do a normal library call if we were unable to fold
5696
         the values.  */
5697
    case BUILT_IN_CABS:
5698
    case BUILT_IN_CABSF:
5699
    case BUILT_IN_CABSL:
5700
      break;
5701
 
5702
    case BUILT_IN_EXP:
5703
    case BUILT_IN_EXPF:
5704
    case BUILT_IN_EXPL:
5705
    case BUILT_IN_EXP10:
5706
    case BUILT_IN_EXP10F:
5707
    case BUILT_IN_EXP10L:
5708
    case BUILT_IN_POW10:
5709
    case BUILT_IN_POW10F:
5710
    case BUILT_IN_POW10L:
5711
    case BUILT_IN_EXP2:
5712
    case BUILT_IN_EXP2F:
5713
    case BUILT_IN_EXP2L:
5714
    case BUILT_IN_EXPM1:
5715
    case BUILT_IN_EXPM1F:
5716
    case BUILT_IN_EXPM1L:
5717
    case BUILT_IN_LOGB:
5718
    case BUILT_IN_LOGBF:
5719
    case BUILT_IN_LOGBL:
5720
    case BUILT_IN_ILOGB:
5721
    case BUILT_IN_ILOGBF:
5722
    case BUILT_IN_ILOGBL:
5723
    case BUILT_IN_LOG:
5724
    case BUILT_IN_LOGF:
5725
    case BUILT_IN_LOGL:
5726
    case BUILT_IN_LOG10:
5727
    case BUILT_IN_LOG10F:
5728
    case BUILT_IN_LOG10L:
5729
    case BUILT_IN_LOG2:
5730
    case BUILT_IN_LOG2F:
5731
    case BUILT_IN_LOG2L:
5732
    case BUILT_IN_LOG1P:
5733
    case BUILT_IN_LOG1PF:
5734
    case BUILT_IN_LOG1PL:
5735
    case BUILT_IN_TAN:
5736
    case BUILT_IN_TANF:
5737
    case BUILT_IN_TANL:
5738
    case BUILT_IN_ASIN:
5739
    case BUILT_IN_ASINF:
5740
    case BUILT_IN_ASINL:
5741
    case BUILT_IN_ACOS:
5742
    case BUILT_IN_ACOSF:
5743
    case BUILT_IN_ACOSL:
5744
    case BUILT_IN_ATAN:
5745
    case BUILT_IN_ATANF:
5746
    case BUILT_IN_ATANL:
5747
      /* Treat these like sqrt only if unsafe math optimizations are allowed,
5748
         because of possible accuracy problems.  */
5749
      if (! flag_unsafe_math_optimizations)
5750
        break;
5751
    case BUILT_IN_SQRT:
5752
    case BUILT_IN_SQRTF:
5753
    case BUILT_IN_SQRTL:
5754
    case BUILT_IN_FLOOR:
5755
    case BUILT_IN_FLOORF:
5756
    case BUILT_IN_FLOORL:
5757
    case BUILT_IN_CEIL:
5758
    case BUILT_IN_CEILF:
5759
    case BUILT_IN_CEILL:
5760
    case BUILT_IN_TRUNC:
5761
    case BUILT_IN_TRUNCF:
5762
    case BUILT_IN_TRUNCL:
5763
    case BUILT_IN_ROUND:
5764
    case BUILT_IN_ROUNDF:
5765
    case BUILT_IN_ROUNDL:
5766
    case BUILT_IN_NEARBYINT:
5767
    case BUILT_IN_NEARBYINTF:
5768
    case BUILT_IN_NEARBYINTL:
5769
    case BUILT_IN_RINT:
5770
    case BUILT_IN_RINTF:
5771
    case BUILT_IN_RINTL:
5772
    case BUILT_IN_LRINT:
5773
    case BUILT_IN_LRINTF:
5774
    case BUILT_IN_LRINTL:
5775
    case BUILT_IN_LLRINT:
5776
    case BUILT_IN_LLRINTF:
5777
    case BUILT_IN_LLRINTL:
5778
      target = expand_builtin_mathfn (exp, target, subtarget);
5779
      if (target)
5780
        return target;
5781
      break;
5782
 
5783
    case BUILT_IN_LCEIL:
5784
    case BUILT_IN_LCEILF:
5785
    case BUILT_IN_LCEILL:
5786
    case BUILT_IN_LLCEIL:
5787
    case BUILT_IN_LLCEILF:
5788
    case BUILT_IN_LLCEILL:
5789
    case BUILT_IN_LFLOOR:
5790
    case BUILT_IN_LFLOORF:
5791
    case BUILT_IN_LFLOORL:
5792
    case BUILT_IN_LLFLOOR:
5793
    case BUILT_IN_LLFLOORF:
5794
    case BUILT_IN_LLFLOORL:
5795
      target = expand_builtin_int_roundingfn (exp, target, subtarget);
5796
      if (target)
5797
        return target;
5798
      break;
5799
 
5800
    case BUILT_IN_POW:
5801
    case BUILT_IN_POWF:
5802
    case BUILT_IN_POWL:
5803
      target = expand_builtin_pow (exp, target, subtarget);
5804
      if (target)
5805
        return target;
5806
      break;
5807
 
5808
    case BUILT_IN_POWI:
5809
    case BUILT_IN_POWIF:
5810
    case BUILT_IN_POWIL:
5811
      target = expand_builtin_powi (exp, target, subtarget);
5812
      if (target)
5813
        return target;
5814
      break;
5815
 
5816
    case BUILT_IN_ATAN2:
5817
    case BUILT_IN_ATAN2F:
5818
    case BUILT_IN_ATAN2L:
5819
    case BUILT_IN_LDEXP:
5820
    case BUILT_IN_LDEXPF:
5821
    case BUILT_IN_LDEXPL:
5822
    case BUILT_IN_FMOD:
5823
    case BUILT_IN_FMODF:
5824
    case BUILT_IN_FMODL:
5825
    case BUILT_IN_DREM:
5826
    case BUILT_IN_DREMF:
5827
    case BUILT_IN_DREML:
5828
      if (! flag_unsafe_math_optimizations)
5829
        break;
5830
      target = expand_builtin_mathfn_2 (exp, target, subtarget);
5831
      if (target)
5832
        return target;
5833
      break;
5834
 
5835
    case BUILT_IN_SIN:
5836
    case BUILT_IN_SINF:
5837
    case BUILT_IN_SINL:
5838
    case BUILT_IN_COS:
5839
    case BUILT_IN_COSF:
5840
    case BUILT_IN_COSL:
5841
      if (! flag_unsafe_math_optimizations)
5842
        break;
5843
      target = expand_builtin_mathfn_3 (exp, target, subtarget);
5844
      if (target)
5845
        return target;
5846
      break;
5847
 
5848
    case BUILT_IN_APPLY_ARGS:
5849
      return expand_builtin_apply_args ();
5850
 
5851
      /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5852
         FUNCTION with a copy of the parameters described by
5853
         ARGUMENTS, and ARGSIZE.  It returns a block of memory
5854
         allocated on the stack into which is stored all the registers
5855
         that might possibly be used for returning the result of a
5856
         function.  ARGUMENTS is the value returned by
5857
         __builtin_apply_args.  ARGSIZE is the number of bytes of
5858
         arguments that must be copied.  ??? How should this value be
5859
         computed?  We'll also need a safe worst case value for varargs
5860
         functions.  */
5861
    case BUILT_IN_APPLY:
5862
      if (!validate_arglist (arglist, POINTER_TYPE,
5863
                             POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5864
          && !validate_arglist (arglist, REFERENCE_TYPE,
5865
                                POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5866
        return const0_rtx;
5867
      else
5868
        {
5869
          int i;
5870
          tree t;
5871
          rtx ops[3];
5872
 
5873
          for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5874
            ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5875
 
5876
          return expand_builtin_apply (ops[0], ops[1], ops[2]);
5877
        }
5878
 
5879
      /* __builtin_return (RESULT) causes the function to return the
5880
         value described by RESULT.  RESULT is address of the block of
5881
         memory returned by __builtin_apply.  */
5882
    case BUILT_IN_RETURN:
5883
      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5884
        expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5885
                                            NULL_RTX, VOIDmode, 0));
5886
      return const0_rtx;
5887
 
5888
    case BUILT_IN_SAVEREGS:
5889
      return expand_builtin_saveregs ();
5890
 
5891
    case BUILT_IN_ARGS_INFO:
5892
      return expand_builtin_args_info (arglist);
5893
 
5894
      /* Return the address of the first anonymous stack arg.  */
5895
    case BUILT_IN_NEXT_ARG:
5896
      if (fold_builtin_next_arg (arglist))
5897
        return const0_rtx;
5898
      return expand_builtin_next_arg ();
5899
 
5900
    case BUILT_IN_CLASSIFY_TYPE:
5901
      return expand_builtin_classify_type (arglist);
5902
 
5903
    case BUILT_IN_CONSTANT_P:
5904
      return const0_rtx;
5905
 
5906
    case BUILT_IN_FRAME_ADDRESS:
5907
    case BUILT_IN_RETURN_ADDRESS:
5908
      return expand_builtin_frame_address (fndecl, arglist);
5909
 
5910
    /* Returns the address of the area where the structure is returned.
5911
 
5912
    case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5913
      if (arglist != 0
5914
          || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5915
          || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5916
        return const0_rtx;
5917
      else
5918
        return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5919
 
5920
    case BUILT_IN_ALLOCA:
5921
      target = expand_builtin_alloca (arglist, target);
5922
      if (target)
5923
        return target;
5924
      break;
5925
 
5926
    case BUILT_IN_STACK_SAVE:
5927
      return expand_stack_save ();
5928
 
5929
    case BUILT_IN_STACK_RESTORE:
5930
      expand_stack_restore (TREE_VALUE (arglist));
5931
      return const0_rtx;
5932
 
5933
    case BUILT_IN_FFS:
5934
    case BUILT_IN_FFSL:
5935
    case BUILT_IN_FFSLL:
5936
    case BUILT_IN_FFSIMAX:
5937
      target = expand_builtin_unop (target_mode, arglist, target,
5938
                                    subtarget, ffs_optab);
5939
      if (target)
5940
        return target;
5941
      break;
5942
 
5943
    case BUILT_IN_CLZ:
5944
    case BUILT_IN_CLZL:
5945
    case BUILT_IN_CLZLL:
5946
    case BUILT_IN_CLZIMAX:
5947
      target = expand_builtin_unop (target_mode, arglist, target,
5948
                                    subtarget, clz_optab);
5949
      if (target)
5950
        return target;
5951
      break;
5952
 
5953
    case BUILT_IN_CTZ:
5954
    case BUILT_IN_CTZL:
5955
    case BUILT_IN_CTZLL:
5956
    case BUILT_IN_CTZIMAX:
5957
      target = expand_builtin_unop (target_mode, arglist, target,
5958
                                    subtarget, ctz_optab);
5959
      if (target)
5960
        return target;
5961
      break;
5962
 
5963
    case BUILT_IN_POPCOUNT:
5964
    case BUILT_IN_POPCOUNTL:
5965
    case BUILT_IN_POPCOUNTLL:
5966
    case BUILT_IN_POPCOUNTIMAX:
5967
      target = expand_builtin_unop (target_mode, arglist, target,
5968
                                    subtarget, popcount_optab);
5969
      if (target)
5970
        return target;
5971
      break;
5972
 
5973
    case BUILT_IN_PARITY:
5974
    case BUILT_IN_PARITYL:
5975
    case BUILT_IN_PARITYLL:
5976
    case BUILT_IN_PARITYIMAX:
5977
      target = expand_builtin_unop (target_mode, arglist, target,
5978
                                    subtarget, parity_optab);
5979
      if (target)
5980
        return target;
5981
      break;
5982
 
5983
    case BUILT_IN_STRLEN:
5984
      target = expand_builtin_strlen (arglist, target, target_mode);
5985
      if (target)
5986
        return target;
5987
      break;
5988
 
5989
    case BUILT_IN_STRCPY:
5990
      target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5991
      if (target)
5992
        return target;
5993
      break;
5994
 
5995
    case BUILT_IN_STRNCPY:
5996
      target = expand_builtin_strncpy (exp, target, mode);
5997
      if (target)
5998
        return target;
5999
      break;
6000
 
6001
    case BUILT_IN_STPCPY:
6002
      target = expand_builtin_stpcpy (exp, target, mode);
6003
      if (target)
6004
        return target;
6005
      break;
6006
 
6007
    case BUILT_IN_STRCAT:
6008
      target = expand_builtin_strcat (fndecl, arglist, target, mode);
6009
      if (target)
6010
        return target;
6011
      break;
6012
 
6013
    case BUILT_IN_STRNCAT:
6014
      target = expand_builtin_strncat (arglist, target, mode);
6015
      if (target)
6016
        return target;
6017
      break;
6018
 
6019
    case BUILT_IN_STRSPN:
6020
      target = expand_builtin_strspn (arglist, target, mode);
6021
      if (target)
6022
        return target;
6023
      break;
6024
 
6025
    case BUILT_IN_STRCSPN:
6026
      target = expand_builtin_strcspn (arglist, target, mode);
6027
      if (target)
6028
        return target;
6029
      break;
6030
 
6031
    case BUILT_IN_STRSTR:
6032
      target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6033
      if (target)
6034
        return target;
6035
      break;
6036
 
6037
    case BUILT_IN_STRPBRK:
6038
      target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6039
      if (target)
6040
        return target;
6041
      break;
6042
 
6043
    case BUILT_IN_INDEX:
6044
    case BUILT_IN_STRCHR:
6045
      target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6046
      if (target)
6047
        return target;
6048
      break;
6049
 
6050
    case BUILT_IN_RINDEX:
6051
    case BUILT_IN_STRRCHR:
6052
      target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6053
      if (target)
6054
        return target;
6055
      break;
6056
 
6057
    case BUILT_IN_MEMCPY:
6058
      target = expand_builtin_memcpy (exp, target, mode);
6059
      if (target)
6060
        return target;
6061
      break;
6062
 
6063
    case BUILT_IN_MEMPCPY:
6064
      target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6065
      if (target)
6066
        return target;
6067
      break;
6068
 
6069
    case BUILT_IN_MEMMOVE:
6070
      target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6071
                                       mode, exp);
6072
      if (target)
6073
        return target;
6074
      break;
6075
 
6076
    case BUILT_IN_BCOPY:
6077
      target = expand_builtin_bcopy (exp);
6078
      if (target)
6079
        return target;
6080
      break;
6081
 
6082
    case BUILT_IN_MEMSET:
6083
      target = expand_builtin_memset (arglist, target, mode, exp);
6084
      if (target)
6085
        return target;
6086
      break;
6087
 
6088
    case BUILT_IN_BZERO:
6089
      target = expand_builtin_bzero (exp);
6090
      if (target)
6091
        return target;
6092
      break;
6093
 
6094
    case BUILT_IN_STRCMP:
6095
      target = expand_builtin_strcmp (exp, target, mode);
6096
      if (target)
6097
        return target;
6098
      break;
6099
 
6100
    case BUILT_IN_STRNCMP:
6101
      target = expand_builtin_strncmp (exp, target, mode);
6102
      if (target)
6103
        return target;
6104
      break;
6105
 
6106
    case BUILT_IN_BCMP:
6107
    case BUILT_IN_MEMCMP:
6108
      target = expand_builtin_memcmp (exp, arglist, target, mode);
6109
      if (target)
6110
        return target;
6111
      break;
6112
 
6113
    case BUILT_IN_SETJMP:
6114
      target = expand_builtin_setjmp (arglist, target);
6115
      if (target)
6116
        return target;
6117
      break;
6118
 
6119
      /* __builtin_longjmp is passed a pointer to an array of five words.
6120
         It's similar to the C library longjmp function but works with
6121
         __builtin_setjmp above.  */
6122
    case BUILT_IN_LONGJMP:
6123
      if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6124
        break;
6125
      else
6126
        {
6127
          rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6128
                                      VOIDmode, 0);
6129
          rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6130
                                   NULL_RTX, VOIDmode, 0);
6131
 
6132
          if (value != const1_rtx)
6133
            {
6134
              error ("%<__builtin_longjmp%> second argument must be 1");
6135
              return const0_rtx;
6136
            }
6137
 
6138
          expand_builtin_longjmp (buf_addr, value);
6139
          return const0_rtx;
6140
        }
6141
 
6142
    case BUILT_IN_NONLOCAL_GOTO:
6143
      target = expand_builtin_nonlocal_goto (arglist);
6144
      if (target)
6145
        return target;
6146
      break;
6147
 
6148
      /* This updates the setjmp buffer that is its argument with the value
6149
         of the current stack pointer.  */
6150
    case BUILT_IN_UPDATE_SETJMP_BUF:
6151
      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6152
        {
6153
          rtx buf_addr
6154
            = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6155
 
6156
          expand_builtin_update_setjmp_buf (buf_addr);
6157
          return const0_rtx;
6158
        }
6159
      break;
6160
 
6161
    case BUILT_IN_TRAP:
6162
      expand_builtin_trap ();
6163
      return const0_rtx;
6164
 
6165
    case BUILT_IN_PRINTF:
6166
      target = expand_builtin_printf (exp, target, mode, false);
6167
      if (target)
6168
        return target;
6169
      break;
6170
 
6171
    case BUILT_IN_PRINTF_UNLOCKED:
6172
      target = expand_builtin_printf (exp, target, mode, true);
6173
      if (target)
6174
        return target;
6175
      break;
6176
 
6177
    case BUILT_IN_FPUTS:
6178
      target = expand_builtin_fputs (arglist, target, false);
6179
      if (target)
6180
        return target;
6181
      break;
6182
    case BUILT_IN_FPUTS_UNLOCKED:
6183
      target = expand_builtin_fputs (arglist, target, true);
6184
      if (target)
6185
        return target;
6186
      break;
6187
 
6188
    case BUILT_IN_FPRINTF:
6189
      target = expand_builtin_fprintf (exp, target, mode, false);
6190
      if (target)
6191
        return target;
6192
      break;
6193
 
6194
    case BUILT_IN_FPRINTF_UNLOCKED:
6195
      target = expand_builtin_fprintf (exp, target, mode, true);
6196
      if (target)
6197
        return target;
6198
      break;
6199
 
6200
    case BUILT_IN_SPRINTF:
6201
      target = expand_builtin_sprintf (arglist, target, mode);
6202
      if (target)
6203
        return target;
6204
      break;
6205
 
6206
    case BUILT_IN_SIGNBIT:
6207
    case BUILT_IN_SIGNBITF:
6208
    case BUILT_IN_SIGNBITL:
6209
      target = expand_builtin_signbit (exp, target);
6210
      if (target)
6211
        return target;
6212
      break;
6213
 
6214
      /* Various hooks for the DWARF 2 __throw routine.  */
6215
    case BUILT_IN_UNWIND_INIT:
6216
      expand_builtin_unwind_init ();
6217
      return const0_rtx;
6218
    case BUILT_IN_DWARF_CFA:
6219
      return virtual_cfa_rtx;
6220
#ifdef DWARF2_UNWIND_INFO
6221
    case BUILT_IN_DWARF_SP_COLUMN:
6222
      return expand_builtin_dwarf_sp_column ();
6223
    case BUILT_IN_INIT_DWARF_REG_SIZES:
6224
      expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6225
      return const0_rtx;
6226
#endif
6227
    case BUILT_IN_FROB_RETURN_ADDR:
6228
      return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6229
    case BUILT_IN_EXTRACT_RETURN_ADDR:
6230
      return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6231
    case BUILT_IN_EH_RETURN:
6232
      expand_builtin_eh_return (TREE_VALUE (arglist),
6233
                                TREE_VALUE (TREE_CHAIN (arglist)));
6234
      return const0_rtx;
6235
#ifdef EH_RETURN_DATA_REGNO
6236
    case BUILT_IN_EH_RETURN_DATA_REGNO:
6237
      return expand_builtin_eh_return_data_regno (arglist);
6238
#endif
6239
    case BUILT_IN_EXTEND_POINTER:
6240
      return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6241
 
6242
    case BUILT_IN_VA_START:
6243
    case BUILT_IN_STDARG_START:
6244
      return expand_builtin_va_start (arglist);
6245
    case BUILT_IN_VA_END:
6246
      return expand_builtin_va_end (arglist);
6247
    case BUILT_IN_VA_COPY:
6248
      return expand_builtin_va_copy (arglist);
6249
    case BUILT_IN_EXPECT:
6250
      return expand_builtin_expect (arglist, target);
6251
    case BUILT_IN_PREFETCH:
6252
      expand_builtin_prefetch (arglist);
6253
      return const0_rtx;
6254
 
6255
    case BUILT_IN_PROFILE_FUNC_ENTER:
6256
      return expand_builtin_profile_func (false);
6257
    case BUILT_IN_PROFILE_FUNC_EXIT:
6258
      return expand_builtin_profile_func (true);
6259
 
6260
    case BUILT_IN_INIT_TRAMPOLINE:
6261
      return expand_builtin_init_trampoline (arglist);
6262
    case BUILT_IN_ADJUST_TRAMPOLINE:
6263
      return expand_builtin_adjust_trampoline (arglist);
6264
 
6265
    case BUILT_IN_FORK:
6266
    case BUILT_IN_EXECL:
6267
    case BUILT_IN_EXECV:
6268
    case BUILT_IN_EXECLP:
6269
    case BUILT_IN_EXECLE:
6270
    case BUILT_IN_EXECVP:
6271
    case BUILT_IN_EXECVE:
6272
      target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6273
      if (target)
6274
        return target;
6275
      break;
6276
 
6277
    case BUILT_IN_FETCH_AND_ADD_1:
6278
    case BUILT_IN_FETCH_AND_ADD_2:
6279
    case BUILT_IN_FETCH_AND_ADD_4:
6280
    case BUILT_IN_FETCH_AND_ADD_8:
6281
      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6282
      target = expand_builtin_sync_operation (mode, arglist, PLUS,
6283
                                              false, target, ignore);
6284
      if (target)
6285
        return target;
6286
      break;
6287
 
6288
    case BUILT_IN_FETCH_AND_SUB_1:
6289
    case BUILT_IN_FETCH_AND_SUB_2:
6290
    case BUILT_IN_FETCH_AND_SUB_4:
6291
    case BUILT_IN_FETCH_AND_SUB_8:
6292
      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6293
      target = expand_builtin_sync_operation (mode, arglist, MINUS,
6294
                                              false, target, ignore);
6295
      if (target)
6296
        return target;
6297
      break;
6298
 
6299
    case BUILT_IN_FETCH_AND_OR_1:
6300
    case BUILT_IN_FETCH_AND_OR_2:
6301
    case BUILT_IN_FETCH_AND_OR_4:
6302
    case BUILT_IN_FETCH_AND_OR_8:
6303
      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6304
      target = expand_builtin_sync_operation (mode, arglist, IOR,
6305
                                              false, target, ignore);
6306
      if (target)
6307
        return target;
6308
      break;
6309
 
6310
    case BUILT_IN_FETCH_AND_AND_1:
6311
    case BUILT_IN_FETCH_AND_AND_2:
6312
    case BUILT_IN_FETCH_AND_AND_4:
6313
    case BUILT_IN_FETCH_AND_AND_8:
6314
      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6315
      target = expand_builtin_sync_operation (mode, arglist, AND,
6316
                                              false, target, ignore);
6317
      if (target)
6318
        return target;
6319
      break;
6320
 
6321
    case BUILT_IN_FETCH_AND_XOR_1:
6322
    case BUILT_IN_FETCH_AND_XOR_2:
6323
    case BUILT_IN_FETCH_AND_XOR_4:
6324
    case BUILT_IN_FETCH_AND_XOR_8:
6325
      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6326
      target = expand_builtin_sync_operation (mode, arglist, XOR,
6327
                                              false, target, ignore);
6328
      if (target)
6329
        return target;
6330
      break;
6331
 
6332
    case BUILT_IN_FETCH_AND_NAND_1:
6333
    case BUILT_IN_FETCH_AND_NAND_2:
6334
    case BUILT_IN_FETCH_AND_NAND_4:
6335
    case BUILT_IN_FETCH_AND_NAND_8:
6336
      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6337
      target = expand_builtin_sync_operation (mode, arglist, NOT,
6338
                                              false, target, ignore);
6339
      if (target)
6340
        return target;
6341
      break;
6342
 
6343
    case BUILT_IN_ADD_AND_FETCH_1:
6344
    case BUILT_IN_ADD_AND_FETCH_2:
6345
    case BUILT_IN_ADD_AND_FETCH_4:
6346
    case BUILT_IN_ADD_AND_FETCH_8:
6347
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6348
      target = expand_builtin_sync_operation (mode, arglist, PLUS,
6349
                                              true, target, ignore);
6350
      if (target)
6351
        return target;
6352
      break;
6353
 
6354
    case BUILT_IN_SUB_AND_FETCH_1:
6355
    case BUILT_IN_SUB_AND_FETCH_2:
6356
    case BUILT_IN_SUB_AND_FETCH_4:
6357
    case BUILT_IN_SUB_AND_FETCH_8:
6358
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6359
      target = expand_builtin_sync_operation (mode, arglist, MINUS,
6360
                                              true, target, ignore);
6361
      if (target)
6362
        return target;
6363
      break;
6364
 
6365
    case BUILT_IN_OR_AND_FETCH_1:
6366
    case BUILT_IN_OR_AND_FETCH_2:
6367
    case BUILT_IN_OR_AND_FETCH_4:
6368
    case BUILT_IN_OR_AND_FETCH_8:
6369
      mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6370
      target = expand_builtin_sync_operation (mode, arglist, IOR,
6371
                                              true, target, ignore);
6372
      if (target)
6373
        return target;
6374
      break;
6375
 
6376
    case BUILT_IN_AND_AND_FETCH_1:
6377
    case BUILT_IN_AND_AND_FETCH_2:
6378
    case BUILT_IN_AND_AND_FETCH_4:
6379
    case BUILT_IN_AND_AND_FETCH_8:
6380
      mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6381
      target = expand_builtin_sync_operation (mode, arglist, AND,
6382
                                              true, target, ignore);
6383
      if (target)
6384
        return target;
6385
      break;
6386
 
6387
    case BUILT_IN_XOR_AND_FETCH_1:
6388
    case BUILT_IN_XOR_AND_FETCH_2:
6389
    case BUILT_IN_XOR_AND_FETCH_4:
6390
    case BUILT_IN_XOR_AND_FETCH_8:
6391
      mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6392
      target = expand_builtin_sync_operation (mode, arglist, XOR,
6393
                                              true, target, ignore);
6394
      if (target)
6395
        return target;
6396
      break;
6397
 
6398
    case BUILT_IN_NAND_AND_FETCH_1:
6399
    case BUILT_IN_NAND_AND_FETCH_2:
6400
    case BUILT_IN_NAND_AND_FETCH_4:
6401
    case BUILT_IN_NAND_AND_FETCH_8:
6402
      mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6403
      target = expand_builtin_sync_operation (mode, arglist, NOT,
6404
                                              true, target, ignore);
6405
      if (target)
6406
        return target;
6407
      break;
6408
 
6409
    case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6410
    case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6411
    case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6412
    case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6413
      if (mode == VOIDmode)
6414
        mode = TYPE_MODE (boolean_type_node);
6415
      if (!target || !register_operand (target, mode))
6416
        target = gen_reg_rtx (mode);
6417
 
6418
      mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6419
      target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6420
      if (target)
6421
        return target;
6422
      break;
6423
 
6424
    case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6425
    case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6426
    case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6427
    case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6428
      mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6429
      target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6430
      if (target)
6431
        return target;
6432
      break;
6433
 
6434
    case BUILT_IN_LOCK_TEST_AND_SET_1:
6435
    case BUILT_IN_LOCK_TEST_AND_SET_2:
6436
    case BUILT_IN_LOCK_TEST_AND_SET_4:
6437
    case BUILT_IN_LOCK_TEST_AND_SET_8:
6438
      mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6439
      target = expand_builtin_lock_test_and_set (mode, arglist, target);
6440
      if (target)
6441
        return target;
6442
      break;
6443
 
6444
    case BUILT_IN_LOCK_RELEASE_1:
6445
    case BUILT_IN_LOCK_RELEASE_2:
6446
    case BUILT_IN_LOCK_RELEASE_4:
6447
    case BUILT_IN_LOCK_RELEASE_8:
6448
      mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6449
      expand_builtin_lock_release (mode, arglist);
6450
      return const0_rtx;
6451
 
6452
    case BUILT_IN_SYNCHRONIZE:
6453
      expand_builtin_synchronize ();
6454
      return const0_rtx;
6455
 
6456
    case BUILT_IN_OBJECT_SIZE:
6457
      return expand_builtin_object_size (exp);
6458
 
6459
    case BUILT_IN_MEMCPY_CHK:
6460
    case BUILT_IN_MEMPCPY_CHK:
6461
    case BUILT_IN_MEMMOVE_CHK:
6462
    case BUILT_IN_MEMSET_CHK:
6463
      target = expand_builtin_memory_chk (exp, target, mode, fcode);
6464
      if (target)
6465
        return target;
6466
      break;
6467
 
6468
    case BUILT_IN_STRCPY_CHK:
6469
    case BUILT_IN_STPCPY_CHK:
6470
    case BUILT_IN_STRNCPY_CHK:
6471
    case BUILT_IN_STRCAT_CHK:
6472
    case BUILT_IN_SNPRINTF_CHK:
6473
    case BUILT_IN_VSNPRINTF_CHK:
6474
      maybe_emit_chk_warning (exp, fcode);
6475
      break;
6476
 
6477
    case BUILT_IN_SPRINTF_CHK:
6478
    case BUILT_IN_VSPRINTF_CHK:
6479
      maybe_emit_sprintf_chk_warning (exp, fcode);
6480
      break;
6481
 
6482
    default:    /* just do library call, if unknown builtin */
6483
      break;
6484
    }
6485
 
6486
  /* The switch statement above can drop through to cause the function
6487
     to be called normally.  */
6488
  return expand_call (exp, target, ignore);
6489
}
6490
 
6491
/* Determine whether a tree node represents a call to a built-in
6492
   function.  If the tree T is a call to a built-in function with
6493
   the right number of arguments of the appropriate types, return
6494
   the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6495
   Otherwise the return value is END_BUILTINS.  */
6496
 
6497
enum built_in_function
6498
builtin_mathfn_code (tree t)
6499
{
6500
  tree fndecl, arglist, parmlist;
6501
  tree argtype, parmtype;
6502
 
6503
  if (TREE_CODE (t) != CALL_EXPR
6504
      || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6505
    return END_BUILTINS;
6506
 
6507
  fndecl = get_callee_fndecl (t);
6508
  if (fndecl == NULL_TREE
6509
      || TREE_CODE (fndecl) != FUNCTION_DECL
6510
      || ! DECL_BUILT_IN (fndecl)
6511
      || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6512
    return END_BUILTINS;
6513
 
6514
  arglist = TREE_OPERAND (t, 1);
6515
  parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6516
  for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6517
    {
6518
      /* If a function doesn't take a variable number of arguments,
6519
         the last element in the list will have type `void'.  */
6520
      parmtype = TREE_VALUE (parmlist);
6521
      if (VOID_TYPE_P (parmtype))
6522
        {
6523
          if (arglist)
6524
            return END_BUILTINS;
6525
          return DECL_FUNCTION_CODE (fndecl);
6526
        }
6527
 
6528
      if (! arglist)
6529
        return END_BUILTINS;
6530
 
6531
      argtype = TREE_TYPE (TREE_VALUE (arglist));
6532
 
6533
      if (SCALAR_FLOAT_TYPE_P (parmtype))
6534
        {
6535
          if (! SCALAR_FLOAT_TYPE_P (argtype))
6536
            return END_BUILTINS;
6537
        }
6538
      else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6539
        {
6540
          if (! COMPLEX_FLOAT_TYPE_P (argtype))
6541
            return END_BUILTINS;
6542
        }
6543
      else if (POINTER_TYPE_P (parmtype))
6544
        {
6545
          if (! POINTER_TYPE_P (argtype))
6546
            return END_BUILTINS;
6547
        }
6548
      else if (INTEGRAL_TYPE_P (parmtype))
6549
        {
6550
          if (! INTEGRAL_TYPE_P (argtype))
6551
            return END_BUILTINS;
6552
        }
6553
      else
6554
        return END_BUILTINS;
6555
 
6556
      arglist = TREE_CHAIN (arglist);
6557
    }
6558
 
6559
  /* Variable-length argument list.  */
6560
  return DECL_FUNCTION_CODE (fndecl);
6561
}
6562
 
6563
/* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6564
   constant.  ARGLIST is the argument list of the call.  */
6565
 
6566
static tree
6567
fold_builtin_constant_p (tree arglist)
6568
{
6569
  if (arglist == 0)
6570
    return 0;
6571
 
6572
  arglist = TREE_VALUE (arglist);
6573
 
6574
  /* We return 1 for a numeric type that's known to be a constant
6575
     value at compile-time or for an aggregate type that's a
6576
     literal constant.  */
6577
  STRIP_NOPS (arglist);
6578
 
6579
  /* If we know this is a constant, emit the constant of one.  */
6580
  if (CONSTANT_CLASS_P (arglist)
6581
      || (TREE_CODE (arglist) == CONSTRUCTOR
6582
          && TREE_CONSTANT (arglist)))
6583
    return integer_one_node;
6584
  if (TREE_CODE (arglist) == ADDR_EXPR)
6585
    {
6586
       tree op = TREE_OPERAND (arglist, 0);
6587
       if (TREE_CODE (op) == STRING_CST
6588
           || (TREE_CODE (op) == ARRAY_REF
6589
               && integer_zerop (TREE_OPERAND (op, 1))
6590
               && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6591
         return integer_one_node;
6592
    }
6593
 
6594
  /* If this expression has side effects, show we don't know it to be a
6595
     constant.  Likewise if it's a pointer or aggregate type since in
6596
     those case we only want literals, since those are only optimized
6597
     when generating RTL, not later.
6598
     And finally, if we are compiling an initializer, not code, we
6599
     need to return a definite result now; there's not going to be any
6600
     more optimization done.  */
6601
  if (TREE_SIDE_EFFECTS (arglist)
6602
      || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6603
      || POINTER_TYPE_P (TREE_TYPE (arglist))
6604
      || cfun == 0)
6605
    return integer_zero_node;
6606
 
6607
  return 0;
6608
}
6609
 
6610
/* Fold a call to __builtin_expect, if we expect that a comparison against
6611
   the argument will fold to a constant.  In practice, this means a true
6612
   constant or the address of a non-weak symbol.  ARGLIST is the argument
6613
   list of the call.  */
6614
 
6615
static tree
6616
fold_builtin_expect (tree arglist)
6617
{
6618
  tree arg, inner;
6619
 
6620
  if (arglist == 0)
6621
    return 0;
6622
 
6623
  arg = TREE_VALUE (arglist);
6624
 
6625
  /* If the argument isn't invariant, then there's nothing we can do.  */
6626
  if (!TREE_INVARIANT (arg))
6627
    return 0;
6628
 
6629
  /* If we're looking at an address of a weak decl, then do not fold.  */
6630
  inner = arg;
6631
  STRIP_NOPS (inner);
6632
  if (TREE_CODE (inner) == ADDR_EXPR)
6633
    {
6634
      do
6635
        {
6636
          inner = TREE_OPERAND (inner, 0);
6637
        }
6638
      while (TREE_CODE (inner) == COMPONENT_REF
6639
             || TREE_CODE (inner) == ARRAY_REF);
6640
      if (DECL_P (inner) && DECL_WEAK (inner))
6641
        return 0;
6642
    }
6643
 
6644
  /* Otherwise, ARG already has the proper type for the return value.  */
6645
  return arg;
6646
}
6647
 
6648
/* Fold a call to __builtin_classify_type.  */
6649
 
6650
static tree
6651
fold_builtin_classify_type (tree arglist)
6652
{
6653
  if (arglist == 0)
6654
    return build_int_cst (NULL_TREE, no_type_class);
6655
 
6656
  return build_int_cst (NULL_TREE,
6657
                        type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6658
}
6659
 
6660
/* Fold a call to __builtin_strlen.  */
6661
 
6662
static tree
6663
fold_builtin_strlen (tree arglist)
6664
{
6665
  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6666
    return NULL_TREE;
6667
  else
6668
    {
6669
      tree len = c_strlen (TREE_VALUE (arglist), 0);
6670
 
6671
      if (len)
6672
        {
6673
          /* Convert from the internal "sizetype" type to "size_t".  */
6674
          if (size_type_node)
6675
            len = fold_convert (size_type_node, len);
6676
          return len;
6677
        }
6678
 
6679
      return NULL_TREE;
6680
    }
6681
}
6682
 
6683
/* Fold a call to __builtin_inf or __builtin_huge_val.  */
6684
 
6685
static tree
6686
fold_builtin_inf (tree type, int warn)
6687
{
6688
  REAL_VALUE_TYPE real;
6689
 
6690
  /* __builtin_inff is intended to be usable to define INFINITY on all
6691
     targets.  If an infinity is not available, INFINITY expands "to a
6692
     positive constant of type float that overflows at translation
6693
     time", footnote "In this case, using INFINITY will violate the
6694
     constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6695
     Thus we pedwarn to ensure this constraint violation is
6696
     diagnosed.  */
6697
  if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6698
    pedwarn ("target format does not support infinity");
6699
 
6700
  real_inf (&real);
6701
  return build_real (type, real);
6702
}
6703
 
6704
/* Fold a call to __builtin_nan or __builtin_nans.  */
6705
 
6706
static tree
6707
fold_builtin_nan (tree arglist, tree type, int quiet)
6708
{
6709
  REAL_VALUE_TYPE real;
6710
  const char *str;
6711
 
6712
  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6713
    return 0;
6714
  str = c_getstr (TREE_VALUE (arglist));
6715
  if (!str)
6716
    return 0;
6717
 
6718
  if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6719
    return 0;
6720
 
6721
  return build_real (type, real);
6722
}
6723
 
6724
/* Return true if the floating point expression T has an integer value.
6725
   We also allow +Inf, -Inf and NaN to be considered integer values.  */
6726
 
6727
static bool
6728
integer_valued_real_p (tree t)
6729
{
6730
  switch (TREE_CODE (t))
6731
    {
6732
    case FLOAT_EXPR:
6733
      return true;
6734
 
6735
    case ABS_EXPR:
6736
    case SAVE_EXPR:
6737
    case NON_LVALUE_EXPR:
6738
      return integer_valued_real_p (TREE_OPERAND (t, 0));
6739
 
6740
    case COMPOUND_EXPR:
6741
    case MODIFY_EXPR:
6742
    case BIND_EXPR:
6743
      return integer_valued_real_p (TREE_OPERAND (t, 1));
6744
 
6745
    case PLUS_EXPR:
6746
    case MINUS_EXPR:
6747
    case MULT_EXPR:
6748
    case MIN_EXPR:
6749
    case MAX_EXPR:
6750
      return integer_valued_real_p (TREE_OPERAND (t, 0))
6751
             && integer_valued_real_p (TREE_OPERAND (t, 1));
6752
 
6753
    case COND_EXPR:
6754
      return integer_valued_real_p (TREE_OPERAND (t, 1))
6755
             && integer_valued_real_p (TREE_OPERAND (t, 2));
6756
 
6757
    case REAL_CST:
6758
      if (! TREE_CONSTANT_OVERFLOW (t))
6759
      {
6760
        REAL_VALUE_TYPE c, cint;
6761
 
6762
        c = TREE_REAL_CST (t);
6763
        real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6764
        return real_identical (&c, &cint);
6765
      }
6766
      break;
6767
 
6768
    case NOP_EXPR:
6769
      {
6770
        tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6771
        if (TREE_CODE (type) == INTEGER_TYPE)
6772
          return true;
6773
        if (TREE_CODE (type) == REAL_TYPE)
6774
          return integer_valued_real_p (TREE_OPERAND (t, 0));
6775
        break;
6776
      }
6777
 
6778
    case CALL_EXPR:
6779
      switch (builtin_mathfn_code (t))
6780
        {
6781
        case BUILT_IN_CEIL:
6782
        case BUILT_IN_CEILF:
6783
        case BUILT_IN_CEILL:
6784
        case BUILT_IN_FLOOR:
6785
        case BUILT_IN_FLOORF:
6786
        case BUILT_IN_FLOORL:
6787
        case BUILT_IN_NEARBYINT:
6788
        case BUILT_IN_NEARBYINTF:
6789
        case BUILT_IN_NEARBYINTL:
6790
        case BUILT_IN_RINT:
6791
        case BUILT_IN_RINTF:
6792
        case BUILT_IN_RINTL:
6793
        case BUILT_IN_ROUND:
6794
        case BUILT_IN_ROUNDF:
6795
        case BUILT_IN_ROUNDL:
6796
        case BUILT_IN_TRUNC:
6797
        case BUILT_IN_TRUNCF:
6798
        case BUILT_IN_TRUNCL:
6799
          return true;
6800
 
6801
        default:
6802
          break;
6803
        }
6804
      break;
6805
 
6806
    default:
6807
      break;
6808
    }
6809
  return false;
6810
}
6811
 
6812
/* EXP is assumed to be builtin call where truncation can be propagated
6813
   across (for instance floor((double)f) == (double)floorf (f).
6814
   Do the transformation.  */
6815
 
6816
static tree
6817
fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6818
{
6819
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6820
  tree arg;
6821
 
6822
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6823
    return 0;
6824
 
6825
  arg = TREE_VALUE (arglist);
6826
  /* Integer rounding functions are idempotent.  */
6827
  if (fcode == builtin_mathfn_code (arg))
6828
    return arg;
6829
 
6830
  /* If argument is already integer valued, and we don't need to worry
6831
     about setting errno, there's no need to perform rounding.  */
6832
  if (! flag_errno_math && integer_valued_real_p (arg))
6833
    return arg;
6834
 
6835
  if (optimize)
6836
    {
6837
      tree arg0 = strip_float_extensions (arg);
6838
      tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6839
      tree newtype = TREE_TYPE (arg0);
6840
      tree decl;
6841
 
6842
      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6843
          && (decl = mathfn_built_in (newtype, fcode)))
6844
        {
6845
          arglist =
6846
            build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6847
          return fold_convert (ftype,
6848
                               build_function_call_expr (decl, arglist));
6849
        }
6850
    }
6851
  return 0;
6852
}
6853
 
6854
/* EXP is assumed to be builtin call which can narrow the FP type of
6855
   the argument, for instance lround((double)f) -> lroundf (f).  */
6856
 
6857
static tree
6858
fold_fixed_mathfn (tree fndecl, tree arglist)
6859
{
6860
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6861
  tree arg;
6862
 
6863
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6864
    return 0;
6865
 
6866
  arg = TREE_VALUE (arglist);
6867
 
6868
  /* If argument is already integer valued, and we don't need to worry
6869
     about setting errno, there's no need to perform rounding.  */
6870
  if (! flag_errno_math && integer_valued_real_p (arg))
6871
    return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6872
 
6873
  if (optimize)
6874
    {
6875
      tree ftype = TREE_TYPE (arg);
6876
      tree arg0 = strip_float_extensions (arg);
6877
      tree newtype = TREE_TYPE (arg0);
6878
      tree decl;
6879
 
6880
      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6881
          && (decl = mathfn_built_in (newtype, fcode)))
6882
        {
6883
          arglist =
6884
            build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6885
          return build_function_call_expr (decl, arglist);
6886
        }
6887
    }
6888
  return 0;
6889
}
6890
 
6891
/* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6892
   is the argument list and TYPE is the return type.  Return
6893
   NULL_TREE if no if no simplification can be made.  */
6894
 
6895
static tree
6896
fold_builtin_cabs (tree arglist, tree type)
6897
{
6898
  tree arg;
6899
 
6900
  if (!arglist || TREE_CHAIN (arglist))
6901
    return NULL_TREE;
6902
 
6903
  arg = TREE_VALUE (arglist);
6904
  if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6905
      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6906
    return NULL_TREE;
6907
 
6908
  /* Evaluate cabs of a constant at compile-time.  */
6909
  if (flag_unsafe_math_optimizations
6910
      && TREE_CODE (arg) == COMPLEX_CST
6911
      && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6912
      && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6913
      && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6914
      && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6915
    {
6916
      REAL_VALUE_TYPE r, i;
6917
 
6918
      r = TREE_REAL_CST (TREE_REALPART (arg));
6919
      i = TREE_REAL_CST (TREE_IMAGPART (arg));
6920
 
6921
      real_arithmetic (&r, MULT_EXPR, &r, &r);
6922
      real_arithmetic (&i, MULT_EXPR, &i, &i);
6923
      real_arithmetic (&r, PLUS_EXPR, &r, &i);
6924
      if (real_sqrt (&r, TYPE_MODE (type), &r)
6925
          || ! flag_trapping_math)
6926
        return build_real (type, r);
6927
    }
6928
 
6929
  /* If either part is zero, cabs is fabs of the other.  */
6930
  if (TREE_CODE (arg) == COMPLEX_EXPR
6931
      && real_zerop (TREE_OPERAND (arg, 0)))
6932
    return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6933
  if (TREE_CODE (arg) == COMPLEX_EXPR
6934
      && real_zerop (TREE_OPERAND (arg, 1)))
6935
    return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6936
 
6937
  /* Don't do this when optimizing for size.  */
6938
  if (flag_unsafe_math_optimizations
6939
      && optimize && !optimize_size)
6940
    {
6941
      tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6942
 
6943
      if (sqrtfn != NULL_TREE)
6944
        {
6945
          tree rpart, ipart, result, arglist;
6946
 
6947
          arg = builtin_save_expr (arg);
6948
 
6949
          rpart = fold_build1 (REALPART_EXPR, type, arg);
6950
          ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6951
 
6952
          rpart = builtin_save_expr (rpart);
6953
          ipart = builtin_save_expr (ipart);
6954
 
6955
          result = fold_build2 (PLUS_EXPR, type,
6956
                                fold_build2 (MULT_EXPR, type,
6957
                                             rpart, rpart),
6958
                                fold_build2 (MULT_EXPR, type,
6959
                                             ipart, ipart));
6960
 
6961
          arglist = build_tree_list (NULL_TREE, result);
6962
          return build_function_call_expr (sqrtfn, arglist);
6963
        }
6964
    }
6965
 
6966
  return NULL_TREE;
6967
}
6968
 
6969
/* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6970
   NULL_TREE if no simplification can be made.  */
6971
 
6972
static tree
6973
fold_builtin_sqrt (tree arglist, tree type)
6974
{
6975
 
6976
  enum built_in_function fcode;
6977
  tree arg = TREE_VALUE (arglist);
6978
 
6979
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6980
    return NULL_TREE;
6981
 
6982
  /* Optimize sqrt of constant value.  */
6983
  if (TREE_CODE (arg) == REAL_CST
6984
      && ! TREE_CONSTANT_OVERFLOW (arg))
6985
    {
6986
      REAL_VALUE_TYPE r, x;
6987
 
6988
      x = TREE_REAL_CST (arg);
6989
      if (real_sqrt (&r, TYPE_MODE (type), &x)
6990
          || (!flag_trapping_math && !flag_errno_math))
6991
        return build_real (type, r);
6992
    }
6993
 
6994
  /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6995
  fcode = builtin_mathfn_code (arg);
6996
  if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6997
    {
6998
      tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6999
      arg = fold_build2 (MULT_EXPR, type,
7000
                         TREE_VALUE (TREE_OPERAND (arg, 1)),
7001
                         build_real (type, dconsthalf));
7002
      arglist = build_tree_list (NULL_TREE, arg);
7003
      return build_function_call_expr (expfn, arglist);
7004
    }
7005
 
7006
  /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7007
  if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7008
    {
7009
      tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7010
 
7011
      if (powfn)
7012
        {
7013
          tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7014
          tree tree_root;
7015
          /* The inner root was either sqrt or cbrt.  */
7016
          REAL_VALUE_TYPE dconstroot =
7017
            BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7018
 
7019
          /* Adjust for the outer root.  */
7020
          SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7021
          dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7022
          tree_root = build_real (type, dconstroot);
7023
          arglist = tree_cons (NULL_TREE, arg0,
7024
                               build_tree_list (NULL_TREE, tree_root));
7025
          return build_function_call_expr (powfn, arglist);
7026
        }
7027
    }
7028
 
7029
  /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7030
  if (flag_unsafe_math_optimizations
7031
      && (fcode == BUILT_IN_POW
7032
          || fcode == BUILT_IN_POWF
7033
          || fcode == BUILT_IN_POWL))
7034
    {
7035
      tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7036
      tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7037
      tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7038
      tree narg1;
7039
      if (!tree_expr_nonnegative_p (arg0))
7040
        arg0 = build1 (ABS_EXPR, type, arg0);
7041
      narg1 = fold_build2 (MULT_EXPR, type, arg1,
7042
                           build_real (type, dconsthalf));
7043
      arglist = tree_cons (NULL_TREE, arg0,
7044
                           build_tree_list (NULL_TREE, narg1));
7045
      return build_function_call_expr (powfn, arglist);
7046
    }
7047
 
7048
  return NULL_TREE;
7049
}
7050
 
7051
/* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
7052
   NULL_TREE if no simplification can be made.  */
7053
static tree
7054
fold_builtin_cbrt (tree arglist, tree type)
7055
{
7056
  tree arg = TREE_VALUE (arglist);
7057
  const enum built_in_function fcode = builtin_mathfn_code (arg);
7058
 
7059
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7060
    return NULL_TREE;
7061
 
7062
  /* Optimize cbrt of constant value.  */
7063
  if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7064
    return arg;
7065
 
7066
  if (flag_unsafe_math_optimizations)
7067
    {
7068
      /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7069
      if (BUILTIN_EXPONENT_P (fcode))
7070
        {
7071
          tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7072
          const REAL_VALUE_TYPE third_trunc =
7073
            real_value_truncate (TYPE_MODE (type), dconstthird);
7074
          arg = fold_build2 (MULT_EXPR, type,
7075
                             TREE_VALUE (TREE_OPERAND (arg, 1)),
7076
                             build_real (type, third_trunc));
7077
          arglist = build_tree_list (NULL_TREE, arg);
7078
          return build_function_call_expr (expfn, arglist);
7079
        }
7080
 
7081
      /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7082
      if (BUILTIN_SQRT_P (fcode))
7083
        {
7084
          tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7085
 
7086
          if (powfn)
7087
            {
7088
              tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7089
              tree tree_root;
7090
              REAL_VALUE_TYPE dconstroot = dconstthird;
7091
 
7092
              SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7093
              dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7094
              tree_root = build_real (type, dconstroot);
7095
              arglist = tree_cons (NULL_TREE, arg0,
7096
                                   build_tree_list (NULL_TREE, tree_root));
7097
              return build_function_call_expr (powfn, arglist);
7098
            }
7099
        }
7100
 
7101
      /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7102
      if (BUILTIN_CBRT_P (fcode))
7103
        {
7104
          tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7105
          if (tree_expr_nonnegative_p (arg0))
7106
            {
7107
              tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7108
 
7109
              if (powfn)
7110
                {
7111
                  tree tree_root;
7112
                  REAL_VALUE_TYPE dconstroot;
7113
 
7114
                  real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7115
                  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7116
                  tree_root = build_real (type, dconstroot);
7117
                  arglist = tree_cons (NULL_TREE, arg0,
7118
                                       build_tree_list (NULL_TREE, tree_root));
7119
                  return build_function_call_expr (powfn, arglist);
7120
                }
7121
            }
7122
        }
7123
 
7124
      /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7125
      if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7126
          || fcode == BUILT_IN_POWL)
7127
        {
7128
          tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7129
          tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7130
          if (tree_expr_nonnegative_p (arg00))
7131
            {
7132
              tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7133
              const REAL_VALUE_TYPE dconstroot
7134
                = real_value_truncate (TYPE_MODE (type), dconstthird);
7135
              tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7136
                                         build_real (type, dconstroot));
7137
              arglist = tree_cons (NULL_TREE, arg00,
7138
                                   build_tree_list (NULL_TREE, narg01));
7139
              return build_function_call_expr (powfn, arglist);
7140
            }
7141
        }
7142
    }
7143
  return NULL_TREE;
7144
}
7145
 
7146
/* Fold function call to builtin sin, sinf, or sinl.  Return
7147
   NULL_TREE if no simplification can be made.  */
7148
static tree
7149
fold_builtin_sin (tree arglist)
7150
{
7151
  tree arg = TREE_VALUE (arglist);
7152
 
7153
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7154
    return NULL_TREE;
7155
 
7156
  /* Optimize sin (0.0) = 0.0.  */
7157
  if (real_zerop (arg))
7158
    return arg;
7159
 
7160
  return NULL_TREE;
7161
}
7162
 
7163
/* Fold function call to builtin cos, cosf, or cosl.  Return
7164
   NULL_TREE if no simplification can be made.  */
7165
static tree
7166
fold_builtin_cos (tree arglist, tree type, tree fndecl)
7167
{
7168
  tree arg = TREE_VALUE (arglist);
7169
 
7170
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7171
    return NULL_TREE;
7172
 
7173
  /* Optimize cos (0.0) = 1.0.  */
7174
  if (real_zerop (arg))
7175
    return build_real (type, dconst1);
7176
 
7177
  /* Optimize cos(-x) into cos (x).  */
7178
  if (TREE_CODE (arg) == NEGATE_EXPR)
7179
    {
7180
      tree args = build_tree_list (NULL_TREE,
7181
                                   TREE_OPERAND (arg, 0));
7182
      return build_function_call_expr (fndecl, args);
7183
    }
7184
 
7185
  return NULL_TREE;
7186
}
7187
 
7188
/* Fold function call to builtin tan, tanf, or tanl.  Return
7189
   NULL_TREE if no simplification can be made.  */
7190
static tree
7191
fold_builtin_tan (tree arglist)
7192
{
7193
  enum built_in_function fcode;
7194
  tree arg = TREE_VALUE (arglist);
7195
 
7196
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7197
    return NULL_TREE;
7198
 
7199
  /* Optimize tan(0.0) = 0.0.  */
7200
  if (real_zerop (arg))
7201
    return arg;
7202
 
7203
  /* Optimize tan(atan(x)) = x.  */
7204
  fcode = builtin_mathfn_code (arg);
7205
  if (flag_unsafe_math_optimizations
7206
      && (fcode == BUILT_IN_ATAN
7207
          || fcode == BUILT_IN_ATANF
7208
          || fcode == BUILT_IN_ATANL))
7209
    return TREE_VALUE (TREE_OPERAND (arg, 1));
7210
 
7211
  return NULL_TREE;
7212
}
7213
 
7214
/* Fold function call to builtin atan, atanf, or atanl.  Return
7215
   NULL_TREE if no simplification can be made.  */
7216
 
7217
static tree
7218
fold_builtin_atan (tree arglist, tree type)
7219
{
7220
 
7221
  tree arg = TREE_VALUE (arglist);
7222
 
7223
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7224
    return NULL_TREE;
7225
 
7226
  /* Optimize atan(0.0) = 0.0.  */
7227
  if (real_zerop (arg))
7228
    return arg;
7229
 
7230
  /* Optimize atan(1.0) = pi/4.  */
7231
  if (real_onep (arg))
7232
    {
7233
      REAL_VALUE_TYPE cst;
7234
 
7235
      real_convert (&cst, TYPE_MODE (type), &dconstpi);
7236
      SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7237
      return build_real (type, cst);
7238
    }
7239
 
7240
  return NULL_TREE;
7241
}
7242
 
7243
/* Fold function call to builtin trunc, truncf or truncl.  Return
7244
   NULL_TREE if no simplification can be made.  */
7245
 
7246
static tree
7247
fold_builtin_trunc (tree fndecl, tree arglist)
7248
{
7249
  tree arg;
7250
 
7251
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7252
    return 0;
7253
 
7254
  /* Optimize trunc of constant value.  */
7255
  arg = TREE_VALUE (arglist);
7256
  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7257
    {
7258
      REAL_VALUE_TYPE r, x;
7259
      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7260
 
7261
      x = TREE_REAL_CST (arg);
7262
      real_trunc (&r, TYPE_MODE (type), &x);
7263
      return build_real (type, r);
7264
    }
7265
 
7266
  return fold_trunc_transparent_mathfn (fndecl, arglist);
7267
}
7268
 
7269
/* Fold function call to builtin floor, floorf or floorl.  Return
7270
   NULL_TREE if no simplification can be made.  */
7271
 
7272
static tree
7273
fold_builtin_floor (tree fndecl, tree arglist)
7274
{
7275
  tree arg;
7276
 
7277
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7278
    return 0;
7279
 
7280
  /* Optimize floor of constant value.  */
7281
  arg = TREE_VALUE (arglist);
7282
  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7283
    {
7284
      REAL_VALUE_TYPE x;
7285
 
7286
      x = TREE_REAL_CST (arg);
7287
      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7288
        {
7289
          tree type = TREE_TYPE (TREE_TYPE (fndecl));
7290
          REAL_VALUE_TYPE r;
7291
 
7292
          real_floor (&r, TYPE_MODE (type), &x);
7293
          return build_real (type, r);
7294
        }
7295
    }
7296
 
7297
  return fold_trunc_transparent_mathfn (fndecl, arglist);
7298
}
7299
 
7300
/* Fold function call to builtin ceil, ceilf or ceill.  Return
7301
   NULL_TREE if no simplification can be made.  */
7302
 
7303
static tree
7304
fold_builtin_ceil (tree fndecl, tree arglist)
7305
{
7306
  tree arg;
7307
 
7308
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7309
    return 0;
7310
 
7311
  /* Optimize ceil of constant value.  */
7312
  arg = TREE_VALUE (arglist);
7313
  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7314
    {
7315
      REAL_VALUE_TYPE x;
7316
 
7317
      x = TREE_REAL_CST (arg);
7318
      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7319
        {
7320
          tree type = TREE_TYPE (TREE_TYPE (fndecl));
7321
          REAL_VALUE_TYPE r;
7322
 
7323
          real_ceil (&r, TYPE_MODE (type), &x);
7324
          return build_real (type, r);
7325
        }
7326
    }
7327
 
7328
  return fold_trunc_transparent_mathfn (fndecl, arglist);
7329
}
7330
 
7331
/* Fold function call to builtin round, roundf or roundl.  Return
7332
   NULL_TREE if no simplification can be made.  */
7333
 
7334
static tree
7335
fold_builtin_round (tree fndecl, tree arglist)
7336
{
7337
  tree arg;
7338
 
7339
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7340
    return 0;
7341
 
7342
  /* Optimize round of constant value.  */
7343
  arg = TREE_VALUE (arglist);
7344
  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7345
    {
7346
      REAL_VALUE_TYPE x;
7347
 
7348
      x = TREE_REAL_CST (arg);
7349
      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7350
        {
7351
          tree type = TREE_TYPE (TREE_TYPE (fndecl));
7352
          REAL_VALUE_TYPE r;
7353
 
7354
          real_round (&r, TYPE_MODE (type), &x);
7355
          return build_real (type, r);
7356
        }
7357
    }
7358
 
7359
  return fold_trunc_transparent_mathfn (fndecl, arglist);
7360
}
7361
 
7362
/* Fold function call to builtin lround, lroundf or lroundl (or the
7363
   corresponding long long versions) and other rounding functions.
7364
   Return NULL_TREE if no simplification can be made.  */
7365
 
7366
static tree
7367
fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7368
{
7369
  tree arg;
7370
 
7371
  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7372
    return 0;
7373
 
7374
  /* Optimize lround of constant value.  */
7375
  arg = TREE_VALUE (arglist);
7376
  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7377
    {
7378
      const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7379
 
7380
      if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7381
        {
7382
          tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7383
          tree ftype = TREE_TYPE (arg), result;
7384
          HOST_WIDE_INT hi, lo;
7385
          REAL_VALUE_TYPE r;
7386
 
7387
          switch (DECL_FUNCTION_CODE (fndecl))
7388
            {
7389
            case BUILT_IN_LFLOOR:
7390
            case BUILT_IN_LFLOORF:
7391
            case BUILT_IN_LFLOORL:
7392
            case BUILT_IN_LLFLOOR:
7393
            case BUILT_IN_LLFLOORF:
7394
            case BUILT_IN_LLFLOORL:
7395
              real_floor (&r, TYPE_MODE (ftype), &x);
7396
              break;
7397
 
7398
            case BUILT_IN_LCEIL:
7399
            case BUILT_IN_LCEILF:
7400
            case BUILT_IN_LCEILL:
7401
            case BUILT_IN_LLCEIL:
7402
            case BUILT_IN_LLCEILF:
7403
            case BUILT_IN_LLCEILL:
7404
              real_ceil (&r, TYPE_MODE (ftype), &x);
7405
              break;
7406
 
7407
            case BUILT_IN_LROUND:
7408
            case BUILT_IN_LROUNDF:
7409
            case BUILT_IN_LROUNDL:
7410
            case BUILT_IN_LLROUND:
7411
            case BUILT_IN_LLROUNDF:
7412
            case BUILT_IN_LLROUNDL:
7413
              real_round (&r, TYPE_MODE (ftype), &x);
7414
              break;
7415
 
7416
            default:
7417
              gcc_unreachable ();
7418
            }
7419
 
7420
          REAL_VALUE_TO_INT (&lo, &hi, r);
7421
          result = build_int_cst_wide (NULL_TREE, lo, hi);
7422
          if (int_fits_type_p (result, itype))
7423
            return fold_convert (itype, result);
7424
        }
7425
    }
7426
 
7427
  return fold_fixed_mathfn (fndecl, arglist);
7428
}
7429
 
7430
/* Fold function call to builtin ffs, clz, ctz, popcount and parity
7431
   and their long and long long variants (i.e. ffsl and ffsll).
7432
   Return NULL_TREE if no simplification can be made.  */
7433
 
7434
static tree
7435
fold_builtin_bitop (tree fndecl, tree arglist)
7436
{
7437
  tree arg;
7438
 
7439
  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7440
    return NULL_TREE;
7441
 
7442
  /* Optimize for constant argument.  */
7443
  arg = TREE_VALUE (arglist);
7444
  if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7445
    {
7446
      HOST_WIDE_INT hi, width, result;
7447
      unsigned HOST_WIDE_INT lo;
7448
      tree type;
7449
 
7450
      type = TREE_TYPE (arg);
7451
      width = TYPE_PRECISION (type);
7452
      lo = TREE_INT_CST_LOW (arg);
7453
 
7454
      /* Clear all the bits that are beyond the type's precision.  */
7455
      if (width > HOST_BITS_PER_WIDE_INT)
7456
        {
7457
          hi = TREE_INT_CST_HIGH (arg);
7458
          if (width < 2 * HOST_BITS_PER_WIDE_INT)
7459
            hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7460
        }
7461
      else
7462
        {
7463
          hi = 0;
7464
          if (width < HOST_BITS_PER_WIDE_INT)
7465
            lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7466
        }
7467
 
7468
      switch (DECL_FUNCTION_CODE (fndecl))
7469
        {
7470
        case BUILT_IN_FFS:
7471
        case BUILT_IN_FFSL:
7472
        case BUILT_IN_FFSLL:
7473
          if (lo != 0)
7474
            result = exact_log2 (lo & -lo) + 1;
7475
          else if (hi != 0)
7476
            result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7477
          else
7478
            result = 0;
7479
          break;
7480
 
7481
        case BUILT_IN_CLZ:
7482
        case BUILT_IN_CLZL:
7483
        case BUILT_IN_CLZLL:
7484
          if (hi != 0)
7485
            result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7486
          else if (lo != 0)
7487
            result = width - floor_log2 (lo) - 1;
7488
          else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7489
            result = width;
7490
          break;
7491
 
7492
        case BUILT_IN_CTZ:
7493
        case BUILT_IN_CTZL:
7494
        case BUILT_IN_CTZLL:
7495
          if (lo != 0)
7496
            result = exact_log2 (lo & -lo);
7497
          else if (hi != 0)
7498
            result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7499
          else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7500
            result = width;
7501
          break;
7502
 
7503
        case BUILT_IN_POPCOUNT:
7504
        case BUILT_IN_POPCOUNTL:
7505
        case BUILT_IN_POPCOUNTLL:
7506
          result = 0;
7507
          while (lo)
7508
            result++, lo &= lo - 1;
7509
          while (hi)
7510
            result++, hi &= hi - 1;
7511
          break;
7512
 
7513
        case BUILT_IN_PARITY:
7514
        case BUILT_IN_PARITYL:
7515
        case BUILT_IN_PARITYLL:
7516
          result = 0;
7517
          while (lo)
7518
            result++, lo &= lo - 1;
7519
          while (hi)
7520
            result++, hi &= hi - 1;
7521
          result &= 1;
7522
          break;
7523
 
7524
        default:
7525
          gcc_unreachable ();
7526
        }
7527
 
7528
      return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7529
    }
7530
 
7531
  return NULL_TREE;
7532
}
7533
 
7534
/* Return true if EXPR is the real constant contained in VALUE.  */
7535
 
7536
static bool
7537
real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7538
{
7539
  STRIP_NOPS (expr);
7540
 
7541
  return ((TREE_CODE (expr) == REAL_CST
7542
           && ! TREE_CONSTANT_OVERFLOW (expr)
7543
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7544
          || (TREE_CODE (expr) == COMPLEX_CST
7545
              && real_dconstp (TREE_REALPART (expr), value)
7546
              && real_zerop (TREE_IMAGPART (expr))));
7547
}
7548
 
7549
/* A subroutine of fold_builtin to fold the various logarithmic
7550
   functions.  EXP is the CALL_EXPR of a call to a builtin logN
7551
   function.  VALUE is the base of the logN function.  */
7552
 
7553
static tree
7554
fold_builtin_logarithm (tree fndecl, tree arglist,
7555
                        const REAL_VALUE_TYPE *value)
7556
{
7557
  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7558
    {
7559
      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7560
      tree arg = TREE_VALUE (arglist);
7561
      const enum built_in_function fcode = builtin_mathfn_code (arg);
7562
 
7563
      /* Optimize logN(1.0) = 0.0.  */
7564
      if (real_onep (arg))
7565
        return build_real (type, dconst0);
7566
 
7567
      /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7568
         exactly, then only do this if flag_unsafe_math_optimizations.  */
7569
      if (exact_real_truncate (TYPE_MODE (type), value)
7570
          || flag_unsafe_math_optimizations)
7571
        {
7572
          const REAL_VALUE_TYPE value_truncate =
7573
            real_value_truncate (TYPE_MODE (type), *value);
7574
          if (real_dconstp (arg, &value_truncate))
7575
            return build_real (type, dconst1);
7576
        }
7577
 
7578
      /* Special case, optimize logN(expN(x)) = x.  */
7579
      if (flag_unsafe_math_optimizations
7580
          && ((value == &dconste
7581
               && (fcode == BUILT_IN_EXP
7582
                   || fcode == BUILT_IN_EXPF
7583
                   || fcode == BUILT_IN_EXPL))
7584
              || (value == &dconst2
7585
                  && (fcode == BUILT_IN_EXP2
7586
                      || fcode == BUILT_IN_EXP2F
7587
                      || fcode == BUILT_IN_EXP2L))
7588
              || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7589
        return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7590
 
7591
      /* Optimize logN(func()) for various exponential functions.  We
7592
         want to determine the value "x" and the power "exponent" in
7593
         order to transform logN(x**exponent) into exponent*logN(x).  */
7594
      if (flag_unsafe_math_optimizations)
7595
        {
7596
          tree exponent = 0, x = 0;
7597
 
7598
          switch (fcode)
7599
          {
7600
          case BUILT_IN_EXP:
7601
          case BUILT_IN_EXPF:
7602
          case BUILT_IN_EXPL:
7603
            /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7604
            x = build_real (type,
7605
                            real_value_truncate (TYPE_MODE (type), dconste));
7606
            exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7607
            break;
7608
          case BUILT_IN_EXP2:
7609
          case BUILT_IN_EXP2F:
7610
          case BUILT_IN_EXP2L:
7611
            /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7612
            x = build_real (type, dconst2);
7613
            exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7614
            break;
7615
          case BUILT_IN_EXP10:
7616
          case BUILT_IN_EXP10F:
7617
          case BUILT_IN_EXP10L:
7618
          case BUILT_IN_POW10:
7619
          case BUILT_IN_POW10F:
7620
          case BUILT_IN_POW10L:
7621
            /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7622
            x = build_real (type, dconst10);
7623
            exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7624
            break;
7625
          case BUILT_IN_SQRT:
7626
          case BUILT_IN_SQRTF:
7627
          case BUILT_IN_SQRTL:
7628
            /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7629
            x = TREE_VALUE (TREE_OPERAND (arg, 1));
7630
            exponent = build_real (type, dconsthalf);
7631
            break;
7632
          case BUILT_IN_CBRT:
7633
          case BUILT_IN_CBRTF:
7634
          case BUILT_IN_CBRTL:
7635
            /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7636
            x = TREE_VALUE (TREE_OPERAND (arg, 1));
7637
            exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7638
                                                              dconstthird));
7639
            break;
7640
          case BUILT_IN_POW:
7641
          case BUILT_IN_POWF:
7642
          case BUILT_IN_POWL:
7643
            /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7644
            x = TREE_VALUE (TREE_OPERAND (arg, 1));
7645
            exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7646
            break;
7647
          default:
7648
            break;
7649
          }
7650
 
7651
          /* Now perform the optimization.  */
7652
          if (x && exponent)
7653
            {
7654
              tree logfn;
7655
              arglist = build_tree_list (NULL_TREE, x);
7656
              logfn = build_function_call_expr (fndecl, arglist);
7657
              return fold_build2 (MULT_EXPR, type, exponent, logfn);
7658
            }
7659
        }
7660
    }
7661
 
7662
  return 0;
7663
}
7664
 
7665
/* Fold a builtin function call to pow, powf, or powl.  Return
7666
   NULL_TREE if no simplification can be made.  */
7667
static tree
7668
fold_builtin_pow (tree fndecl, tree arglist, tree type)
7669
{
7670
  tree arg0 = TREE_VALUE (arglist);
7671
  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7672
 
7673
  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7674
    return NULL_TREE;
7675
 
7676
  /* Optimize pow(1.0,y) = 1.0.  */
7677
  if (real_onep (arg0))
7678
    return omit_one_operand (type, build_real (type, dconst1), arg1);
7679
 
7680
  if (TREE_CODE (arg1) == REAL_CST
7681
      && ! TREE_CONSTANT_OVERFLOW (arg1))
7682
    {
7683
      REAL_VALUE_TYPE cint;
7684
      REAL_VALUE_TYPE c;
7685
      HOST_WIDE_INT n;
7686
 
7687
      c = TREE_REAL_CST (arg1);
7688
 
7689
      /* Optimize pow(x,0.0) = 1.0.  */
7690
      if (REAL_VALUES_EQUAL (c, dconst0))
7691
        return omit_one_operand (type, build_real (type, dconst1),
7692
                                 arg0);
7693
 
7694
      /* Optimize pow(x,1.0) = x.  */
7695
      if (REAL_VALUES_EQUAL (c, dconst1))
7696
        return arg0;
7697
 
7698
      /* Optimize pow(x,-1.0) = 1.0/x.  */
7699
      if (REAL_VALUES_EQUAL (c, dconstm1))
7700
        return fold_build2 (RDIV_EXPR, type,
7701
                            build_real (type, dconst1), arg0);
7702
 
7703
      /* Optimize pow(x,0.5) = sqrt(x).  */
7704
      if (flag_unsafe_math_optimizations
7705
          && REAL_VALUES_EQUAL (c, dconsthalf))
7706
        {
7707
          tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7708
 
7709
          if (sqrtfn != NULL_TREE)
7710
            {
7711
              tree arglist = build_tree_list (NULL_TREE, arg0);
7712
              return build_function_call_expr (sqrtfn, arglist);
7713
            }
7714
        }
7715
 
7716
      /* Check for an integer exponent.  */
7717
      n = real_to_integer (&c);
7718
      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7719
      if (real_identical (&c, &cint))
7720
        {
7721
          /* Attempt to evaluate pow at compile-time.  */
7722
          if (TREE_CODE (arg0) == REAL_CST
7723
              && ! TREE_CONSTANT_OVERFLOW (arg0))
7724
            {
7725
              REAL_VALUE_TYPE x;
7726
              bool inexact;
7727
 
7728
              x = TREE_REAL_CST (arg0);
7729
              inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7730
              if (flag_unsafe_math_optimizations || !inexact)
7731
                return build_real (type, x);
7732
            }
7733
 
7734
          /* Strip sign ops from even integer powers.  */
7735
          if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7736
            {
7737
              tree narg0 = fold_strip_sign_ops (arg0);
7738
              if (narg0)
7739
                {
7740
                  arglist = build_tree_list (NULL_TREE, arg1);
7741
                  arglist = tree_cons (NULL_TREE, narg0, arglist);
7742
                  return build_function_call_expr (fndecl, arglist);
7743
                }
7744
            }
7745
        }
7746
    }
7747
 
7748
  if (flag_unsafe_math_optimizations)
7749
    {
7750
      const enum built_in_function fcode = builtin_mathfn_code (arg0);
7751
 
7752
      /* Optimize pow(expN(x),y) = expN(x*y).  */
7753
      if (BUILTIN_EXPONENT_P (fcode))
7754
        {
7755
          tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7756
          tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7757
          arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7758
          arglist = build_tree_list (NULL_TREE, arg);
7759
          return build_function_call_expr (expfn, arglist);
7760
        }
7761
 
7762
      /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7763
      if (BUILTIN_SQRT_P (fcode))
7764
        {
7765
          tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7766
          tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7767
                                    build_real (type, dconsthalf));
7768
 
7769
          arglist = tree_cons (NULL_TREE, narg0,
7770
                               build_tree_list (NULL_TREE, narg1));
7771
          return build_function_call_expr (fndecl, arglist);
7772
        }
7773
 
7774
      /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7775
      if (BUILTIN_CBRT_P (fcode))
7776
        {
7777
          tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7778
          if (tree_expr_nonnegative_p (arg))
7779
            {
7780
              const REAL_VALUE_TYPE dconstroot
7781
                = real_value_truncate (TYPE_MODE (type), dconstthird);
7782
              tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7783
                                        build_real (type, dconstroot));
7784
              arglist = tree_cons (NULL_TREE, arg,
7785
                                   build_tree_list (NULL_TREE, narg1));
7786
              return build_function_call_expr (fndecl, arglist);
7787
            }
7788
        }
7789
 
7790
      /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7791
      if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7792
           || fcode == BUILT_IN_POWL)
7793
        {
7794
          tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7795
          tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7796
          tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7797
          arglist = tree_cons (NULL_TREE, arg00,
7798
                               build_tree_list (NULL_TREE, narg1));
7799
          return build_function_call_expr (fndecl, arglist);
7800
        }
7801
    }
7802
 
7803
  return NULL_TREE;
7804
}
7805
 
7806
/* Fold a builtin function call to powi, powif, or powil.  Return
7807
   NULL_TREE if no simplification can be made.  */
7808
static tree
7809
fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7810
{
7811
  tree arg0 = TREE_VALUE (arglist);
7812
  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7813
 
7814
  if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7815
    return NULL_TREE;
7816
 
7817
  /* Optimize pow(1.0,y) = 1.0.  */
7818
  if (real_onep (arg0))
7819
    return omit_one_operand (type, build_real (type, dconst1), arg1);
7820
 
7821
  if (host_integerp (arg1, 0))
7822
    {
7823
      HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7824
 
7825
      /* Evaluate powi at compile-time.  */
7826
      if (TREE_CODE (arg0) == REAL_CST
7827
          && ! TREE_CONSTANT_OVERFLOW (arg0))
7828
        {
7829
          REAL_VALUE_TYPE x;
7830
          x = TREE_REAL_CST (arg0);
7831
          real_powi (&x, TYPE_MODE (type), &x, c);
7832
          return build_real (type, x);
7833
        }
7834
 
7835
      /* Optimize pow(x,0) = 1.0.  */
7836
      if (c == 0)
7837
        return omit_one_operand (type, build_real (type, dconst1),
7838
                                 arg0);
7839
 
7840
      /* Optimize pow(x,1) = x.  */
7841
      if (c == 1)
7842
        return arg0;
7843
 
7844
      /* Optimize pow(x,-1) = 1.0/x.  */
7845
      if (c == -1)
7846
        return fold_build2 (RDIV_EXPR, type,
7847
                           build_real (type, dconst1), arg0);
7848
    }
7849
 
7850
  return NULL_TREE;
7851
}
7852
 
7853
/* A subroutine of fold_builtin to fold the various exponent
7854
   functions.  EXP is the CALL_EXPR of a call to a builtin function.
7855
   VALUE is the value which will be raised to a power.  */
7856
 
7857
static tree
7858
fold_builtin_exponent (tree fndecl, tree arglist,
7859
                       const REAL_VALUE_TYPE *value)
7860
{
7861
  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7862
    {
7863
      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7864
      tree arg = TREE_VALUE (arglist);
7865
 
7866
      /* Optimize exp*(0.0) = 1.0.  */
7867
      if (real_zerop (arg))
7868
        return build_real (type, dconst1);
7869
 
7870
      /* Optimize expN(1.0) = N.  */
7871
      if (real_onep (arg))
7872
        {
7873
          REAL_VALUE_TYPE cst;
7874
 
7875
          real_convert (&cst, TYPE_MODE (type), value);
7876
          return build_real (type, cst);
7877
        }
7878
 
7879
      /* Attempt to evaluate expN(integer) at compile-time.  */
7880
      if (flag_unsafe_math_optimizations
7881
          && TREE_CODE (arg) == REAL_CST
7882
          && ! TREE_CONSTANT_OVERFLOW (arg))
7883
        {
7884
          REAL_VALUE_TYPE cint;
7885
          REAL_VALUE_TYPE c;
7886
          HOST_WIDE_INT n;
7887
 
7888
          c = TREE_REAL_CST (arg);
7889
          n = real_to_integer (&c);
7890
          real_from_integer (&cint, VOIDmode, n,
7891
                             n < 0 ? -1 : 0, 0);
7892
          if (real_identical (&c, &cint))
7893
            {
7894
              REAL_VALUE_TYPE x;
7895
 
7896
              real_powi (&x, TYPE_MODE (type), value, n);
7897
              return build_real (type, x);
7898
            }
7899
        }
7900
 
7901
      /* Optimize expN(logN(x)) = x.  */
7902
      if (flag_unsafe_math_optimizations)
7903
        {
7904
          const enum built_in_function fcode = builtin_mathfn_code (arg);
7905
 
7906
          if ((value == &dconste
7907
               && (fcode == BUILT_IN_LOG
7908
                   || fcode == BUILT_IN_LOGF
7909
                   || fcode == BUILT_IN_LOGL))
7910
              || (value == &dconst2
7911
                  && (fcode == BUILT_IN_LOG2
7912
                      || fcode == BUILT_IN_LOG2F
7913
                      || fcode == BUILT_IN_LOG2L))
7914
              || (value == &dconst10
7915
                  && (fcode == BUILT_IN_LOG10
7916
                      || fcode == BUILT_IN_LOG10F
7917
                      || fcode == BUILT_IN_LOG10L)))
7918
            return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7919
        }
7920
    }
7921
 
7922
  return 0;
7923
}
7924
 
7925
/* Fold function call to builtin memcpy.  Return
7926
   NULL_TREE if no simplification can be made.  */
7927
 
7928
static tree
7929
fold_builtin_memcpy (tree fndecl, tree arglist)
7930
{
7931
  tree dest, src, len;
7932
 
7933
  if (!validate_arglist (arglist,
7934
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7935
    return 0;
7936
 
7937
  dest = TREE_VALUE (arglist);
7938
  src = TREE_VALUE (TREE_CHAIN (arglist));
7939
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7940
 
7941
  /* If the LEN parameter is zero, return DEST.  */
7942
  if (integer_zerop (len))
7943
    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7944
 
7945
  /* If SRC and DEST are the same (and not volatile), return DEST.  */
7946
  if (operand_equal_p (src, dest, 0))
7947
    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7948
 
7949
  return 0;
7950
}
7951
 
7952
/* Fold function call to builtin mempcpy.  Return
7953
   NULL_TREE if no simplification can be made.  */
7954
 
7955
static tree
7956
fold_builtin_mempcpy (tree arglist, tree type, int endp)
7957
{
7958
  if (validate_arglist (arglist,
7959
                        POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7960
    {
7961
      tree dest = TREE_VALUE (arglist);
7962
      tree src = TREE_VALUE (TREE_CHAIN (arglist));
7963
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7964
 
7965
      /* If the LEN parameter is zero, return DEST.  */
7966
      if (integer_zerop (len))
7967
        return omit_one_operand (type, dest, src);
7968
 
7969
      /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7970
      if (operand_equal_p (src, dest, 0))
7971
        {
7972
          if (endp == 0)
7973
            return omit_one_operand (type, dest, len);
7974
 
7975
          if (endp == 2)
7976
            len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7977
                               ssize_int (1));
7978
 
7979
          len = fold_convert (TREE_TYPE (dest), len);
7980
          len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7981
          return fold_convert (type, len);
7982
        }
7983
    }
7984
  return 0;
7985
}
7986
 
7987
/* Fold function call to builtin memmove.  Return
7988
   NULL_TREE if no simplification can be made.  */
7989
 
7990
static tree
7991
fold_builtin_memmove (tree arglist, tree type)
7992
{
7993
  tree dest, src, len;
7994
 
7995
  if (!validate_arglist (arglist,
7996
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7997
    return 0;
7998
 
7999
  dest = TREE_VALUE (arglist);
8000
  src = TREE_VALUE (TREE_CHAIN (arglist));
8001
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8002
 
8003
  /* If the LEN parameter is zero, return DEST.  */
8004
  if (integer_zerop (len))
8005
    return omit_one_operand (type, dest, src);
8006
 
8007
  /* If SRC and DEST are the same (and not volatile), return DEST.  */
8008
  if (operand_equal_p (src, dest, 0))
8009
    return omit_one_operand (type, dest, len);
8010
 
8011
  return 0;
8012
}
8013
 
8014
/* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
8015
   the length of the string to be copied.  Return NULL_TREE if no
8016
   simplification can be made.  */
8017
 
8018
tree
8019
fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8020
{
8021
  tree dest, src, fn;
8022
 
8023
  if (!validate_arglist (arglist,
8024
                         POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8025
    return 0;
8026
 
8027
  dest = TREE_VALUE (arglist);
8028
  src = TREE_VALUE (TREE_CHAIN (arglist));
8029
 
8030
  /* If SRC and DEST are the same (and not volatile), return DEST.  */
8031
  if (operand_equal_p (src, dest, 0))
8032
    return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8033
 
8034
  if (optimize_size)
8035
    return 0;
8036
 
8037
  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8038
  if (!fn)
8039
    return 0;
8040
 
8041
  if (!len)
8042
    {
8043
      len = c_strlen (src, 1);
8044
      if (! len || TREE_SIDE_EFFECTS (len))
8045
        return 0;
8046
    }
8047
 
8048
  len = size_binop (PLUS_EXPR, len, ssize_int (1));
8049
  arglist = build_tree_list (NULL_TREE, len);
8050
  arglist = tree_cons (NULL_TREE, src, arglist);
8051
  arglist = tree_cons (NULL_TREE, dest, arglist);
8052
  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8053
                       build_function_call_expr (fn, arglist));
8054
}
8055
 
8056
/* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
8057
   the length of the source string.  Return NULL_TREE if no simplification
8058
   can be made.  */
8059
 
8060
tree
8061
fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8062
{
8063
  tree dest, src, len, fn;
8064
 
8065
  if (!validate_arglist (arglist,
8066
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8067
    return 0;
8068
 
8069
  dest = TREE_VALUE (arglist);
8070
  src = TREE_VALUE (TREE_CHAIN (arglist));
8071
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8072
 
8073
  /* If the LEN parameter is zero, return DEST.  */
8074
  if (integer_zerop (len))
8075
    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8076
 
8077
  /* We can't compare slen with len as constants below if len is not a
8078
     constant.  */
8079
  if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8080
    return 0;
8081
 
8082
  if (!slen)
8083
    slen = c_strlen (src, 1);
8084
 
8085
  /* Now, we must be passed a constant src ptr parameter.  */
8086
  if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8087
    return 0;
8088
 
8089
  slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8090
 
8091
  /* We do not support simplification of this case, though we do
8092
     support it when expanding trees into RTL.  */
8093
  /* FIXME: generate a call to __builtin_memset.  */
8094
  if (tree_int_cst_lt (slen, len))
8095
    return 0;
8096
 
8097
  /* OK transform into builtin memcpy.  */
8098
  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8099
  if (!fn)
8100
    return 0;
8101
  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8102
                       build_function_call_expr (fn, arglist));
8103
}
8104
 
8105
/* Fold function call to builtin memcmp.  Return
8106
   NULL_TREE if no simplification can be made.  */
8107
 
8108
static tree
8109
fold_builtin_memcmp (tree arglist)
8110
{
8111
  tree arg1, arg2, len;
8112
  const char *p1, *p2;
8113
 
8114
  if (!validate_arglist (arglist,
8115
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8116
    return 0;
8117
 
8118
  arg1 = TREE_VALUE (arglist);
8119
  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8120
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8121
 
8122
  /* If the LEN parameter is zero, return zero.  */
8123
  if (integer_zerop (len))
8124
    return omit_two_operands (integer_type_node, integer_zero_node,
8125
                              arg1, arg2);
8126
 
8127
  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8128
  if (operand_equal_p (arg1, arg2, 0))
8129
    return omit_one_operand (integer_type_node, integer_zero_node, len);
8130
 
8131
  p1 = c_getstr (arg1);
8132
  p2 = c_getstr (arg2);
8133
 
8134
  /* If all arguments are constant, and the value of len is not greater
8135
     than the lengths of arg1 and arg2, evaluate at compile-time.  */
8136
  if (host_integerp (len, 1) && p1 && p2
8137
      && compare_tree_int (len, strlen (p1) + 1) <= 0
8138
      && compare_tree_int (len, strlen (p2) + 1) <= 0)
8139
    {
8140
      const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8141
 
8142
      if (r > 0)
8143
        return integer_one_node;
8144
      else if (r < 0)
8145
        return integer_minus_one_node;
8146
      else
8147
        return integer_zero_node;
8148
    }
8149
 
8150
  /* If len parameter is one, return an expression corresponding to
8151
     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8152
  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8153
    {
8154
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8155
      tree cst_uchar_ptr_node
8156
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8157
 
8158
      tree ind1 = fold_convert (integer_type_node,
8159
                                build1 (INDIRECT_REF, cst_uchar_node,
8160
                                        fold_convert (cst_uchar_ptr_node,
8161
                                                      arg1)));
8162
      tree ind2 = fold_convert (integer_type_node,
8163
                                build1 (INDIRECT_REF, cst_uchar_node,
8164
                                        fold_convert (cst_uchar_ptr_node,
8165
                                                      arg2)));
8166
      return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8167
    }
8168
 
8169
  return 0;
8170
}
8171
 
8172
/* Fold function call to builtin strcmp.  Return
8173
   NULL_TREE if no simplification can be made.  */
8174
 
8175
static tree
8176
fold_builtin_strcmp (tree arglist)
8177
{
8178
  tree arg1, arg2;
8179
  const char *p1, *p2;
8180
 
8181
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8182
    return 0;
8183
 
8184
  arg1 = TREE_VALUE (arglist);
8185
  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8186
 
8187
  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8188
  if (operand_equal_p (arg1, arg2, 0))
8189
    return integer_zero_node;
8190
 
8191
  p1 = c_getstr (arg1);
8192
  p2 = c_getstr (arg2);
8193
 
8194
  if (p1 && p2)
8195
    {
8196
      const int i = strcmp (p1, p2);
8197
      if (i < 0)
8198
        return integer_minus_one_node;
8199
      else if (i > 0)
8200
        return integer_one_node;
8201
      else
8202
        return integer_zero_node;
8203
    }
8204
 
8205
  /* If the second arg is "", return *(const unsigned char*)arg1.  */
8206
  if (p2 && *p2 == '\0')
8207
    {
8208
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8209
      tree cst_uchar_ptr_node
8210
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8211
 
8212
      return fold_convert (integer_type_node,
8213
                           build1 (INDIRECT_REF, cst_uchar_node,
8214
                                   fold_convert (cst_uchar_ptr_node,
8215
                                                 arg1)));
8216
    }
8217
 
8218
  /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8219
  if (p1 && *p1 == '\0')
8220
    {
8221
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8222
      tree cst_uchar_ptr_node
8223
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8224
 
8225
      tree temp = fold_convert (integer_type_node,
8226
                                build1 (INDIRECT_REF, cst_uchar_node,
8227
                                        fold_convert (cst_uchar_ptr_node,
8228
                                                      arg2)));
8229
      return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8230
    }
8231
 
8232
  return 0;
8233
}
8234
 
8235
/* Fold function call to builtin strncmp.  Return
8236
   NULL_TREE if no simplification can be made.  */
8237
 
8238
static tree
8239
fold_builtin_strncmp (tree arglist)
8240
{
8241
  tree arg1, arg2, len;
8242
  const char *p1, *p2;
8243
 
8244
  if (!validate_arglist (arglist,
8245
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8246
    return 0;
8247
 
8248
  arg1 = TREE_VALUE (arglist);
8249
  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8250
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8251
 
8252
  /* If the LEN parameter is zero, return zero.  */
8253
  if (integer_zerop (len))
8254
    return omit_two_operands (integer_type_node, integer_zero_node,
8255
                              arg1, arg2);
8256
 
8257
  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8258
  if (operand_equal_p (arg1, arg2, 0))
8259
    return omit_one_operand (integer_type_node, integer_zero_node, len);
8260
 
8261
  p1 = c_getstr (arg1);
8262
  p2 = c_getstr (arg2);
8263
 
8264
  if (host_integerp (len, 1) && p1 && p2)
8265
    {
8266
      const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8267
      if (i > 0)
8268
        return integer_one_node;
8269
      else if (i < 0)
8270
        return integer_minus_one_node;
8271
      else
8272
        return integer_zero_node;
8273
    }
8274
 
8275
  /* If the second arg is "", and the length is greater than zero,
8276
     return *(const unsigned char*)arg1.  */
8277
  if (p2 && *p2 == '\0'
8278
      && TREE_CODE (len) == INTEGER_CST
8279
      && tree_int_cst_sgn (len) == 1)
8280
    {
8281
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8282
      tree cst_uchar_ptr_node
8283
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8284
 
8285
      return fold_convert (integer_type_node,
8286
                           build1 (INDIRECT_REF, cst_uchar_node,
8287
                                   fold_convert (cst_uchar_ptr_node,
8288
                                                 arg1)));
8289
    }
8290
 
8291
  /* If the first arg is "", and the length is greater than zero,
8292
     return -*(const unsigned char*)arg2.  */
8293
  if (p1 && *p1 == '\0'
8294
      && TREE_CODE (len) == INTEGER_CST
8295
      && tree_int_cst_sgn (len) == 1)
8296
    {
8297
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8298
      tree cst_uchar_ptr_node
8299
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8300
 
8301
      tree temp = fold_convert (integer_type_node,
8302
                                build1 (INDIRECT_REF, cst_uchar_node,
8303
                                        fold_convert (cst_uchar_ptr_node,
8304
                                                      arg2)));
8305
      return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8306
    }
8307
 
8308
  /* If len parameter is one, return an expression corresponding to
8309
     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8310
  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8311
    {
8312
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8313
      tree cst_uchar_ptr_node
8314
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8315
 
8316
      tree ind1 = fold_convert (integer_type_node,
8317
                                build1 (INDIRECT_REF, cst_uchar_node,
8318
                                        fold_convert (cst_uchar_ptr_node,
8319
                                                      arg1)));
8320
      tree ind2 = fold_convert (integer_type_node,
8321
                                build1 (INDIRECT_REF, cst_uchar_node,
8322
                                        fold_convert (cst_uchar_ptr_node,
8323
                                                      arg2)));
8324
      return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8325
    }
8326
 
8327
  return 0;
8328
}
8329
 
8330
/* Fold function call to builtin signbit, signbitf or signbitl.  Return
8331
   NULL_TREE if no simplification can be made.  */
8332
 
8333
static tree
8334
fold_builtin_signbit (tree fndecl, tree arglist)
8335
{
8336
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8337
  tree arg, temp;
8338
 
8339
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8340
    return NULL_TREE;
8341
 
8342
  arg = TREE_VALUE (arglist);
8343
 
8344
  /* If ARG is a compile-time constant, determine the result.  */
8345
  if (TREE_CODE (arg) == REAL_CST
8346
      && !TREE_CONSTANT_OVERFLOW (arg))
8347
    {
8348
      REAL_VALUE_TYPE c;
8349
 
8350
      c = TREE_REAL_CST (arg);
8351
      temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8352
      return fold_convert (type, temp);
8353
    }
8354
 
8355
  /* If ARG is non-negative, the result is always zero.  */
8356
  if (tree_expr_nonnegative_p (arg))
8357
    return omit_one_operand (type, integer_zero_node, arg);
8358
 
8359
  /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8360
  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8361
    return fold_build2 (LT_EXPR, type, arg,
8362
                        build_real (TREE_TYPE (arg), dconst0));
8363
 
8364
  return NULL_TREE;
8365
}
8366
 
8367
/* Fold function call to builtin copysign, copysignf or copysignl.
8368
   Return NULL_TREE if no simplification can be made.  */
8369
 
8370
static tree
8371
fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8372
{
8373
  tree arg1, arg2, tem;
8374
 
8375
  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8376
    return NULL_TREE;
8377
 
8378
  arg1 = TREE_VALUE (arglist);
8379
  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8380
 
8381
  /* copysign(X,X) is X.  */
8382
  if (operand_equal_p (arg1, arg2, 0))
8383
    return fold_convert (type, arg1);
8384
 
8385
  /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8386
  if (TREE_CODE (arg1) == REAL_CST
8387
      && TREE_CODE (arg2) == REAL_CST
8388
      && !TREE_CONSTANT_OVERFLOW (arg1)
8389
      && !TREE_CONSTANT_OVERFLOW (arg2))
8390
    {
8391
      REAL_VALUE_TYPE c1, c2;
8392
 
8393
      c1 = TREE_REAL_CST (arg1);
8394
      c2 = TREE_REAL_CST (arg2);
8395
      real_copysign (&c1, &c2);
8396
      return build_real (type, c1);
8397
      c1.sign = c2.sign;
8398
    }
8399
 
8400
  /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8401
     Remember to evaluate Y for side-effects.  */
8402
  if (tree_expr_nonnegative_p (arg2))
8403
    return omit_one_operand (type,
8404
                             fold_build1 (ABS_EXPR, type, arg1),
8405
                             arg2);
8406
 
8407
  /* Strip sign changing operations for the first argument.  */
8408
  tem = fold_strip_sign_ops (arg1);
8409
  if (tem)
8410
    {
8411
      arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8412
      return build_function_call_expr (fndecl, arglist);
8413
    }
8414
 
8415
  return NULL_TREE;
8416
}
8417
 
8418
/* Fold a call to builtin isascii.  */
8419
 
8420
static tree
8421
fold_builtin_isascii (tree arglist)
8422
{
8423
  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8424
    return 0;
8425
  else
8426
    {
8427
      /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8428
      tree arg = TREE_VALUE (arglist);
8429
 
8430
      arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8431
                    build_int_cst (NULL_TREE,
8432
                                   ~ (unsigned HOST_WIDE_INT) 0x7f));
8433
      arg = fold_build2 (EQ_EXPR, integer_type_node,
8434
                         arg, integer_zero_node);
8435
 
8436
      if (in_gimple_form && !TREE_CONSTANT (arg))
8437
        return NULL_TREE;
8438
      else
8439
        return arg;
8440
    }
8441
}
8442
 
8443
/* Fold a call to builtin toascii.  */
8444
 
8445
static tree
8446
fold_builtin_toascii (tree arglist)
8447
{
8448
  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8449
    return 0;
8450
  else
8451
    {
8452
      /* Transform toascii(c) -> (c & 0x7f).  */
8453
      tree arg = TREE_VALUE (arglist);
8454
 
8455
      return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8456
                          build_int_cst (NULL_TREE, 0x7f));
8457
    }
8458
}
8459
 
8460
/* Fold a call to builtin isdigit.  */
8461
 
8462
static tree
8463
fold_builtin_isdigit (tree arglist)
8464
{
8465
  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8466
    return 0;
8467
  else
8468
    {
8469
      /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8470
      /* According to the C standard, isdigit is unaffected by locale.
8471
         However, it definitely is affected by the target character set.  */
8472
      tree arg;
8473
      unsigned HOST_WIDE_INT target_digit0
8474
        = lang_hooks.to_target_charset ('0');
8475
 
8476
      if (target_digit0 == 0)
8477
        return NULL_TREE;
8478
 
8479
      arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8480
      arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8481
                    build_int_cst (unsigned_type_node, target_digit0));
8482
      arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8483
                         build_int_cst (unsigned_type_node, 9));
8484
      if (in_gimple_form && !TREE_CONSTANT (arg))
8485
        return NULL_TREE;
8486
      else
8487
        return arg;
8488
    }
8489
}
8490
 
8491
/* Fold a call to fabs, fabsf or fabsl.  */
8492
 
8493
static tree
8494
fold_builtin_fabs (tree arglist, tree type)
8495
{
8496
  tree arg;
8497
 
8498
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8499
    return 0;
8500
 
8501
  arg = TREE_VALUE (arglist);
8502
  arg = fold_convert (type, arg);
8503
  if (TREE_CODE (arg) == REAL_CST)
8504
    return fold_abs_const (arg, type);
8505
  return fold_build1 (ABS_EXPR, type, arg);
8506
}
8507
 
8508
/* Fold a call to abs, labs, llabs or imaxabs.  */
8509
 
8510
static tree
8511
fold_builtin_abs (tree arglist, tree type)
8512
{
8513
  tree arg;
8514
 
8515
  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8516
    return 0;
8517
 
8518
  arg = TREE_VALUE (arglist);
8519
  arg = fold_convert (type, arg);
8520
  if (TREE_CODE (arg) == INTEGER_CST)
8521
    return fold_abs_const (arg, type);
8522
  return fold_build1 (ABS_EXPR, type, arg);
8523
}
8524
 
8525
/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8526
   EXP is the CALL_EXPR for the call.  */
8527
 
8528
static tree
8529
fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8530
{
8531
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8532
  tree arg;
8533
  REAL_VALUE_TYPE r;
8534
 
8535
  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8536
    {
8537
      /* Check that we have exactly one argument.  */
8538
      if (arglist == 0)
8539
        {
8540
          error ("too few arguments to function %qs",
8541
                 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8542
          return error_mark_node;
8543
        }
8544
      else if (TREE_CHAIN (arglist) != 0)
8545
        {
8546
          error ("too many arguments to function %qs",
8547
                 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8548
          return error_mark_node;
8549
        }
8550
      else
8551
        {
8552
          error ("non-floating-point argument to function %qs",
8553
                 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8554
          return error_mark_node;
8555
        }
8556
    }
8557
 
8558
  arg = TREE_VALUE (arglist);
8559
  switch (builtin_index)
8560
    {
8561
    case BUILT_IN_ISINF:
8562
      if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8563
        return omit_one_operand (type, integer_zero_node, arg);
8564
 
8565
      if (TREE_CODE (arg) == REAL_CST)
8566
        {
8567
          r = TREE_REAL_CST (arg);
8568
          if (real_isinf (&r))
8569
            return real_compare (GT_EXPR, &r, &dconst0)
8570
                   ? integer_one_node : integer_minus_one_node;
8571
          else
8572
            return integer_zero_node;
8573
        }
8574
 
8575
      return NULL_TREE;
8576
 
8577
    case BUILT_IN_FINITE:
8578
      if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8579
          && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8580
        return omit_one_operand (type, integer_zero_node, arg);
8581
 
8582
      if (TREE_CODE (arg) == REAL_CST)
8583
        {
8584
          r = TREE_REAL_CST (arg);
8585
          return real_isinf (&r) || real_isnan (&r)
8586
                 ? integer_zero_node : integer_one_node;
8587
        }
8588
 
8589
      return NULL_TREE;
8590
 
8591
    case BUILT_IN_ISNAN:
8592
      if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8593
        return omit_one_operand (type, integer_zero_node, arg);
8594
 
8595
      if (TREE_CODE (arg) == REAL_CST)
8596
        {
8597
          r = TREE_REAL_CST (arg);
8598
          return real_isnan (&r) ? integer_one_node : integer_zero_node;
8599
        }
8600
 
8601
      arg = builtin_save_expr (arg);
8602
      return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8603
 
8604
    default:
8605
      gcc_unreachable ();
8606
    }
8607
}
8608
 
8609
/* Fold a call to an unordered comparison function such as
8610
   __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8611
   being called and ARGLIST is the argument list for the call.
8612
   UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8613
   the opposite of the desired result.  UNORDERED_CODE is used
8614
   for modes that can hold NaNs and ORDERED_CODE is used for
8615
   the rest.  */
8616
 
8617
static tree
8618
fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8619
                            enum tree_code unordered_code,
8620
                            enum tree_code ordered_code)
8621
{
8622
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8623
  enum tree_code code;
8624
  tree arg0, arg1;
8625
  tree type0, type1;
8626
  enum tree_code code0, code1;
8627
  tree cmp_type = NULL_TREE;
8628
 
8629
  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8630
    {
8631
      /* Check that we have exactly two arguments.  */
8632
      if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8633
        {
8634
          error ("too few arguments to function %qs",
8635
                 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8636
          return error_mark_node;
8637
        }
8638
      else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8639
        {
8640
          error ("too many arguments to function %qs",
8641
                 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8642
          return error_mark_node;
8643
        }
8644
    }
8645
 
8646
  arg0 = TREE_VALUE (arglist);
8647
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8648
 
8649
  type0 = TREE_TYPE (arg0);
8650
  type1 = TREE_TYPE (arg1);
8651
 
8652
  code0 = TREE_CODE (type0);
8653
  code1 = TREE_CODE (type1);
8654
 
8655
  if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8656
    /* Choose the wider of two real types.  */
8657
    cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8658
      ? type0 : type1;
8659
  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8660
    cmp_type = type0;
8661
  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8662
    cmp_type = type1;
8663
  else
8664
    {
8665
      error ("non-floating-point argument to function %qs",
8666
                 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8667
      return error_mark_node;
8668
    }
8669
 
8670
  arg0 = fold_convert (cmp_type, arg0);
8671
  arg1 = fold_convert (cmp_type, arg1);
8672
 
8673
  if (unordered_code == UNORDERED_EXPR)
8674
    {
8675
      if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8676
        return omit_two_operands (type, integer_zero_node, arg0, arg1);
8677
      return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8678
    }
8679
 
8680
  code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8681
                                                      : ordered_code;
8682
  return fold_build1 (TRUTH_NOT_EXPR, type,
8683
                      fold_build2 (code, type, arg0, arg1));
8684
}
8685
 
8686
/* Used by constant folding to simplify calls to builtin functions.  EXP is
8687
   the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8688
   result of the function call is ignored.  This function returns NULL_TREE
8689
   if no simplification was possible.  */
8690
 
8691
static tree
8692
fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8693
{
8694
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8695
  enum built_in_function fcode;
8696
 
8697
  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8698
    return targetm.fold_builtin (fndecl, arglist, ignore);
8699
 
8700
  fcode = DECL_FUNCTION_CODE (fndecl);
8701
  switch (fcode)
8702
    {
8703
    case BUILT_IN_FPUTS:
8704
      return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8705
 
8706
    case BUILT_IN_FPUTS_UNLOCKED:
8707
      return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8708
 
8709
    case BUILT_IN_STRSTR:
8710
      return fold_builtin_strstr (arglist, type);
8711
 
8712
    case BUILT_IN_STRCAT:
8713
      return fold_builtin_strcat (arglist);
8714
 
8715
    case BUILT_IN_STRNCAT:
8716
      return fold_builtin_strncat (arglist);
8717
 
8718
    case BUILT_IN_STRSPN:
8719
      return fold_builtin_strspn (arglist);
8720
 
8721
    case BUILT_IN_STRCSPN:
8722
      return fold_builtin_strcspn (arglist);
8723
 
8724
    case BUILT_IN_STRCHR:
8725
    case BUILT_IN_INDEX:
8726
      return fold_builtin_strchr (arglist, type);
8727
 
8728
    case BUILT_IN_STRRCHR:
8729
    case BUILT_IN_RINDEX:
8730
      return fold_builtin_strrchr (arglist, type);
8731
 
8732
    case BUILT_IN_STRCPY:
8733
      return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8734
 
8735
    case BUILT_IN_STRNCPY:
8736
      return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8737
 
8738
    case BUILT_IN_STRCMP:
8739
      return fold_builtin_strcmp (arglist);
8740
 
8741
    case BUILT_IN_STRNCMP:
8742
      return fold_builtin_strncmp (arglist);
8743
 
8744
    case BUILT_IN_STRPBRK:
8745
      return fold_builtin_strpbrk (arglist, type);
8746
 
8747
    case BUILT_IN_BCMP:
8748
    case BUILT_IN_MEMCMP:
8749
      return fold_builtin_memcmp (arglist);
8750
 
8751
    case BUILT_IN_SPRINTF:
8752
      return fold_builtin_sprintf (arglist, ignore);
8753
 
8754
    case BUILT_IN_CONSTANT_P:
8755
      {
8756
        tree val;
8757
 
8758
        val = fold_builtin_constant_p (arglist);
8759
        /* Gimplification will pull the CALL_EXPR for the builtin out of
8760
           an if condition.  When not optimizing, we'll not CSE it back.
8761
           To avoid link error types of regressions, return false now.  */
8762
        if (!val && !optimize)
8763
          val = integer_zero_node;
8764
 
8765
        return val;
8766
      }
8767
 
8768
    case BUILT_IN_EXPECT:
8769
      return fold_builtin_expect (arglist);
8770
 
8771
    case BUILT_IN_CLASSIFY_TYPE:
8772
      return fold_builtin_classify_type (arglist);
8773
 
8774
    case BUILT_IN_STRLEN:
8775
      return fold_builtin_strlen (arglist);
8776
 
8777
    case BUILT_IN_FABS:
8778
    case BUILT_IN_FABSF:
8779
    case BUILT_IN_FABSL:
8780
      return fold_builtin_fabs (arglist, type);
8781
 
8782
    case BUILT_IN_ABS:
8783
    case BUILT_IN_LABS:
8784
    case BUILT_IN_LLABS:
8785
    case BUILT_IN_IMAXABS:
8786
      return fold_builtin_abs (arglist, type);
8787
 
8788
    case BUILT_IN_CONJ:
8789
    case BUILT_IN_CONJF:
8790
    case BUILT_IN_CONJL:
8791
      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8792
        return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8793
      break;
8794
 
8795
    case BUILT_IN_CREAL:
8796
    case BUILT_IN_CREALF:
8797
    case BUILT_IN_CREALL:
8798
      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8799
        return non_lvalue (fold_build1 (REALPART_EXPR, type,
8800
                                        TREE_VALUE (arglist)));
8801
      break;
8802
 
8803
    case BUILT_IN_CIMAG:
8804
    case BUILT_IN_CIMAGF:
8805
    case BUILT_IN_CIMAGL:
8806
      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8807
        return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8808
                                        TREE_VALUE (arglist)));
8809
      break;
8810
 
8811
    case BUILT_IN_CABS:
8812
    case BUILT_IN_CABSF:
8813
    case BUILT_IN_CABSL:
8814
      return fold_builtin_cabs (arglist, type);
8815
 
8816
    case BUILT_IN_SQRT:
8817
    case BUILT_IN_SQRTF:
8818
    case BUILT_IN_SQRTL:
8819
      return fold_builtin_sqrt (arglist, type);
8820
 
8821
    case BUILT_IN_CBRT:
8822
    case BUILT_IN_CBRTF:
8823
    case BUILT_IN_CBRTL:
8824
      return fold_builtin_cbrt (arglist, type);
8825
 
8826
    case BUILT_IN_SIN:
8827
    case BUILT_IN_SINF:
8828
    case BUILT_IN_SINL:
8829
      return fold_builtin_sin (arglist);
8830
 
8831
    case BUILT_IN_COS:
8832
    case BUILT_IN_COSF:
8833
    case BUILT_IN_COSL:
8834
      return fold_builtin_cos (arglist, type, fndecl);
8835
 
8836
    case BUILT_IN_EXP:
8837
    case BUILT_IN_EXPF:
8838
    case BUILT_IN_EXPL:
8839
      return fold_builtin_exponent (fndecl, arglist, &dconste);
8840
 
8841
    case BUILT_IN_EXP2:
8842
    case BUILT_IN_EXP2F:
8843
    case BUILT_IN_EXP2L:
8844
      return fold_builtin_exponent (fndecl, arglist, &dconst2);
8845
 
8846
    case BUILT_IN_EXP10:
8847
    case BUILT_IN_EXP10F:
8848
    case BUILT_IN_EXP10L:
8849
    case BUILT_IN_POW10:
8850
    case BUILT_IN_POW10F:
8851
    case BUILT_IN_POW10L:
8852
      return fold_builtin_exponent (fndecl, arglist, &dconst10);
8853
 
8854
    case BUILT_IN_LOG:
8855
    case BUILT_IN_LOGF:
8856
    case BUILT_IN_LOGL:
8857
      return fold_builtin_logarithm (fndecl, arglist, &dconste);
8858
 
8859
    case BUILT_IN_LOG2:
8860
    case BUILT_IN_LOG2F:
8861
    case BUILT_IN_LOG2L:
8862
      return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8863
 
8864
    case BUILT_IN_LOG10:
8865
    case BUILT_IN_LOG10F:
8866
    case BUILT_IN_LOG10L:
8867
      return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8868
 
8869
    case BUILT_IN_TAN:
8870
    case BUILT_IN_TANF:
8871
    case BUILT_IN_TANL:
8872
      return fold_builtin_tan (arglist);
8873
 
8874
    case BUILT_IN_ATAN:
8875
    case BUILT_IN_ATANF:
8876
    case BUILT_IN_ATANL:
8877
      return fold_builtin_atan (arglist, type);
8878
 
8879
    case BUILT_IN_POW:
8880
    case BUILT_IN_POWF:
8881
    case BUILT_IN_POWL:
8882
      return fold_builtin_pow (fndecl, arglist, type);
8883
 
8884
    case BUILT_IN_POWI:
8885
    case BUILT_IN_POWIF:
8886
    case BUILT_IN_POWIL:
8887
      return fold_builtin_powi (fndecl, arglist, type);
8888
 
8889
    case BUILT_IN_INF:
8890
    case BUILT_IN_INFF:
8891
    case BUILT_IN_INFL:
8892
      return fold_builtin_inf (type, true);
8893
 
8894
    case BUILT_IN_HUGE_VAL:
8895
    case BUILT_IN_HUGE_VALF:
8896
    case BUILT_IN_HUGE_VALL:
8897
      return fold_builtin_inf (type, false);
8898
 
8899
    case BUILT_IN_NAN:
8900
    case BUILT_IN_NANF:
8901
    case BUILT_IN_NANL:
8902
      return fold_builtin_nan (arglist, type, true);
8903
 
8904
    case BUILT_IN_NANS:
8905
    case BUILT_IN_NANSF:
8906
    case BUILT_IN_NANSL:
8907
      return fold_builtin_nan (arglist, type, false);
8908
 
8909
    case BUILT_IN_FLOOR:
8910
    case BUILT_IN_FLOORF:
8911
    case BUILT_IN_FLOORL:
8912
      return fold_builtin_floor (fndecl, arglist);
8913
 
8914
    case BUILT_IN_CEIL:
8915
    case BUILT_IN_CEILF:
8916
    case BUILT_IN_CEILL:
8917
      return fold_builtin_ceil (fndecl, arglist);
8918
 
8919
    case BUILT_IN_TRUNC:
8920
    case BUILT_IN_TRUNCF:
8921
    case BUILT_IN_TRUNCL:
8922
      return fold_builtin_trunc (fndecl, arglist);
8923
 
8924
    case BUILT_IN_ROUND:
8925
    case BUILT_IN_ROUNDF:
8926
    case BUILT_IN_ROUNDL:
8927
      return fold_builtin_round (fndecl, arglist);
8928
 
8929
    case BUILT_IN_NEARBYINT:
8930
    case BUILT_IN_NEARBYINTF:
8931
    case BUILT_IN_NEARBYINTL:
8932
    case BUILT_IN_RINT:
8933
    case BUILT_IN_RINTF:
8934
    case BUILT_IN_RINTL:
8935
      return fold_trunc_transparent_mathfn (fndecl, arglist);
8936
 
8937
    case BUILT_IN_LCEIL:
8938
    case BUILT_IN_LCEILF:
8939
    case BUILT_IN_LCEILL:
8940
    case BUILT_IN_LLCEIL:
8941
    case BUILT_IN_LLCEILF:
8942
    case BUILT_IN_LLCEILL:
8943
    case BUILT_IN_LFLOOR:
8944
    case BUILT_IN_LFLOORF:
8945
    case BUILT_IN_LFLOORL:
8946
    case BUILT_IN_LLFLOOR:
8947
    case BUILT_IN_LLFLOORF:
8948
    case BUILT_IN_LLFLOORL:
8949
    case BUILT_IN_LROUND:
8950
    case BUILT_IN_LROUNDF:
8951
    case BUILT_IN_LROUNDL:
8952
    case BUILT_IN_LLROUND:
8953
    case BUILT_IN_LLROUNDF:
8954
    case BUILT_IN_LLROUNDL:
8955
      return fold_builtin_int_roundingfn (fndecl, arglist);
8956
 
8957
    case BUILT_IN_LRINT:
8958
    case BUILT_IN_LRINTF:
8959
    case BUILT_IN_LRINTL:
8960
    case BUILT_IN_LLRINT:
8961
    case BUILT_IN_LLRINTF:
8962
    case BUILT_IN_LLRINTL:
8963
      return fold_fixed_mathfn (fndecl, arglist);
8964
 
8965
    case BUILT_IN_FFS:
8966
    case BUILT_IN_FFSL:
8967
    case BUILT_IN_FFSLL:
8968
    case BUILT_IN_CLZ:
8969
    case BUILT_IN_CLZL:
8970
    case BUILT_IN_CLZLL:
8971
    case BUILT_IN_CTZ:
8972
    case BUILT_IN_CTZL:
8973
    case BUILT_IN_CTZLL:
8974
    case BUILT_IN_POPCOUNT:
8975
    case BUILT_IN_POPCOUNTL:
8976
    case BUILT_IN_POPCOUNTLL:
8977
    case BUILT_IN_PARITY:
8978
    case BUILT_IN_PARITYL:
8979
    case BUILT_IN_PARITYLL:
8980
      return fold_builtin_bitop (fndecl, arglist);
8981
 
8982
    case BUILT_IN_MEMCPY:
8983
      return fold_builtin_memcpy (fndecl, arglist);
8984
 
8985
    case BUILT_IN_MEMPCPY:
8986
      return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8987
 
8988
    case BUILT_IN_MEMMOVE:
8989
      return fold_builtin_memmove (arglist, type);
8990
 
8991
    case BUILT_IN_SIGNBIT:
8992
    case BUILT_IN_SIGNBITF:
8993
    case BUILT_IN_SIGNBITL:
8994
      return fold_builtin_signbit (fndecl, arglist);
8995
 
8996
    case BUILT_IN_ISASCII:
8997
      return fold_builtin_isascii (arglist);
8998
 
8999
    case BUILT_IN_TOASCII:
9000
      return fold_builtin_toascii (arglist);
9001
 
9002
    case BUILT_IN_ISDIGIT:
9003
      return fold_builtin_isdigit (arglist);
9004
 
9005
    case BUILT_IN_COPYSIGN:
9006
    case BUILT_IN_COPYSIGNF:
9007
    case BUILT_IN_COPYSIGNL:
9008
      return fold_builtin_copysign (fndecl, arglist, type);
9009
 
9010
    case BUILT_IN_FINITE:
9011
    case BUILT_IN_FINITEF:
9012
    case BUILT_IN_FINITEL:
9013
      return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9014
 
9015
    case BUILT_IN_ISINF:
9016
    case BUILT_IN_ISINFF:
9017
    case BUILT_IN_ISINFL:
9018
      return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9019
 
9020
    case BUILT_IN_ISNAN:
9021
    case BUILT_IN_ISNANF:
9022
    case BUILT_IN_ISNANL:
9023
      return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9024
 
9025
    case BUILT_IN_ISGREATER:
9026
      return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9027
    case BUILT_IN_ISGREATEREQUAL:
9028
      return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9029
    case BUILT_IN_ISLESS:
9030
      return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9031
    case BUILT_IN_ISLESSEQUAL:
9032
      return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9033
    case BUILT_IN_ISLESSGREATER:
9034
      return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9035
    case BUILT_IN_ISUNORDERED:
9036
      return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9037
                                         NOP_EXPR);
9038
 
9039
      /* We do the folding for va_start in the expander.  */
9040
    case BUILT_IN_VA_START:
9041
      break;
9042
 
9043
    case BUILT_IN_OBJECT_SIZE:
9044
      return fold_builtin_object_size (arglist);
9045
    case BUILT_IN_MEMCPY_CHK:
9046
    case BUILT_IN_MEMPCPY_CHK:
9047
    case BUILT_IN_MEMMOVE_CHK:
9048
    case BUILT_IN_MEMSET_CHK:
9049
      return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9050
                                      DECL_FUNCTION_CODE (fndecl));
9051
    case BUILT_IN_STRCPY_CHK:
9052
    case BUILT_IN_STPCPY_CHK:
9053
      return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9054
                                      DECL_FUNCTION_CODE (fndecl));
9055
    case BUILT_IN_STRNCPY_CHK:
9056
      return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9057
    case BUILT_IN_STRCAT_CHK:
9058
      return fold_builtin_strcat_chk (fndecl, arglist);
9059
    case BUILT_IN_STRNCAT_CHK:
9060
      return fold_builtin_strncat_chk (fndecl, arglist);
9061
    case BUILT_IN_SPRINTF_CHK:
9062
    case BUILT_IN_VSPRINTF_CHK:
9063
      return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9064
    case BUILT_IN_SNPRINTF_CHK:
9065
    case BUILT_IN_VSNPRINTF_CHK:
9066
      return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9067
                                        DECL_FUNCTION_CODE (fndecl));
9068
 
9069
    case BUILT_IN_PRINTF:
9070
    case BUILT_IN_PRINTF_UNLOCKED:
9071
    case BUILT_IN_VPRINTF:
9072
    case BUILT_IN_PRINTF_CHK:
9073
    case BUILT_IN_VPRINTF_CHK:
9074
      return fold_builtin_printf (fndecl, arglist, ignore,
9075
                                  DECL_FUNCTION_CODE (fndecl));
9076
 
9077
    case BUILT_IN_FPRINTF:
9078
    case BUILT_IN_FPRINTF_UNLOCKED:
9079
    case BUILT_IN_VFPRINTF:
9080
    case BUILT_IN_FPRINTF_CHK:
9081
    case BUILT_IN_VFPRINTF_CHK:
9082
      return fold_builtin_fprintf (fndecl, arglist, ignore,
9083
                                   DECL_FUNCTION_CODE (fndecl));
9084
 
9085
    default:
9086
      break;
9087
    }
9088
 
9089
  return 0;
9090
}
9091
 
9092
/* A wrapper function for builtin folding that prevents warnings for
9093
   "statement without effect" and the like, caused by removing the
9094
   call node earlier than the warning is generated.  */
9095
 
9096
tree
9097
fold_builtin (tree fndecl, tree arglist, bool ignore)
9098
{
9099
  tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9100
  if (exp)
9101
    {
9102
      exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9103
      TREE_NO_WARNING (exp) = 1;
9104
    }
9105
 
9106
  return exp;
9107
}
9108
 
9109
/* Conveniently construct a function call expression.  */
9110
 
9111
tree
9112
build_function_call_expr (tree fn, tree arglist)
9113
{
9114
  tree call_expr;
9115
 
9116
  call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9117
  return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9118
                      call_expr, arglist, NULL_TREE);
9119
}
9120
 
9121
/* This function validates the types of a function call argument list
9122
   represented as a tree chain of parameters against a specified list
9123
   of tree_codes.  If the last specifier is a 0, that represents an
9124
   ellipses, otherwise the last specifier must be a VOID_TYPE.  */
9125
 
9126
static int
9127
validate_arglist (tree arglist, ...)
9128
{
9129
  enum tree_code code;
9130
  int res = 0;
9131
  va_list ap;
9132
 
9133
  va_start (ap, arglist);
9134
 
9135
  do
9136
    {
9137
      code = va_arg (ap, enum tree_code);
9138
      switch (code)
9139
        {
9140
        case 0:
9141
          /* This signifies an ellipses, any further arguments are all ok.  */
9142
          res = 1;
9143
          goto end;
9144
        case VOID_TYPE:
9145
          /* This signifies an endlink, if no arguments remain, return
9146
             true, otherwise return false.  */
9147
          res = arglist == 0;
9148
          goto end;
9149
        default:
9150
          /* If no parameters remain or the parameter's code does not
9151
             match the specified code, return false.  Otherwise continue
9152
             checking any remaining arguments.  */
9153
          if (arglist == 0)
9154
            goto end;
9155
          if (code == POINTER_TYPE)
9156
            {
9157
              if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9158
                goto end;
9159
            }
9160
          else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9161
            goto end;
9162
          break;
9163
        }
9164
      arglist = TREE_CHAIN (arglist);
9165
    }
9166
  while (1);
9167
 
9168
  /* We need gotos here since we can only have one VA_CLOSE in a
9169
     function.  */
9170
 end: ;
9171
  va_end (ap);
9172
 
9173
  return res;
9174
}
9175
 
9176
/* Default target-specific builtin expander that does nothing.  */
9177
 
9178
rtx
9179
default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9180
                        rtx target ATTRIBUTE_UNUSED,
9181
                        rtx subtarget ATTRIBUTE_UNUSED,
9182
                        enum machine_mode mode ATTRIBUTE_UNUSED,
9183
                        int ignore ATTRIBUTE_UNUSED)
9184
{
9185
  return NULL_RTX;
9186
}
9187
 
9188
/* Returns true is EXP represents data that would potentially reside
9189
   in a readonly section.  */
9190
 
9191
static bool
9192
readonly_data_expr (tree exp)
9193
{
9194
  STRIP_NOPS (exp);
9195
 
9196
  if (TREE_CODE (exp) != ADDR_EXPR)
9197
    return false;
9198
 
9199
  exp = get_base_address (TREE_OPERAND (exp, 0));
9200
  if (!exp)
9201
    return false;
9202
 
9203
  /* Make sure we call decl_readonly_section only for trees it
9204
     can handle (since it returns true for everything it doesn't
9205
     understand).  */
9206
  if (TREE_CODE (exp) == STRING_CST
9207
      || TREE_CODE (exp) == CONSTRUCTOR
9208
      || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9209
    return decl_readonly_section (exp, 0);
9210
  else
9211
    return false;
9212
}
9213
 
9214
/* Simplify a call to the strstr builtin.
9215
 
9216
   Return 0 if no simplification was possible, otherwise return the
9217
   simplified form of the call as a tree.
9218
 
9219
   The simplified form may be a constant or other expression which
9220
   computes the same value, but in a more efficient manner (including
9221
   calls to other builtin functions).
9222
 
9223
   The call may contain arguments which need to be evaluated, but
9224
   which are not useful to determine the result of the call.  In
9225
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9226
   COMPOUND_EXPR will be an argument which must be evaluated.
9227
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9228
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9229
   form of the builtin function call.  */
9230
 
9231
static tree
9232
fold_builtin_strstr (tree arglist, tree type)
9233
{
9234
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9235
    return 0;
9236
  else
9237
    {
9238
      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9239
      tree fn;
9240
      const char *p1, *p2;
9241
 
9242
      p2 = c_getstr (s2);
9243
      if (p2 == NULL)
9244
        return 0;
9245
 
9246
      p1 = c_getstr (s1);
9247
      if (p1 != NULL)
9248
        {
9249
          const char *r = strstr (p1, p2);
9250
          tree tem;
9251
 
9252
          if (r == NULL)
9253
            return build_int_cst (TREE_TYPE (s1), 0);
9254
 
9255
          /* Return an offset into the constant string argument.  */
9256
          tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9257
                             s1, build_int_cst (TREE_TYPE (s1), r - p1));
9258
          return fold_convert (type, tem);
9259
        }
9260
 
9261
      /* The argument is const char *, and the result is char *, so we need
9262
         a type conversion here to avoid a warning.  */
9263
      if (p2[0] == '\0')
9264
        return fold_convert (type, s1);
9265
 
9266
      if (p2[1] != '\0')
9267
        return 0;
9268
 
9269
      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9270
      if (!fn)
9271
        return 0;
9272
 
9273
      /* New argument list transforming strstr(s1, s2) to
9274
         strchr(s1, s2[0]).  */
9275
      arglist = build_tree_list (NULL_TREE,
9276
                                 build_int_cst (NULL_TREE, p2[0]));
9277
      arglist = tree_cons (NULL_TREE, s1, arglist);
9278
      return build_function_call_expr (fn, arglist);
9279
    }
9280
}
9281
 
9282
/* Simplify a call to the strchr builtin.
9283
 
9284
   Return 0 if no simplification was possible, otherwise return the
9285
   simplified form of the call as a tree.
9286
 
9287
   The simplified form may be a constant or other expression which
9288
   computes the same value, but in a more efficient manner (including
9289
   calls to other builtin functions).
9290
 
9291
   The call may contain arguments which need to be evaluated, but
9292
   which are not useful to determine the result of the call.  In
9293
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9294
   COMPOUND_EXPR will be an argument which must be evaluated.
9295
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9296
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9297
   form of the builtin function call.  */
9298
 
9299
static tree
9300
fold_builtin_strchr (tree arglist, tree type)
9301
{
9302
  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9303
    return 0;
9304
  else
9305
    {
9306
      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9307
      const char *p1;
9308
 
9309
      if (TREE_CODE (s2) != INTEGER_CST)
9310
        return 0;
9311
 
9312
      p1 = c_getstr (s1);
9313
      if (p1 != NULL)
9314
        {
9315
          char c;
9316
          const char *r;
9317
          tree tem;
9318
 
9319
          if (target_char_cast (s2, &c))
9320
            return 0;
9321
 
9322
          r = strchr (p1, c);
9323
 
9324
          if (r == NULL)
9325
            return build_int_cst (TREE_TYPE (s1), 0);
9326
 
9327
          /* Return an offset into the constant string argument.  */
9328
          tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9329
                             s1, build_int_cst (TREE_TYPE (s1), r - p1));
9330
          return fold_convert (type, tem);
9331
        }
9332
      return 0;
9333
    }
9334
}
9335
 
9336
/* Simplify a call to the strrchr builtin.
9337
 
9338
   Return 0 if no simplification was possible, otherwise return the
9339
   simplified form of the call as a tree.
9340
 
9341
   The simplified form may be a constant or other expression which
9342
   computes the same value, but in a more efficient manner (including
9343
   calls to other builtin functions).
9344
 
9345
   The call may contain arguments which need to be evaluated, but
9346
   which are not useful to determine the result of the call.  In
9347
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9348
   COMPOUND_EXPR will be an argument which must be evaluated.
9349
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9350
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9351
   form of the builtin function call.  */
9352
 
9353
static tree
9354
fold_builtin_strrchr (tree arglist, tree type)
9355
{
9356
  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9357
    return 0;
9358
  else
9359
    {
9360
      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9361
      tree fn;
9362
      const char *p1;
9363
 
9364
      if (TREE_CODE (s2) != INTEGER_CST)
9365
        return 0;
9366
 
9367
      p1 = c_getstr (s1);
9368
      if (p1 != NULL)
9369
        {
9370
          char c;
9371
          const char *r;
9372
          tree tem;
9373
 
9374
          if (target_char_cast (s2, &c))
9375
            return 0;
9376
 
9377
          r = strrchr (p1, c);
9378
 
9379
          if (r == NULL)
9380
            return build_int_cst (TREE_TYPE (s1), 0);
9381
 
9382
          /* Return an offset into the constant string argument.  */
9383
          tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9384
                             s1, build_int_cst (TREE_TYPE (s1), r - p1));
9385
          return fold_convert (type, tem);
9386
        }
9387
 
9388
      if (! integer_zerop (s2))
9389
        return 0;
9390
 
9391
      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9392
      if (!fn)
9393
        return 0;
9394
 
9395
      /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9396
      return build_function_call_expr (fn, arglist);
9397
    }
9398
}
9399
 
9400
/* Simplify a call to the strpbrk builtin.
9401
 
9402
   Return 0 if no simplification was possible, otherwise return the
9403
   simplified form of the call as a tree.
9404
 
9405
   The simplified form may be a constant or other expression which
9406
   computes the same value, but in a more efficient manner (including
9407
   calls to other builtin functions).
9408
 
9409
   The call may contain arguments which need to be evaluated, but
9410
   which are not useful to determine the result of the call.  In
9411
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9412
   COMPOUND_EXPR will be an argument which must be evaluated.
9413
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9414
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9415
   form of the builtin function call.  */
9416
 
9417
static tree
9418
fold_builtin_strpbrk (tree arglist, tree type)
9419
{
9420
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9421
    return 0;
9422
  else
9423
    {
9424
      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9425
      tree fn;
9426
      const char *p1, *p2;
9427
 
9428
      p2 = c_getstr (s2);
9429
      if (p2 == NULL)
9430
        return 0;
9431
 
9432
      p1 = c_getstr (s1);
9433
      if (p1 != NULL)
9434
        {
9435
          const char *r = strpbrk (p1, p2);
9436
          tree tem;
9437
 
9438
          if (r == NULL)
9439
            return build_int_cst (TREE_TYPE (s1), 0);
9440
 
9441
          /* Return an offset into the constant string argument.  */
9442
          tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9443
                             s1, build_int_cst (TREE_TYPE (s1), r - p1));
9444
          return fold_convert (type, tem);
9445
        }
9446
 
9447
      if (p2[0] == '\0')
9448
        /* strpbrk(x, "") == NULL.
9449
           Evaluate and ignore s1 in case it had side-effects.  */
9450
        return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9451
 
9452
      if (p2[1] != '\0')
9453
        return 0;  /* Really call strpbrk.  */
9454
 
9455
      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9456
      if (!fn)
9457
        return 0;
9458
 
9459
      /* New argument list transforming strpbrk(s1, s2) to
9460
         strchr(s1, s2[0]).  */
9461
      arglist = build_tree_list (NULL_TREE,
9462
                                 build_int_cst (NULL_TREE, p2[0]));
9463
      arglist = tree_cons (NULL_TREE, s1, arglist);
9464
      return build_function_call_expr (fn, arglist);
9465
    }
9466
}
9467
 
9468
/* Simplify a call to the strcat builtin.
9469
 
9470
   Return 0 if no simplification was possible, otherwise return the
9471
   simplified form of the call as a tree.
9472
 
9473
   The simplified form may be a constant or other expression which
9474
   computes the same value, but in a more efficient manner (including
9475
   calls to other builtin functions).
9476
 
9477
   The call may contain arguments which need to be evaluated, but
9478
   which are not useful to determine the result of the call.  In
9479
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9480
   COMPOUND_EXPR will be an argument which must be evaluated.
9481
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9482
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9483
   form of the builtin function call.  */
9484
 
9485
static tree
9486
fold_builtin_strcat (tree arglist)
9487
{
9488
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9489
    return 0;
9490
  else
9491
    {
9492
      tree dst = TREE_VALUE (arglist),
9493
        src = TREE_VALUE (TREE_CHAIN (arglist));
9494
      const char *p = c_getstr (src);
9495
 
9496
      /* If the string length is zero, return the dst parameter.  */
9497
      if (p && *p == '\0')
9498
        return dst;
9499
 
9500
      return 0;
9501
    }
9502
}
9503
 
9504
/* Simplify a call to the strncat builtin.
9505
 
9506
   Return 0 if no simplification was possible, otherwise return the
9507
   simplified form of the call as a tree.
9508
 
9509
   The simplified form may be a constant or other expression which
9510
   computes the same value, but in a more efficient manner (including
9511
   calls to other builtin functions).
9512
 
9513
   The call may contain arguments which need to be evaluated, but
9514
   which are not useful to determine the result of the call.  In
9515
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9516
   COMPOUND_EXPR will be an argument which must be evaluated.
9517
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9518
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9519
   form of the builtin function call.  */
9520
 
9521
static tree
9522
fold_builtin_strncat (tree arglist)
9523
{
9524
  if (!validate_arglist (arglist,
9525
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9526
    return 0;
9527
  else
9528
    {
9529
      tree dst = TREE_VALUE (arglist);
9530
      tree src = TREE_VALUE (TREE_CHAIN (arglist));
9531
      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9532
      const char *p = c_getstr (src);
9533
 
9534
      /* If the requested length is zero, or the src parameter string
9535
         length is zero, return the dst parameter.  */
9536
      if (integer_zerop (len) || (p && *p == '\0'))
9537
        return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9538
 
9539
      /* If the requested len is greater than or equal to the string
9540
         length, call strcat.  */
9541
      if (TREE_CODE (len) == INTEGER_CST && p
9542
          && compare_tree_int (len, strlen (p)) >= 0)
9543
        {
9544
          tree newarglist
9545
            = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9546
          tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9547
 
9548
          /* If the replacement _DECL isn't initialized, don't do the
9549
             transformation.  */
9550
          if (!fn)
9551
            return 0;
9552
 
9553
          return build_function_call_expr (fn, newarglist);
9554
        }
9555
      return 0;
9556
    }
9557
}
9558
 
9559
/* Simplify a call to the strspn builtin.
9560
 
9561
   Return 0 if no simplification was possible, otherwise return the
9562
   simplified form of the call as a tree.
9563
 
9564
   The simplified form may be a constant or other expression which
9565
   computes the same value, but in a more efficient manner (including
9566
   calls to other builtin functions).
9567
 
9568
   The call may contain arguments which need to be evaluated, but
9569
   which are not useful to determine the result of the call.  In
9570
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9571
   COMPOUND_EXPR will be an argument which must be evaluated.
9572
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9573
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9574
   form of the builtin function call.  */
9575
 
9576
static tree
9577
fold_builtin_strspn (tree arglist)
9578
{
9579
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9580
    return 0;
9581
  else
9582
    {
9583
      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9584
      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9585
 
9586
      /* If both arguments are constants, evaluate at compile-time.  */
9587
      if (p1 && p2)
9588
        {
9589
          const size_t r = strspn (p1, p2);
9590
          return size_int (r);
9591
        }
9592
 
9593
      /* If either argument is "", return 0.  */
9594
      if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9595
        /* Evaluate and ignore both arguments in case either one has
9596
           side-effects.  */
9597
        return omit_two_operands (integer_type_node, integer_zero_node,
9598
                                  s1, s2);
9599
      return 0;
9600
    }
9601
}
9602
 
9603
/* Simplify a call to the strcspn builtin.
9604
 
9605
   Return 0 if no simplification was possible, otherwise return the
9606
   simplified form of the call as a tree.
9607
 
9608
   The simplified form may be a constant or other expression which
9609
   computes the same value, but in a more efficient manner (including
9610
   calls to other builtin functions).
9611
 
9612
   The call may contain arguments which need to be evaluated, but
9613
   which are not useful to determine the result of the call.  In
9614
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9615
   COMPOUND_EXPR will be an argument which must be evaluated.
9616
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9617
   COMPOUND_EXPR in the chain will contain the tree for the simplified
9618
   form of the builtin function call.  */
9619
 
9620
static tree
9621
fold_builtin_strcspn (tree arglist)
9622
{
9623
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9624
    return 0;
9625
  else
9626
    {
9627
      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9628
      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9629
 
9630
      /* If both arguments are constants, evaluate at compile-time.  */
9631
      if (p1 && p2)
9632
        {
9633
          const size_t r = strcspn (p1, p2);
9634
          return size_int (r);
9635
        }
9636
 
9637
      /* If the first argument is "", return 0.  */
9638
      if (p1 && *p1 == '\0')
9639
        {
9640
          /* Evaluate and ignore argument s2 in case it has
9641
             side-effects.  */
9642
          return omit_one_operand (integer_type_node,
9643
                                   integer_zero_node, s2);
9644
        }
9645
 
9646
      /* If the second argument is "", return __builtin_strlen(s1).  */
9647
      if (p2 && *p2 == '\0')
9648
        {
9649
          tree newarglist = build_tree_list (NULL_TREE, s1),
9650
            fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9651
 
9652
          /* If the replacement _DECL isn't initialized, don't do the
9653
             transformation.  */
9654
          if (!fn)
9655
            return 0;
9656
 
9657
          return build_function_call_expr (fn, newarglist);
9658
        }
9659
      return 0;
9660
    }
9661
}
9662
 
9663
/* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9664
   by the builtin will be ignored.  UNLOCKED is true is true if this
9665
   actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9666
   the known length of the string.  Return NULL_TREE if no simplification
9667
   was possible.  */
9668
 
9669
tree
9670
fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9671
{
9672
  tree fn;
9673
  /* If we're using an unlocked function, assume the other unlocked
9674
     functions exist explicitly.  */
9675
  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9676
    : implicit_built_in_decls[BUILT_IN_FPUTC];
9677
  tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9678
    : implicit_built_in_decls[BUILT_IN_FWRITE];
9679
 
9680
  /* If the return value is used, don't do the transformation.  */
9681
  if (!ignore)
9682
    return 0;
9683
 
9684
  /* Verify the arguments in the original call.  */
9685
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9686
    return 0;
9687
 
9688
  if (! len)
9689
    len = c_strlen (TREE_VALUE (arglist), 0);
9690
 
9691
  /* Get the length of the string passed to fputs.  If the length
9692
     can't be determined, punt.  */
9693
  if (!len
9694
      || TREE_CODE (len) != INTEGER_CST)
9695
    return 0;
9696
 
9697
  switch (compare_tree_int (len, 1))
9698
    {
9699
    case -1: /* length is 0, delete the call entirely .  */
9700
      return omit_one_operand (integer_type_node, integer_zero_node,
9701
                               TREE_VALUE (TREE_CHAIN (arglist)));
9702
 
9703
    case 0: /* length is 1, call fputc.  */
9704
      {
9705
        const char *p = c_getstr (TREE_VALUE (arglist));
9706
 
9707
        if (p != NULL)
9708
          {
9709
            /* New argument list transforming fputs(string, stream) to
9710
               fputc(string[0], stream).  */
9711
            arglist = build_tree_list (NULL_TREE,
9712
                                       TREE_VALUE (TREE_CHAIN (arglist)));
9713
            arglist = tree_cons (NULL_TREE,
9714
                                 build_int_cst (NULL_TREE, p[0]),
9715
                                 arglist);
9716
            fn = fn_fputc;
9717
            break;
9718
          }
9719
      }
9720
      /* FALLTHROUGH */
9721
    case 1: /* length is greater than 1, call fwrite.  */
9722
      {
9723
        tree string_arg;
9724
 
9725
        /* If optimizing for size keep fputs.  */
9726
        if (optimize_size)
9727
          return 0;
9728
        string_arg = TREE_VALUE (arglist);
9729
        /* New argument list transforming fputs(string, stream) to
9730
           fwrite(string, 1, len, stream).  */
9731
        arglist = build_tree_list (NULL_TREE,
9732
                                   TREE_VALUE (TREE_CHAIN (arglist)));
9733
        arglist = tree_cons (NULL_TREE, len, arglist);
9734
        arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9735
        arglist = tree_cons (NULL_TREE, string_arg, arglist);
9736
        fn = fn_fwrite;
9737
        break;
9738
      }
9739
    default:
9740
      gcc_unreachable ();
9741
    }
9742
 
9743
  /* If the replacement _DECL isn't initialized, don't do the
9744
     transformation.  */
9745
  if (!fn)
9746
    return 0;
9747
 
9748
  /* These optimizations are only performed when the result is ignored,
9749
     hence there's no need to cast the result to integer_type_node.  */
9750
  return build_function_call_expr (fn, arglist);
9751
}
9752
 
9753
/* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9754
   produced.  False otherwise.  This is done so that we don't output the error
9755
   or warning twice or three times.  */
9756
bool
9757
fold_builtin_next_arg (tree arglist)
9758
{
9759
  tree fntype = TREE_TYPE (current_function_decl);
9760
 
9761
  if (TYPE_ARG_TYPES (fntype) == 0
9762
      || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9763
          == void_type_node))
9764
    {
9765
      error ("%<va_start%> used in function with fixed args");
9766
      return true;
9767
    }
9768
  else if (!arglist)
9769
    {
9770
      /* Evidently an out of date version of <stdarg.h>; can't validate
9771
         va_start's second argument, but can still work as intended.  */
9772
      warning (0, "%<__builtin_next_arg%> called without an argument");
9773
      return true;
9774
    }
9775
  /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9776
     when we checked the arguments and if needed issued a warning.  */
9777
  else if (!TREE_CHAIN (arglist)
9778
           || !integer_zerop (TREE_VALUE (arglist))
9779
           || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9780
           || TREE_CHAIN (TREE_CHAIN (arglist)))
9781
    {
9782
      tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9783
      tree arg = TREE_VALUE (arglist);
9784
 
9785
      if (TREE_CHAIN (arglist))
9786
        {
9787
          error ("%<va_start%> used with too many arguments");
9788
          return true;
9789
        }
9790
 
9791
      /* Strip off all nops for the sake of the comparison.  This
9792
         is not quite the same as STRIP_NOPS.  It does more.
9793
         We must also strip off INDIRECT_EXPR for C++ reference
9794
         parameters.  */
9795
      while (TREE_CODE (arg) == NOP_EXPR
9796
             || TREE_CODE (arg) == CONVERT_EXPR
9797
             || TREE_CODE (arg) == NON_LVALUE_EXPR
9798
             || TREE_CODE (arg) == INDIRECT_REF)
9799
        arg = TREE_OPERAND (arg, 0);
9800
      if (arg != last_parm)
9801
        {
9802
          /* FIXME: Sometimes with the tree optimizers we can get the
9803
             not the last argument even though the user used the last
9804
             argument.  We just warn and set the arg to be the last
9805
             argument so that we will get wrong-code because of
9806
             it.  */
9807
          warning (0, "second parameter of %<va_start%> not last named argument");
9808
        }
9809
      /* We want to verify the second parameter just once before the tree
9810
         optimizers are run and then avoid keeping it in the tree,
9811
         as otherwise we could warn even for correct code like:
9812
         void foo (int i, ...)
9813
         { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9814
      TREE_VALUE (arglist) = integer_zero_node;
9815
      TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9816
    }
9817
  return false;
9818
}
9819
 
9820
 
9821
/* Simplify a call to the sprintf builtin.
9822
 
9823
   Return 0 if no simplification was possible, otherwise return the
9824
   simplified form of the call as a tree.  If IGNORED is true, it means that
9825
   the caller does not use the returned value of the function.  */
9826
 
9827
static tree
9828
fold_builtin_sprintf (tree arglist, int ignored)
9829
{
9830
  tree call, retval, dest, fmt;
9831
  const char *fmt_str = NULL;
9832
 
9833
  /* Verify the required arguments in the original call.  We deal with two
9834
     types of sprintf() calls: 'sprintf (str, fmt)' and
9835
     'sprintf (dest, "%s", orig)'.  */
9836
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9837
      && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9838
                            VOID_TYPE))
9839
    return NULL_TREE;
9840
 
9841
  /* Get the destination string and the format specifier.  */
9842
  dest = TREE_VALUE (arglist);
9843
  fmt = TREE_VALUE (TREE_CHAIN (arglist));
9844
 
9845
  /* Check whether the format is a literal string constant.  */
9846
  fmt_str = c_getstr (fmt);
9847
  if (fmt_str == NULL)
9848
    return NULL_TREE;
9849
 
9850
  call = NULL_TREE;
9851
  retval = NULL_TREE;
9852
 
9853
  if (!init_target_chars())
9854
    return 0;
9855
 
9856
  /* If the format doesn't contain % args or %%, use strcpy.  */
9857
  if (strchr (fmt_str, target_percent) == NULL)
9858
    {
9859
      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9860
 
9861
      if (!fn)
9862
        return NULL_TREE;
9863
 
9864
      /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9865
         'format' is known to contain no % formats.  */
9866
      arglist = build_tree_list (NULL_TREE, fmt);
9867
      arglist = tree_cons (NULL_TREE, dest, arglist);
9868
      call = build_function_call_expr (fn, arglist);
9869
      if (!ignored)
9870
        retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9871
    }
9872
 
9873
  /* If the format is "%s", use strcpy if the result isn't used.  */
9874
  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9875
    {
9876
      tree fn, orig;
9877
      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9878
 
9879
      if (!fn)
9880
        return NULL_TREE;
9881
 
9882
      /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9883
      orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9884
      arglist = build_tree_list (NULL_TREE, orig);
9885
      arglist = tree_cons (NULL_TREE, dest, arglist);
9886
      if (!ignored)
9887
        {
9888
          retval = c_strlen (orig, 1);
9889
          if (!retval || TREE_CODE (retval) != INTEGER_CST)
9890
            return NULL_TREE;
9891
        }
9892
      call = build_function_call_expr (fn, arglist);
9893
    }
9894
 
9895
  if (call && retval)
9896
    {
9897
      retval = convert
9898
        (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9899
         retval);
9900
      return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9901
    }
9902
  else
9903
    return call;
9904
}
9905
 
9906
/* Expand a call to __builtin_object_size.  */
9907
 
9908
rtx
9909
expand_builtin_object_size (tree exp)
9910
{
9911
  tree ost;
9912
  int object_size_type;
9913
  tree fndecl = get_callee_fndecl (exp);
9914
  tree arglist = TREE_OPERAND (exp, 1);
9915
  location_t locus = EXPR_LOCATION (exp);
9916
 
9917
  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9918
    {
9919
      error ("%Hfirst argument of %D must be a pointer, second integer constant",
9920
             &locus, fndecl);
9921
      expand_builtin_trap ();
9922
      return const0_rtx;
9923
    }
9924
 
9925
  ost = TREE_VALUE (TREE_CHAIN (arglist));
9926
  STRIP_NOPS (ost);
9927
 
9928
  if (TREE_CODE (ost) != INTEGER_CST
9929
      || tree_int_cst_sgn (ost) < 0
9930
      || compare_tree_int (ost, 3) > 0)
9931
    {
9932
      error ("%Hlast argument of %D is not integer constant between 0 and 3",
9933
             &locus, fndecl);
9934
      expand_builtin_trap ();
9935
      return const0_rtx;
9936
    }
9937
 
9938
  object_size_type = tree_low_cst (ost, 0);
9939
 
9940
  return object_size_type < 2 ? constm1_rtx : const0_rtx;
9941
}
9942
 
9943
/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9944
   FCODE is the BUILT_IN_* to use.
9945
   Return 0 if we failed; the caller should emit a normal call,
9946
   otherwise try to get the result in TARGET, if convenient (and in
9947
   mode MODE if that's convenient).  */
9948
 
9949
static rtx
9950
expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9951
                           enum built_in_function fcode)
9952
{
9953
  tree arglist = TREE_OPERAND (exp, 1);
9954
  tree dest, src, len, size;
9955
 
9956
  if (!validate_arglist (arglist,
9957
                         POINTER_TYPE,
9958
                         fcode == BUILT_IN_MEMSET_CHK
9959
                         ? INTEGER_TYPE : POINTER_TYPE,
9960
                         INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9961
    return 0;
9962
 
9963
  dest = TREE_VALUE (arglist);
9964
  src = TREE_VALUE (TREE_CHAIN (arglist));
9965
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9966
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9967
 
9968
  if (! host_integerp (size, 1))
9969
    return 0;
9970
 
9971
  if (host_integerp (len, 1) || integer_all_onesp (size))
9972
    {
9973
      tree fn;
9974
 
9975
      if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9976
        {
9977
          location_t locus = EXPR_LOCATION (exp);
9978
          warning (0, "%Hcall to %D will always overflow destination buffer",
9979
                   &locus, get_callee_fndecl (exp));
9980
          return 0;
9981
        }
9982
 
9983
      arglist = build_tree_list (NULL_TREE, len);
9984
      arglist = tree_cons (NULL_TREE, src, arglist);
9985
      arglist = tree_cons (NULL_TREE, dest, arglist);
9986
 
9987
      fn = NULL_TREE;
9988
      /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9989
         mem{cpy,pcpy,move,set} is available.  */
9990
      switch (fcode)
9991
        {
9992
        case BUILT_IN_MEMCPY_CHK:
9993
          fn = built_in_decls[BUILT_IN_MEMCPY];
9994
          break;
9995
        case BUILT_IN_MEMPCPY_CHK:
9996
          fn = built_in_decls[BUILT_IN_MEMPCPY];
9997
          break;
9998
        case BUILT_IN_MEMMOVE_CHK:
9999
          fn = built_in_decls[BUILT_IN_MEMMOVE];
10000
          break;
10001
        case BUILT_IN_MEMSET_CHK:
10002
          fn = built_in_decls[BUILT_IN_MEMSET];
10003
          break;
10004
        default:
10005
          break;
10006
        }
10007
 
10008
      if (! fn)
10009
        return 0;
10010
 
10011
      fn = build_function_call_expr (fn, arglist);
10012
      if (TREE_CODE (fn) == CALL_EXPR)
10013
        CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10014
      return expand_expr (fn, target, mode, EXPAND_NORMAL);
10015
    }
10016
  else if (fcode == BUILT_IN_MEMSET_CHK)
10017
    return 0;
10018
  else
10019
    {
10020
      unsigned int dest_align
10021
        = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10022
 
10023
      /* If DEST is not a pointer type, call the normal function.  */
10024
      if (dest_align == 0)
10025
        return 0;
10026
 
10027
      /* If SRC and DEST are the same (and not volatile), do nothing.  */
10028
      if (operand_equal_p (src, dest, 0))
10029
        {
10030
          tree expr;
10031
 
10032
          if (fcode != BUILT_IN_MEMPCPY_CHK)
10033
            {
10034
              /* Evaluate and ignore LEN in case it has side-effects.  */
10035
              expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10036
              return expand_expr (dest, target, mode, EXPAND_NORMAL);
10037
            }
10038
 
10039
          len = fold_convert (TREE_TYPE (dest), len);
10040
          expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10041
          return expand_expr (expr, target, mode, EXPAND_NORMAL);
10042
        }
10043
 
10044
      /* __memmove_chk special case.  */
10045
      if (fcode == BUILT_IN_MEMMOVE_CHK)
10046
        {
10047
          unsigned int src_align
10048
            = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10049
 
10050
          if (src_align == 0)
10051
            return 0;
10052
 
10053
          /* If src is categorized for a readonly section we can use
10054
             normal __memcpy_chk.  */
10055
          if (readonly_data_expr (src))
10056
            {
10057
              tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10058
              if (!fn)
10059
                return 0;
10060
              fn = build_function_call_expr (fn, arglist);
10061
              if (TREE_CODE (fn) == CALL_EXPR)
10062
                CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10063
              return expand_expr (fn, target, mode, EXPAND_NORMAL);
10064
            }
10065
        }
10066
      return 0;
10067
    }
10068
}
10069
 
10070
/* Emit warning if a buffer overflow is detected at compile time.  */
10071
 
10072
static void
10073
maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10074
{
10075
  int arg_mask, is_strlen = 0;
10076
  tree arglist = TREE_OPERAND (exp, 1), a;
10077
  tree len, size;
10078
  location_t locus;
10079
 
10080
  switch (fcode)
10081
    {
10082
    case BUILT_IN_STRCPY_CHK:
10083
    case BUILT_IN_STPCPY_CHK:
10084
    /* For __strcat_chk the warning will be emitted only if overflowing
10085
       by at least strlen (dest) + 1 bytes.  */
10086
    case BUILT_IN_STRCAT_CHK:
10087
      arg_mask = 6;
10088
      is_strlen = 1;
10089
      break;
10090
    case BUILT_IN_STRNCPY_CHK:
10091
      arg_mask = 12;
10092
      break;
10093
    case BUILT_IN_SNPRINTF_CHK:
10094
    case BUILT_IN_VSNPRINTF_CHK:
10095
      arg_mask = 10;
10096
      break;
10097
    default:
10098
      gcc_unreachable ();
10099
    }
10100
 
10101
  len = NULL_TREE;
10102
  size = NULL_TREE;
10103
  for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10104
    if (arg_mask & 1)
10105
      {
10106
        if (len)
10107
          size = a;
10108
        else
10109
          len = a;
10110
      }
10111
 
10112
  if (!len || !size)
10113
    return;
10114
 
10115
  len = TREE_VALUE (len);
10116
  size = TREE_VALUE (size);
10117
 
10118
  if (! host_integerp (size, 1) || integer_all_onesp (size))
10119
    return;
10120
 
10121
  if (is_strlen)
10122
    {
10123
      len = c_strlen (len, 1);
10124
      if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10125
        return;
10126
    }
10127
  else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10128
    return;
10129
 
10130
  locus = EXPR_LOCATION (exp);
10131
  warning (0, "%Hcall to %D will always overflow destination buffer",
10132
           &locus, get_callee_fndecl (exp));
10133
}
10134
 
10135
/* Emit warning if a buffer overflow is detected at compile time
10136
   in __sprintf_chk/__vsprintf_chk calls.  */
10137
 
10138
static void
10139
maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10140
{
10141
  tree arglist = TREE_OPERAND (exp, 1);
10142
  tree dest, size, len, fmt, flag;
10143
  const char *fmt_str;
10144
 
10145
  /* Verify the required arguments in the original call.  */
10146
  if (! arglist)
10147
    return;
10148
  dest = TREE_VALUE (arglist);
10149
  arglist = TREE_CHAIN (arglist);
10150
  if (! arglist)
10151
    return;
10152
  flag = TREE_VALUE (arglist);
10153
  arglist = TREE_CHAIN (arglist);
10154
  if (! arglist)
10155
    return;
10156
  size = TREE_VALUE (arglist);
10157
  arglist = TREE_CHAIN (arglist);
10158
  if (! arglist)
10159
    return;
10160
  fmt = TREE_VALUE (arglist);
10161
  arglist = TREE_CHAIN (arglist);
10162
 
10163
  if (! host_integerp (size, 1) || integer_all_onesp (size))
10164
    return;
10165
 
10166
  /* Check whether the format is a literal string constant.  */
10167
  fmt_str = c_getstr (fmt);
10168
  if (fmt_str == NULL)
10169
    return;
10170
 
10171
  if (!init_target_chars())
10172
    return;
10173
 
10174
  /* If the format doesn't contain % args or %%, we know its size.  */
10175
  if (strchr (fmt_str, target_percent) == 0)
10176
    len = build_int_cstu (size_type_node, strlen (fmt_str));
10177
  /* If the format is "%s" and first ... argument is a string literal,
10178
     we know it too.  */
10179
  else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10180
    {
10181
      tree arg;
10182
 
10183
      if (! arglist)
10184
        return;
10185
      arg = TREE_VALUE (arglist);
10186
      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10187
        return;
10188
 
10189
      len = c_strlen (arg, 1);
10190
      if (!len || ! host_integerp (len, 1))
10191
        return;
10192
    }
10193
  else
10194
    return;
10195
 
10196
  if (! tree_int_cst_lt (len, size))
10197
    {
10198
      location_t locus = EXPR_LOCATION (exp);
10199
      warning (0, "%Hcall to %D will always overflow destination buffer",
10200
               &locus, get_callee_fndecl (exp));
10201
    }
10202
}
10203
 
10204
/* Fold a call to __builtin_object_size, if possible.  */
10205
 
10206
tree
10207
fold_builtin_object_size (tree arglist)
10208
{
10209
  tree ptr, ost, ret = 0;
10210
  int object_size_type;
10211
 
10212
  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10213
    return 0;
10214
 
10215
  ptr = TREE_VALUE (arglist);
10216
  ost = TREE_VALUE (TREE_CHAIN (arglist));
10217
  STRIP_NOPS (ost);
10218
 
10219
  if (TREE_CODE (ost) != INTEGER_CST
10220
      || tree_int_cst_sgn (ost) < 0
10221
      || compare_tree_int (ost, 3) > 0)
10222
    return 0;
10223
 
10224
  object_size_type = tree_low_cst (ost, 0);
10225
 
10226
  /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10227
     if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10228
     and (size_t) 0 for types 2 and 3.  */
10229
  if (TREE_SIDE_EFFECTS (ptr))
10230
    return fold_convert (size_type_node,
10231
                         object_size_type < 2
10232
                         ? integer_minus_one_node : integer_zero_node);
10233
 
10234
  if (TREE_CODE (ptr) == ADDR_EXPR)
10235
    ret = build_int_cstu (size_type_node,
10236
                        compute_builtin_object_size (ptr, object_size_type));
10237
 
10238
  else if (TREE_CODE (ptr) == SSA_NAME)
10239
    {
10240
      unsigned HOST_WIDE_INT bytes;
10241
 
10242
      /* If object size is not known yet, delay folding until
10243
       later.  Maybe subsequent passes will help determining
10244
       it.  */
10245
      bytes = compute_builtin_object_size (ptr, object_size_type);
10246
      if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10247
                                             ? -1 : 0))
10248
        ret = build_int_cstu (size_type_node, bytes);
10249
    }
10250
 
10251
  if (ret)
10252
    {
10253
      ret = force_fit_type (ret, -1, false, false);
10254
      if (TREE_CONSTANT_OVERFLOW (ret))
10255
        ret = 0;
10256
    }
10257
 
10258
  return ret;
10259
}
10260
 
10261
/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10262
   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10263
   code of the builtin.  If MAXLEN is not NULL, it is maximum length
10264
   passed as third argument.  */
10265
 
10266
tree
10267
fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10268
                         enum built_in_function fcode)
10269
{
10270
  tree dest, src, len, size, fn;
10271
 
10272
  if (!validate_arglist (arglist,
10273
                         POINTER_TYPE,
10274
                         fcode == BUILT_IN_MEMSET_CHK
10275
                         ? INTEGER_TYPE : POINTER_TYPE,
10276
                         INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10277
    return 0;
10278
 
10279
  dest = TREE_VALUE (arglist);
10280
  /* Actually val for __memset_chk, but it doesn't matter.  */
10281
  src = TREE_VALUE (TREE_CHAIN (arglist));
10282
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10283
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10284
 
10285
  /* If SRC and DEST are the same (and not volatile), return DEST
10286
     (resp. DEST+LEN for __mempcpy_chk).  */
10287
  if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10288
    {
10289
      if (fcode != BUILT_IN_MEMPCPY_CHK)
10290
        return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10291
      else
10292
        {
10293
          tree temp = fold_convert (TREE_TYPE (dest), len);
10294
          temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10295
          return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10296
        }
10297
    }
10298
 
10299
  if (! host_integerp (size, 1))
10300
    return 0;
10301
 
10302
  if (! integer_all_onesp (size))
10303
    {
10304
      if (! host_integerp (len, 1))
10305
        {
10306
          /* If LEN is not constant, try MAXLEN too.
10307
             For MAXLEN only allow optimizing into non-_ocs function
10308
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10309
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10310
            {
10311
              if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10312
                {
10313
                  /* (void) __mempcpy_chk () can be optimized into
10314
                     (void) __memcpy_chk ().  */
10315
                  fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10316
                  if (!fn)
10317
                    return 0;
10318
 
10319
                  return build_function_call_expr (fn, arglist);
10320
                }
10321
              return 0;
10322
            }
10323
        }
10324
      else
10325
        maxlen = len;
10326
 
10327
      if (tree_int_cst_lt (size, maxlen))
10328
        return 0;
10329
    }
10330
 
10331
  arglist = build_tree_list (NULL_TREE, len);
10332
  arglist = tree_cons (NULL_TREE, src, arglist);
10333
  arglist = tree_cons (NULL_TREE, dest, arglist);
10334
 
10335
  fn = NULL_TREE;
10336
  /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10337
     mem{cpy,pcpy,move,set} is available.  */
10338
  switch (fcode)
10339
    {
10340
    case BUILT_IN_MEMCPY_CHK:
10341
      fn = built_in_decls[BUILT_IN_MEMCPY];
10342
      break;
10343
    case BUILT_IN_MEMPCPY_CHK:
10344
      fn = built_in_decls[BUILT_IN_MEMPCPY];
10345
      break;
10346
    case BUILT_IN_MEMMOVE_CHK:
10347
      fn = built_in_decls[BUILT_IN_MEMMOVE];
10348
      break;
10349
    case BUILT_IN_MEMSET_CHK:
10350
      fn = built_in_decls[BUILT_IN_MEMSET];
10351
      break;
10352
    default:
10353
      break;
10354
    }
10355
 
10356
  if (!fn)
10357
    return 0;
10358
 
10359
  return build_function_call_expr (fn, arglist);
10360
}
10361
 
10362
/* Fold a call to the __st[rp]cpy_chk builtin.
10363
   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10364
   code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10365
   strings passed as second argument.  */
10366
 
10367
tree
10368
fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10369
                         enum built_in_function fcode)
10370
{
10371
  tree dest, src, size, len, fn;
10372
 
10373
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10374
                         VOID_TYPE))
10375
    return 0;
10376
 
10377
  dest = TREE_VALUE (arglist);
10378
  src = TREE_VALUE (TREE_CHAIN (arglist));
10379
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10380
 
10381
  /* If SRC and DEST are the same (and not volatile), return DEST.  */
10382
  if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10383
    return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10384
 
10385
  if (! host_integerp (size, 1))
10386
    return 0;
10387
 
10388
  if (! integer_all_onesp (size))
10389
    {
10390
      len = c_strlen (src, 1);
10391
      if (! len || ! host_integerp (len, 1))
10392
        {
10393
          /* If LEN is not constant, try MAXLEN too.
10394
             For MAXLEN only allow optimizing into non-_ocs function
10395
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10396
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10397
            {
10398
              if (fcode == BUILT_IN_STPCPY_CHK)
10399
                {
10400
                  if (! ignore)
10401
                    return 0;
10402
 
10403
                  /* If return value of __stpcpy_chk is ignored,
10404
                     optimize into __strcpy_chk.  */
10405
                  fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10406
                  if (!fn)
10407
                    return 0;
10408
 
10409
                  return build_function_call_expr (fn, arglist);
10410
                }
10411
 
10412
              if (! len || TREE_SIDE_EFFECTS (len))
10413
                return 0;
10414
 
10415
              /* If c_strlen returned something, but not a constant,
10416
                 transform __strcpy_chk into __memcpy_chk.  */
10417
              fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10418
              if (!fn)
10419
                return 0;
10420
 
10421
              len = size_binop (PLUS_EXPR, len, ssize_int (1));
10422
              arglist = build_tree_list (NULL_TREE, size);
10423
              arglist = tree_cons (NULL_TREE, len, arglist);
10424
              arglist = tree_cons (NULL_TREE, src, arglist);
10425
              arglist = tree_cons (NULL_TREE, dest, arglist);
10426
              return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10427
                                   build_function_call_expr (fn, arglist));
10428
            }
10429
        }
10430
      else
10431
        maxlen = len;
10432
 
10433
      if (! tree_int_cst_lt (maxlen, size))
10434
        return 0;
10435
    }
10436
 
10437
  arglist = build_tree_list (NULL_TREE, src);
10438
  arglist = tree_cons (NULL_TREE, dest, arglist);
10439
 
10440
  /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10441
  fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10442
                      ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10443
  if (!fn)
10444
    return 0;
10445
 
10446
  return build_function_call_expr (fn, arglist);
10447
}
10448
 
10449
/* Fold a call to the __strncpy_chk builtin.
10450
   If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10451
 
10452
tree
10453
fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10454
{
10455
  tree dest, src, size, len, fn;
10456
 
10457
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10458
                         INTEGER_TYPE, VOID_TYPE))
10459
    return 0;
10460
 
10461
  dest = TREE_VALUE (arglist);
10462
  src = TREE_VALUE (TREE_CHAIN (arglist));
10463
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10464
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10465
 
10466
  if (! host_integerp (size, 1))
10467
    return 0;
10468
 
10469
  if (! integer_all_onesp (size))
10470
    {
10471
      if (! host_integerp (len, 1))
10472
        {
10473
          /* If LEN is not constant, try MAXLEN too.
10474
             For MAXLEN only allow optimizing into non-_ocs function
10475
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10476
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10477
            return 0;
10478
        }
10479
      else
10480
        maxlen = len;
10481
 
10482
      if (tree_int_cst_lt (size, maxlen))
10483
        return 0;
10484
    }
10485
 
10486
  arglist = build_tree_list (NULL_TREE, len);
10487
  arglist = tree_cons (NULL_TREE, src, arglist);
10488
  arglist = tree_cons (NULL_TREE, dest, arglist);
10489
 
10490
  /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10491
  fn = built_in_decls[BUILT_IN_STRNCPY];
10492
  if (!fn)
10493
    return 0;
10494
 
10495
  return build_function_call_expr (fn, arglist);
10496
}
10497
 
10498
/* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10499
 
10500
static tree
10501
fold_builtin_strcat_chk (tree fndecl, tree arglist)
10502
{
10503
  tree dest, src, size, fn;
10504
  const char *p;
10505
 
10506
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10507
                         VOID_TYPE))
10508
    return 0;
10509
 
10510
  dest = TREE_VALUE (arglist);
10511
  src = TREE_VALUE (TREE_CHAIN (arglist));
10512
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10513
 
10514
  p = c_getstr (src);
10515
  /* If the SRC parameter is "", return DEST.  */
10516
  if (p && *p == '\0')
10517
    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10518
 
10519
  if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10520
    return 0;
10521
 
10522
  arglist = build_tree_list (NULL_TREE, src);
10523
  arglist = tree_cons (NULL_TREE, dest, arglist);
10524
 
10525
  /* If __builtin_strcat_chk is used, assume strcat is available.  */
10526
  fn = built_in_decls[BUILT_IN_STRCAT];
10527
  if (!fn)
10528
    return 0;
10529
 
10530
  return build_function_call_expr (fn, arglist);
10531
}
10532
 
10533
/* Fold a call to the __strncat_chk builtin EXP.  */
10534
 
10535
static tree
10536
fold_builtin_strncat_chk (tree fndecl, tree arglist)
10537
{
10538
  tree dest, src, size, len, fn;
10539
  const char *p;
10540
 
10541
  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10542
                         INTEGER_TYPE, VOID_TYPE))
10543
    return 0;
10544
 
10545
  dest = TREE_VALUE (arglist);
10546
  src = TREE_VALUE (TREE_CHAIN (arglist));
10547
  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10548
  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10549
 
10550
  p = c_getstr (src);
10551
  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10552
  if (p && *p == '\0')
10553
    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10554
  else if (integer_zerop (len))
10555
    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10556
 
10557
  if (! host_integerp (size, 1))
10558
    return 0;
10559
 
10560
  if (! integer_all_onesp (size))
10561
    {
10562
      tree src_len = c_strlen (src, 1);
10563
      if (src_len
10564
          && host_integerp (src_len, 1)
10565
          && host_integerp (len, 1)
10566
          && ! tree_int_cst_lt (len, src_len))
10567
        {
10568
          /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10569
          fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10570
          if (!fn)
10571
            return 0;
10572
 
10573
          arglist = build_tree_list (NULL_TREE, size);
10574
          arglist = tree_cons (NULL_TREE, src, arglist);
10575
          arglist = tree_cons (NULL_TREE, dest, arglist);
10576
          return build_function_call_expr (fn, arglist);
10577
        }
10578
      return 0;
10579
    }
10580
 
10581
  arglist = build_tree_list (NULL_TREE, len);
10582
  arglist = tree_cons (NULL_TREE, src, arglist);
10583
  arglist = tree_cons (NULL_TREE, dest, arglist);
10584
 
10585
  /* If __builtin_strncat_chk is used, assume strncat is available.  */
10586
  fn = built_in_decls[BUILT_IN_STRNCAT];
10587
  if (!fn)
10588
    return 0;
10589
 
10590
  return build_function_call_expr (fn, arglist);
10591
}
10592
 
10593
/* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10594
   a normal call should be emitted rather than expanding the function
10595
   inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10596
 
10597
static tree
10598
fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10599
{
10600
  tree dest, size, len, fn, fmt, flag;
10601
  const char *fmt_str;
10602
 
10603
  /* Verify the required arguments in the original call.  */
10604
  if (! arglist)
10605
    return 0;
10606
  dest = TREE_VALUE (arglist);
10607
  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10608
    return 0;
10609
  arglist = TREE_CHAIN (arglist);
10610
  if (! arglist)
10611
    return 0;
10612
  flag = TREE_VALUE (arglist);
10613
  if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10614
    return 0;
10615
  arglist = TREE_CHAIN (arglist);
10616
  if (! arglist)
10617
    return 0;
10618
  size = TREE_VALUE (arglist);
10619
  if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10620
    return 0;
10621
  arglist = TREE_CHAIN (arglist);
10622
  if (! arglist)
10623
    return 0;
10624
  fmt = TREE_VALUE (arglist);
10625
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10626
    return 0;
10627
  arglist = TREE_CHAIN (arglist);
10628
 
10629
  if (! host_integerp (size, 1))
10630
    return 0;
10631
 
10632
  len = NULL_TREE;
10633
 
10634
  if (!init_target_chars())
10635
    return 0;
10636
 
10637
  /* Check whether the format is a literal string constant.  */
10638
  fmt_str = c_getstr (fmt);
10639
  if (fmt_str != NULL)
10640
    {
10641
      /* If the format doesn't contain % args or %%, we know the size.  */
10642
      if (strchr (fmt_str, target_percent) == 0)
10643
        {
10644
          if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10645
            len = build_int_cstu (size_type_node, strlen (fmt_str));
10646
        }
10647
      /* If the format is "%s" and first ... argument is a string literal,
10648
         we know the size too.  */
10649
      else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10650
        {
10651
          tree arg;
10652
 
10653
          if (arglist && !TREE_CHAIN (arglist))
10654
            {
10655
              arg = TREE_VALUE (arglist);
10656
              if (POINTER_TYPE_P (TREE_TYPE (arg)))
10657
                {
10658
                  len = c_strlen (arg, 1);
10659
                  if (! len || ! host_integerp (len, 1))
10660
                    len = NULL_TREE;
10661
                }
10662
            }
10663
        }
10664
    }
10665
 
10666
  if (! integer_all_onesp (size))
10667
    {
10668
      if (! len || ! tree_int_cst_lt (len, size))
10669
        return 0;
10670
    }
10671
 
10672
  /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10673
     or if format doesn't contain % chars or is "%s".  */
10674
  if (! integer_zerop (flag))
10675
    {
10676
      if (fmt_str == NULL)
10677
        return 0;
10678
      if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10679
        return 0;
10680
    }
10681
 
10682
  arglist = tree_cons (NULL_TREE, fmt, arglist);
10683
  arglist = tree_cons (NULL_TREE, dest, arglist);
10684
 
10685
  /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
10686
  fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10687
                      ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10688
  if (!fn)
10689
    return 0;
10690
 
10691
  return build_function_call_expr (fn, arglist);
10692
}
10693
 
10694
/* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
10695
   a normal call should be emitted rather than expanding the function
10696
   inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
10697
   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
10698
   passed as second argument.  */
10699
 
10700
tree
10701
fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10702
                           enum built_in_function fcode)
10703
{
10704
  tree dest, size, len, fn, fmt, flag;
10705
  const char *fmt_str;
10706
 
10707
  /* Verify the required arguments in the original call.  */
10708
  if (! arglist)
10709
    return 0;
10710
  dest = TREE_VALUE (arglist);
10711
  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10712
    return 0;
10713
  arglist = TREE_CHAIN (arglist);
10714
  if (! arglist)
10715
    return 0;
10716
  len = TREE_VALUE (arglist);
10717
  if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10718
    return 0;
10719
  arglist = TREE_CHAIN (arglist);
10720
  if (! arglist)
10721
    return 0;
10722
  flag = TREE_VALUE (arglist);
10723
  if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10724
    return 0;
10725
  arglist = TREE_CHAIN (arglist);
10726
  if (! arglist)
10727
    return 0;
10728
  size = TREE_VALUE (arglist);
10729
  if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10730
    return 0;
10731
  arglist = TREE_CHAIN (arglist);
10732
  if (! arglist)
10733
    return 0;
10734
  fmt = TREE_VALUE (arglist);
10735
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10736
    return 0;
10737
  arglist = TREE_CHAIN (arglist);
10738
 
10739
  if (! host_integerp (size, 1))
10740
    return 0;
10741
 
10742
  if (! integer_all_onesp (size))
10743
    {
10744
      if (! host_integerp (len, 1))
10745
        {
10746
          /* If LEN is not constant, try MAXLEN too.
10747
             For MAXLEN only allow optimizing into non-_ocs function
10748
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10749
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10750
            return 0;
10751
        }
10752
      else
10753
        maxlen = len;
10754
 
10755
      if (tree_int_cst_lt (size, maxlen))
10756
        return 0;
10757
    }
10758
 
10759
  if (!init_target_chars())
10760
    return 0;
10761
 
10762
  /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10763
     or if format doesn't contain % chars or is "%s".  */
10764
  if (! integer_zerop (flag))
10765
    {
10766
      fmt_str = c_getstr (fmt);
10767
      if (fmt_str == NULL)
10768
        return 0;
10769
      if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10770
        return 0;
10771
    }
10772
 
10773
  arglist = tree_cons (NULL_TREE, fmt, arglist);
10774
  arglist = tree_cons (NULL_TREE, len, arglist);
10775
  arglist = tree_cons (NULL_TREE, dest, arglist);
10776
 
10777
  /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10778
     available.  */
10779
  fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10780
                      ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10781
  if (!fn)
10782
    return 0;
10783
 
10784
  return build_function_call_expr (fn, arglist);
10785
}
10786
 
10787
/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10788
 
10789
   Return 0 if no simplification was possible, otherwise return the
10790
   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10791
   code of the function to be simplified.  */
10792
 
10793
static tree
10794
fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10795
                     enum built_in_function fcode)
10796
{
10797
  tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10798
  const char *fmt_str = NULL;
10799
 
10800
  /* If the return value is used, don't do the transformation.  */
10801
  if (! ignore)
10802
    return 0;
10803
 
10804
  /* Verify the required arguments in the original call.  */
10805
  if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10806
    {
10807
      tree flag;
10808
 
10809
      if (! arglist)
10810
        return 0;
10811
      flag = TREE_VALUE (arglist);
10812
      if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10813
          || TREE_SIDE_EFFECTS (flag))
10814
        return 0;
10815
      arglist = TREE_CHAIN (arglist);
10816
    }
10817
 
10818
  if (! arglist)
10819
    return 0;
10820
  fmt = TREE_VALUE (arglist);
10821
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10822
    return 0;
10823
  arglist = TREE_CHAIN (arglist);
10824
 
10825
  /* Check whether the format is a literal string constant.  */
10826
  fmt_str = c_getstr (fmt);
10827
  if (fmt_str == NULL)
10828
    return NULL_TREE;
10829
 
10830
  if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10831
    {
10832
      /* If we're using an unlocked function, assume the other
10833
         unlocked functions exist explicitly.  */
10834
      fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10835
      fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10836
    }
10837
  else
10838
    {
10839
      fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10840
      fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10841
    }
10842
 
10843
  if (!init_target_chars())
10844
    return 0;
10845
 
10846
  if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10847
    {
10848
      const char *str;
10849
 
10850
      if (strcmp (fmt_str, target_percent_s) == 0)
10851
        {
10852
          if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10853
            return 0;
10854
 
10855
          if (! arglist
10856
              || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10857
              || TREE_CHAIN (arglist))
10858
            return 0;
10859
 
10860
          str = c_getstr (TREE_VALUE (arglist));
10861
          if (str == NULL)
10862
            return 0;
10863
        }
10864
      else
10865
        {
10866
          /* The format specifier doesn't contain any '%' characters.  */
10867
          if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10868
              && arglist)
10869
            return 0;
10870
          str = fmt_str;
10871
        }
10872
 
10873
      /* If the string was "", printf does nothing.  */
10874
      if (str[0] == '\0')
10875
        return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10876
 
10877
      /* If the string has length of 1, call putchar.  */
10878
      if (str[1] == '\0')
10879
        {
10880
          /* Given printf("c"), (where c is any one character,)
10881
             convert "c"[0] to an int and pass that to the replacement
10882
             function.  */
10883
          arg = build_int_cst (NULL_TREE, str[0]);
10884
          arglist = build_tree_list (NULL_TREE, arg);
10885
          fn = fn_putchar;
10886
        }
10887
      else
10888
        {
10889
          /* If the string was "string\n", call puts("string").  */
10890
          size_t len = strlen (str);
10891
          if ((unsigned char)str[len - 1] == target_newline)
10892
            {
10893
              /* Create a NUL-terminated string that's one char shorter
10894
                 than the original, stripping off the trailing '\n'.  */
10895
              char *newstr = alloca (len);
10896
              memcpy (newstr, str, len - 1);
10897
              newstr[len - 1] = 0;
10898
 
10899
              arg = build_string_literal (len, newstr);
10900
              arglist = build_tree_list (NULL_TREE, arg);
10901
              fn = fn_puts;
10902
            }
10903
          else
10904
            /* We'd like to arrange to call fputs(string,stdout) here,
10905
               but we need stdout and don't have a way to get it yet.  */
10906
            return 0;
10907
        }
10908
    }
10909
 
10910
  /* The other optimizations can be done only on the non-va_list variants.  */
10911
  else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10912
    return 0;
10913
 
10914
  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
10915
  else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10916
    {
10917
      if (! arglist
10918
          || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10919
          || TREE_CHAIN (arglist))
10920
        return 0;
10921
      fn = fn_puts;
10922
    }
10923
 
10924
  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
10925
  else if (strcmp (fmt_str, target_percent_c) == 0)
10926
    {
10927
      if (! arglist
10928
          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10929
          || TREE_CHAIN (arglist))
10930
        return 0;
10931
      fn = fn_putchar;
10932
    }
10933
 
10934
  if (!fn)
10935
    return 0;
10936
 
10937
  call = build_function_call_expr (fn, arglist);
10938
  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10939
}
10940
 
10941
/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10942
 
10943
   Return 0 if no simplification was possible, otherwise return the
10944
   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10945
   code of the function to be simplified.  */
10946
 
10947
static tree
10948
fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10949
                      enum built_in_function fcode)
10950
{
10951
  tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10952
  const char *fmt_str = NULL;
10953
 
10954
  /* If the return value is used, don't do the transformation.  */
10955
  if (! ignore)
10956
    return 0;
10957
 
10958
  /* Verify the required arguments in the original call.  */
10959
  if (! arglist)
10960
    return 0;
10961
  fp = TREE_VALUE (arglist);
10962
  if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10963
    return 0;
10964
  arglist = TREE_CHAIN (arglist);
10965
 
10966
  if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10967
    {
10968
      tree flag;
10969
 
10970
      if (! arglist)
10971
        return 0;
10972
      flag = TREE_VALUE (arglist);
10973
      if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10974
          || TREE_SIDE_EFFECTS (flag))
10975
        return 0;
10976
      arglist = TREE_CHAIN (arglist);
10977
    }
10978
 
10979
  if (! arglist)
10980
    return 0;
10981
  fmt = TREE_VALUE (arglist);
10982
  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10983
    return 0;
10984
  arglist = TREE_CHAIN (arglist);
10985
 
10986
  /* Check whether the format is a literal string constant.  */
10987
  fmt_str = c_getstr (fmt);
10988
  if (fmt_str == NULL)
10989
    return NULL_TREE;
10990
 
10991
  if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10992
    {
10993
      /* If we're using an unlocked function, assume the other
10994
         unlocked functions exist explicitly.  */
10995
      fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10996
      fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10997
    }
10998
  else
10999
    {
11000
      fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11001
      fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11002
    }
11003
 
11004
  if (!init_target_chars())
11005
    return 0;
11006
 
11007
  /* If the format doesn't contain % args or %%, use strcpy.  */
11008
  if (strchr (fmt_str, target_percent) == NULL)
11009
    {
11010
      if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11011
          && arglist)
11012
        return 0;
11013
 
11014
      /* If the format specifier was "", fprintf does nothing.  */
11015
      if (fmt_str[0] == '\0')
11016
        {
11017
          /* If FP has side-effects, just wait until gimplification is
11018
             done.  */
11019
          if (TREE_SIDE_EFFECTS (fp))
11020
            return 0;
11021
 
11022
          return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11023
        }
11024
 
11025
      /* When "string" doesn't contain %, replace all cases of
11026
         fprintf (fp, string) with fputs (string, fp).  The fputs
11027
         builtin will take care of special cases like length == 1.  */
11028
      arglist = build_tree_list (NULL_TREE, fp);
11029
      arglist = tree_cons (NULL_TREE, fmt, arglist);
11030
      fn = fn_fputs;
11031
    }
11032
 
11033
  /* The other optimizations can be done only on the non-va_list variants.  */
11034
  else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11035
    return 0;
11036
 
11037
  /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
11038
  else if (strcmp (fmt_str, target_percent_s) == 0)
11039
    {
11040
      if (! arglist
11041
          || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11042
          || TREE_CHAIN (arglist))
11043
        return 0;
11044
      arg = TREE_VALUE (arglist);
11045
      arglist = build_tree_list (NULL_TREE, fp);
11046
      arglist = tree_cons (NULL_TREE, arg, arglist);
11047
      fn = fn_fputs;
11048
    }
11049
 
11050
  /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
11051
  else if (strcmp (fmt_str, target_percent_c) == 0)
11052
    {
11053
      if (! arglist
11054
          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11055
          || TREE_CHAIN (arglist))
11056
        return 0;
11057
      arg = TREE_VALUE (arglist);
11058
      arglist = build_tree_list (NULL_TREE, fp);
11059
      arglist = tree_cons (NULL_TREE, arg, arglist);
11060
      fn = fn_fputc;
11061
    }
11062
 
11063
  if (!fn)
11064
    return 0;
11065
 
11066
  call = build_function_call_expr (fn, arglist);
11067
  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11068
}
11069
 
11070
/* Initialize format string characters in the target charset.  */
11071
 
11072
static bool
11073
init_target_chars (void)
11074
{
11075
  static bool init;
11076
  if (!init)
11077
    {
11078
      target_newline = lang_hooks.to_target_charset ('\n');
11079
      target_percent = lang_hooks.to_target_charset ('%');
11080
      target_c = lang_hooks.to_target_charset ('c');
11081
      target_s = lang_hooks.to_target_charset ('s');
11082
      if (target_newline == 0 || target_percent == 0 || target_c == 0
11083
          || target_s == 0)
11084
        return false;
11085
 
11086
      target_percent_c[0] = target_percent;
11087
      target_percent_c[1] = target_c;
11088
      target_percent_c[2] = '\0';
11089
 
11090
      target_percent_s[0] = target_percent;
11091
      target_percent_s[1] = target_s;
11092
      target_percent_s[2] = '\0';
11093
 
11094
      target_percent_s_newline[0] = target_percent;
11095
      target_percent_s_newline[1] = target_s;
11096
      target_percent_s_newline[2] = target_newline;
11097
      target_percent_s_newline[3] = '\0';
11098
 
11099
      init = true;
11100
    }
11101
  return true;
11102
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.