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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [builtins.c] - Blame information for rev 867

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

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

powered by: WebSVN 2.1.0

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