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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [builtins.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Expand builtin functions.
2
   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
4
   2012 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 "rtl.h"
28
#include "tree.h"
29
#include "realmpfr.h"
30
#include "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 "predict.h"
44
#include "tm_p.h"
45
#include "target.h"
46
#include "langhooks.h"
47
#include "basic-block.h"
48
#include "tree-mudflap.h"
49
#include "tree-flow.h"
50
#include "value-prof.h"
51
#include "diagnostic-core.h"
52
#include "builtins.h"
53
 
54
 
55
#ifndef PAD_VARARGS_DOWN
56
#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
57
#endif
58
static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
59
 
60
struct target_builtins default_target_builtins;
61
#if SWITCHABLE_TARGET
62
struct target_builtins *this_target_builtins = &default_target_builtins;
63
#endif
64
 
65
/* Define the names of the builtin function types and codes.  */
66
const char *const built_in_class_names[4]
67
  = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
 
69
#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
70
const char * built_in_names[(int) END_BUILTINS] =
71
{
72
#include "builtins.def"
73
};
74
#undef DEF_BUILTIN
75
 
76
/* Setup an array of _DECL trees, make sure each element is
77
   initialized to NULL_TREE.  */
78
builtin_info_type builtin_info;
79
 
80
static const char *c_getstr (tree);
81
static rtx c_readstr (const char *, enum machine_mode);
82
static int target_char_cast (tree, char *);
83
static rtx get_memory_rtx (tree, tree);
84
static int apply_args_size (void);
85
static int apply_result_size (void);
86
#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
87
static rtx result_vector (int, rtx);
88
#endif
89
static void expand_builtin_update_setjmp_buf (rtx);
90
static void expand_builtin_prefetch (tree);
91
static rtx expand_builtin_apply_args (void);
92
static rtx expand_builtin_apply_args_1 (void);
93
static rtx expand_builtin_apply (rtx, rtx, rtx);
94
static void expand_builtin_return (rtx);
95
static enum type_class type_to_class (tree);
96
static rtx expand_builtin_classify_type (tree);
97
static void expand_errno_check (tree, rtx);
98
static rtx expand_builtin_mathfn (tree, rtx, rtx);
99
static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
100
static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
101
static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx);
102
static rtx expand_builtin_interclass_mathfn (tree, rtx);
103
static rtx expand_builtin_sincos (tree);
104
static rtx expand_builtin_cexpi (tree, rtx);
105
static rtx expand_builtin_int_roundingfn (tree, rtx);
106
static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
107
static rtx expand_builtin_next_arg (void);
108
static rtx expand_builtin_va_start (tree);
109
static rtx expand_builtin_va_end (tree);
110
static rtx expand_builtin_va_copy (tree);
111
static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
112
static rtx expand_builtin_strcmp (tree, rtx);
113
static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
114
static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
115
static rtx expand_builtin_memcpy (tree, rtx);
116
static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
117
static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
118
                                        enum machine_mode, int);
119
static rtx expand_builtin_strcpy (tree, rtx);
120
static rtx expand_builtin_strcpy_args (tree, tree, rtx);
121
static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
122
static rtx expand_builtin_strncpy (tree, rtx);
123
static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
124
static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
125
static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
126
static rtx expand_builtin_bzero (tree);
127
static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
128
static rtx expand_builtin_alloca (tree, bool);
129
static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130
static rtx expand_builtin_frame_address (tree, tree);
131
static tree stabilize_va_list_loc (location_t, tree, int);
132
static rtx expand_builtin_expect (tree, rtx);
133
static tree fold_builtin_constant_p (tree);
134
static tree fold_builtin_expect (location_t, tree, tree);
135
static tree fold_builtin_classify_type (tree);
136
static tree fold_builtin_strlen (location_t, tree, tree);
137
static tree fold_builtin_inf (location_t, tree, int);
138
static tree fold_builtin_nan (tree, tree, int);
139
static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
140
static bool validate_arg (const_tree, enum tree_code code);
141
static bool integer_valued_real_p (tree);
142
static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
143
static bool readonly_data_expr (tree);
144
static rtx expand_builtin_fabs (tree, rtx, rtx);
145
static rtx expand_builtin_signbit (tree, rtx);
146
static tree fold_builtin_sqrt (location_t, tree, tree);
147
static tree fold_builtin_cbrt (location_t, tree, tree);
148
static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
149
static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
150
static tree fold_builtin_cos (location_t, tree, tree, tree);
151
static tree fold_builtin_cosh (location_t, tree, tree, tree);
152
static tree fold_builtin_tan (tree, tree);
153
static tree fold_builtin_trunc (location_t, tree, tree);
154
static tree fold_builtin_floor (location_t, tree, tree);
155
static tree fold_builtin_ceil (location_t, tree, tree);
156
static tree fold_builtin_round (location_t, tree, tree);
157
static tree fold_builtin_int_roundingfn (location_t, tree, tree);
158
static tree fold_builtin_bitop (tree, tree);
159
static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
160
static tree fold_builtin_strchr (location_t, tree, tree, tree);
161
static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
162
static tree fold_builtin_memcmp (location_t, tree, tree, tree);
163
static tree fold_builtin_strcmp (location_t, tree, tree);
164
static tree fold_builtin_strncmp (location_t, tree, tree, tree);
165
static tree fold_builtin_signbit (location_t, tree, tree);
166
static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
167
static tree fold_builtin_isascii (location_t, tree);
168
static tree fold_builtin_toascii (location_t, tree);
169
static tree fold_builtin_isdigit (location_t, tree);
170
static tree fold_builtin_fabs (location_t, tree, tree);
171
static tree fold_builtin_abs (location_t, tree, tree);
172
static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
173
                                        enum tree_code);
174
static tree fold_builtin_n (location_t, tree, tree *, int, bool);
175
static tree fold_builtin_0 (location_t, tree, bool);
176
static tree fold_builtin_1 (location_t, tree, tree, bool);
177
static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
178
static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
179
static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
180
static tree fold_builtin_varargs (location_t, tree, tree, bool);
181
 
182
static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
183
static tree fold_builtin_strstr (location_t, tree, tree, tree);
184
static tree fold_builtin_strrchr (location_t, tree, tree, tree);
185
static tree fold_builtin_strcat (location_t, tree, tree);
186
static tree fold_builtin_strncat (location_t, tree, tree, tree);
187
static tree fold_builtin_strspn (location_t, tree, tree);
188
static tree fold_builtin_strcspn (location_t, tree, tree);
189
static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
190
static tree fold_builtin_snprintf (location_t, tree, tree, tree, tree, int);
191
 
192
static rtx expand_builtin_object_size (tree);
193
static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
194
                                      enum built_in_function);
195
static void maybe_emit_chk_warning (tree, enum built_in_function);
196
static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
197
static void maybe_emit_free_warning (tree);
198
static tree fold_builtin_object_size (tree, tree);
199
static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
200
static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
201
static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
202
static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
203
static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
204
                                  enum built_in_function);
205
static bool init_target_chars (void);
206
 
207
static unsigned HOST_WIDE_INT target_newline;
208
static unsigned HOST_WIDE_INT target_percent;
209
static unsigned HOST_WIDE_INT target_c;
210
static unsigned HOST_WIDE_INT target_s;
211
static char target_percent_c[3];
212
static char target_percent_s[3];
213
static char target_percent_s_newline[4];
214
static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
215
                          const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
216
static tree do_mpfr_arg2 (tree, tree, tree,
217
                          int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
218
static tree do_mpfr_arg3 (tree, tree, tree, tree,
219
                          int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
220
static tree do_mpfr_sincos (tree, tree, tree);
221
static tree do_mpfr_bessel_n (tree, tree, tree,
222
                              int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
223
                              const REAL_VALUE_TYPE *, bool);
224
static tree do_mpfr_remquo (tree, tree, tree);
225
static tree do_mpfr_lgamma_r (tree, tree, tree);
226
static void expand_builtin_sync_synchronize (void);
227
 
228
/* Return true if NAME starts with __builtin_ or __sync_.  */
229
 
230
static bool
231
is_builtin_name (const char *name)
232
{
233
  if (strncmp (name, "__builtin_", 10) == 0)
234
    return true;
235
  if (strncmp (name, "__sync_", 7) == 0)
236
    return true;
237
  if (strncmp (name, "__atomic_", 9) == 0)
238
    return true;
239
  return false;
240
}
241
 
242
 
243
/* Return true if DECL is a function symbol representing a built-in.  */
244
 
245
bool
246
is_builtin_fn (tree decl)
247
{
248
  return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
249
}
250
 
251
 
252
/* Return true if NODE should be considered for inline expansion regardless
253
   of the optimization level.  This means whenever a function is invoked with
254
   its "internal" name, which normally contains the prefix "__builtin".  */
255
 
256
static bool
257
called_as_built_in (tree node)
258
{
259
  /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
260
     we want the name used to call the function, not the name it
261
     will have. */
262
  const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
263
  return is_builtin_name (name);
264
}
265
 
266
/* Compute values M and N such that M divides (address of EXP - N) and
267
   such that N < M.  Store N in *BITPOSP and return M.
268
 
269
   Note that the address (and thus the alignment) computed here is based
270
   on the address to which a symbol resolves, whereas DECL_ALIGN is based
271
   on the address at which an object is actually located.  These two
272
   addresses are not always the same.  For example, on ARM targets,
273
   the address &foo of a Thumb function foo() has the lowest bit set,
274
   whereas foo() itself starts on an even address.  */
275
 
276
unsigned int
277
get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
278
{
279
  HOST_WIDE_INT bitsize, bitpos;
280
  tree offset;
281
  enum machine_mode mode;
282
  int unsignedp, volatilep;
283
  unsigned int align, inner;
284
 
285
  /* Get the innermost object and the constant (bitpos) and possibly
286
     variable (offset) offset of the access.  */
287
  exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
288
                             &mode, &unsignedp, &volatilep, true);
289
 
290
  /* Extract alignment information from the innermost object and
291
     possibly adjust bitpos and offset.  */
292
  if (TREE_CODE (exp) == CONST_DECL)
293
    exp = DECL_INITIAL (exp);
294
  if (DECL_P (exp)
295
      && TREE_CODE (exp) != LABEL_DECL)
296
    {
297
      if (TREE_CODE (exp) == FUNCTION_DECL)
298
        {
299
          /* Function addresses can encode extra information besides their
300
             alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
301
             allows the low bit to be used as a virtual bit, we know
302
             that the address itself must be 2-byte aligned.  */
303
          if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
304
            align = 2 * BITS_PER_UNIT;
305
          else
306
            align = BITS_PER_UNIT;
307
        }
308
      else
309
        align = DECL_ALIGN (exp);
310
    }
311
  else if (CONSTANT_CLASS_P (exp))
312
    {
313
      align = TYPE_ALIGN (TREE_TYPE (exp));
314
#ifdef CONSTANT_ALIGNMENT
315
      align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
316
#endif
317
    }
318
  else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
319
    align = TYPE_ALIGN (TREE_TYPE (exp));
320
  else if (TREE_CODE (exp) == INDIRECT_REF)
321
    align = TYPE_ALIGN (TREE_TYPE (exp));
322
  else if (TREE_CODE (exp) == MEM_REF)
323
    {
324
      tree addr = TREE_OPERAND (exp, 0);
325
      struct ptr_info_def *pi;
326
      if (TREE_CODE (addr) == BIT_AND_EXPR
327
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
328
        {
329
          align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
330
                    & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
331
          align *= BITS_PER_UNIT;
332
          addr = TREE_OPERAND (addr, 0);
333
        }
334
      else
335
        align = BITS_PER_UNIT;
336
      if (TREE_CODE (addr) == SSA_NAME
337
          && (pi = SSA_NAME_PTR_INFO (addr)))
338
        {
339
          bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
340
          align = MAX (pi->align * BITS_PER_UNIT, align);
341
        }
342
      else if (TREE_CODE (addr) == ADDR_EXPR)
343
        align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
344
      bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
345
    }
346
  else if (TREE_CODE (exp) == TARGET_MEM_REF)
347
    {
348
      struct ptr_info_def *pi;
349
      tree addr = TMR_BASE (exp);
350
      if (TREE_CODE (addr) == BIT_AND_EXPR
351
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
352
        {
353
          align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
354
                   & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
355
          align *= BITS_PER_UNIT;
356
          addr = TREE_OPERAND (addr, 0);
357
        }
358
      else
359
        align = BITS_PER_UNIT;
360
      if (TREE_CODE (addr) == SSA_NAME
361
          && (pi = SSA_NAME_PTR_INFO (addr)))
362
        {
363
          bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
364
          align = MAX (pi->align * BITS_PER_UNIT, align);
365
        }
366
      else if (TREE_CODE (addr) == ADDR_EXPR)
367
        align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
368
      if (TMR_OFFSET (exp))
369
        bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
370
      if (TMR_INDEX (exp) && TMR_STEP (exp))
371
        {
372
          unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
373
          align = MIN (align, (step & -step) * BITS_PER_UNIT);
374
        }
375
      else if (TMR_INDEX (exp))
376
        align = BITS_PER_UNIT;
377
      if (TMR_INDEX2 (exp))
378
        align = BITS_PER_UNIT;
379
    }
380
  else
381
    align = BITS_PER_UNIT;
382
 
383
  /* If there is a non-constant offset part extract the maximum
384
     alignment that can prevail.  */
385
  inner = ~0U;
386
  while (offset)
387
    {
388
      tree next_offset;
389
 
390
      if (TREE_CODE (offset) == PLUS_EXPR)
391
        {
392
          next_offset = TREE_OPERAND (offset, 0);
393
          offset = TREE_OPERAND (offset, 1);
394
        }
395
      else
396
        next_offset = NULL;
397
      if (host_integerp (offset, 1))
398
        {
399
          /* Any overflow in calculating offset_bits won't change
400
             the alignment.  */
401
          unsigned offset_bits
402
            = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
403
 
404
          if (offset_bits)
405
            inner = MIN (inner, (offset_bits & -offset_bits));
406
        }
407
      else if (TREE_CODE (offset) == MULT_EXPR
408
               && host_integerp (TREE_OPERAND (offset, 1), 1))
409
        {
410
          /* Any overflow in calculating offset_factor won't change
411
             the alignment.  */
412
          unsigned offset_factor
413
            = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
414
               * BITS_PER_UNIT);
415
 
416
          if (offset_factor)
417
            inner = MIN (inner, (offset_factor & -offset_factor));
418
        }
419
      else
420
        {
421
          inner = MIN (inner, BITS_PER_UNIT);
422
          break;
423
        }
424
      offset = next_offset;
425
    }
426
 
427
  /* Alignment is innermost object alignment adjusted by the constant
428
     and non-constant offset parts.  */
429
  align = MIN (align, inner);
430
  bitpos = bitpos & (align - 1);
431
 
432
  *bitposp = bitpos;
433
  return align;
434
}
435
 
436
/* Return the alignment in bits of EXP, an object.  */
437
 
438
unsigned int
439
get_object_alignment (tree exp)
440
{
441
  unsigned HOST_WIDE_INT bitpos = 0;
442
  unsigned int align;
443
 
444
  align = get_object_alignment_1 (exp, &bitpos);
445
 
446
  /* align and bitpos now specify known low bits of the pointer.
447
     ptr & (align - 1) == bitpos.  */
448
 
449
  if (bitpos != 0)
450
    align = (bitpos & -bitpos);
451
 
452
  return align;
453
}
454
 
455
/* Return the alignment of object EXP, also considering its type when we do
456
   not know of explicit misalignment.  Only handle MEM_REF and TARGET_MEM_REF.
457
 
458
   ??? Note that, in the general case, the type of an expression is not kept
459
   consistent with misalignment information by the front-end, for example when
460
   taking the address of a member of a packed structure.  However, in most of
461
   the cases, expressions have the alignment of their type so we optimistically
462
   fall back to this alignment when we cannot compute a misalignment.  */
463
 
464
unsigned int
465
get_object_or_type_alignment (tree exp)
466
{
467
  unsigned HOST_WIDE_INT misalign;
468
  unsigned int align = get_object_alignment_1 (exp, &misalign);
469
 
470
  gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF);
471
 
472
  if (misalign != 0)
473
    align = (misalign & -misalign);
474
  else
475
    align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
476
 
477
  return align;
478
}
479
 
480
/* For a pointer valued expression EXP compute values M and N such that
481
   M divides (EXP - N) and such that N < M.  Store N in *BITPOSP and return M.
482
 
483
   If EXP is not a pointer, 0 is returned.  */
484
 
485
unsigned int
486
get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
487
{
488
  STRIP_NOPS (exp);
489
 
490
  if (TREE_CODE (exp) == ADDR_EXPR)
491
    return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp);
492
  else if (TREE_CODE (exp) == SSA_NAME
493
           && POINTER_TYPE_P (TREE_TYPE (exp)))
494
    {
495
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
496
      if (!pi)
497
        {
498
          *bitposp = 0;
499
          return BITS_PER_UNIT;
500
        }
501
      *bitposp = pi->misalign * BITS_PER_UNIT;
502
      return pi->align * BITS_PER_UNIT;
503
    }
504
 
505
  *bitposp = 0;
506
  return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
507
}
508
 
509
/* Return the alignment in bits of EXP, a pointer valued expression.
510
   The alignment returned is, by default, the alignment of the thing that
511
   EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
512
 
513
   Otherwise, look at the expression to see if we can do better, i.e., if the
514
   expression is actually pointing at an object whose alignment is tighter.  */
515
 
516
unsigned int
517
get_pointer_alignment (tree exp)
518
{
519
  unsigned HOST_WIDE_INT bitpos = 0;
520
  unsigned int align;
521
 
522
  align = get_pointer_alignment_1 (exp, &bitpos);
523
 
524
  /* align and bitpos now specify known low bits of the pointer.
525
     ptr & (align - 1) == bitpos.  */
526
 
527
  if (bitpos != 0)
528
    align = (bitpos & -bitpos);
529
 
530
  return align;
531
}
532
 
533
/* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
534
   way, because it could contain a zero byte in the middle.
535
   TREE_STRING_LENGTH is the size of the character array, not the string.
536
 
537
   ONLY_VALUE should be nonzero if the result is not going to be emitted
538
   into the instruction stream and zero if it is going to be expanded.
539
   E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
540
   is returned, otherwise NULL, since
541
   len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
542
   evaluate the side-effects.
543
 
544
   The value returned is of type `ssizetype'.
545
 
546
   Unfortunately, string_constant can't access the values of const char
547
   arrays with initializers, so neither can we do so here.  */
548
 
549
tree
550
c_strlen (tree src, int only_value)
551
{
552
  tree offset_node;
553
  HOST_WIDE_INT offset;
554
  int max;
555
  const char *ptr;
556
  location_t loc;
557
 
558
  STRIP_NOPS (src);
559
  if (TREE_CODE (src) == COND_EXPR
560
      && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
561
    {
562
      tree len1, len2;
563
 
564
      len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
565
      len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
566
      if (tree_int_cst_equal (len1, len2))
567
        return len1;
568
    }
569
 
570
  if (TREE_CODE (src) == COMPOUND_EXPR
571
      && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
572
    return c_strlen (TREE_OPERAND (src, 1), only_value);
573
 
574
  loc = EXPR_LOC_OR_HERE (src);
575
 
576
  src = string_constant (src, &offset_node);
577
  if (src == 0)
578
    return NULL_TREE;
579
 
580
  max = TREE_STRING_LENGTH (src) - 1;
581
  ptr = TREE_STRING_POINTER (src);
582
 
583
  if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
584
    {
585
      /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
586
         compute the offset to the following null if we don't know where to
587
         start searching for it.  */
588
      int i;
589
 
590
      for (i = 0; i < max; i++)
591
        if (ptr[i] == 0)
592
          return NULL_TREE;
593
 
594
      /* We don't know the starting offset, but we do know that the string
595
         has no internal zero bytes.  We can assume that the offset falls
596
         within the bounds of the string; otherwise, the programmer deserves
597
         what he gets.  Subtract the offset from the length of the string,
598
         and return that.  This would perhaps not be valid if we were dealing
599
         with named arrays in addition to literal string constants.  */
600
 
601
      return size_diffop_loc (loc, size_int (max), offset_node);
602
    }
603
 
604
  /* We have a known offset into the string.  Start searching there for
605
     a null character if we can represent it as a single HOST_WIDE_INT.  */
606
  if (offset_node == 0)
607
    offset = 0;
608
  else if (! host_integerp (offset_node, 0))
609
    offset = -1;
610
  else
611
    offset = tree_low_cst (offset_node, 0);
612
 
613
  /* If the offset is known to be out of bounds, warn, and call strlen at
614
     runtime.  */
615
  if (offset < 0 || offset > max)
616
    {
617
     /* Suppress multiple warnings for propagated constant strings.  */
618
      if (! TREE_NO_WARNING (src))
619
        {
620
          warning_at (loc, 0, "offset outside bounds of constant string");
621
          TREE_NO_WARNING (src) = 1;
622
        }
623
      return NULL_TREE;
624
    }
625
 
626
  /* Use strlen to search for the first zero byte.  Since any strings
627
     constructed with build_string will have nulls appended, we win even
628
     if we get handed something like (char[4])"abcd".
629
 
630
     Since OFFSET is our starting index into the string, no further
631
     calculation is needed.  */
632
  return ssize_int (strlen (ptr + offset));
633
}
634
 
635
/* Return a char pointer for a C string if it is a string constant
636
   or sum of string constant and integer constant.  */
637
 
638
static const char *
639
c_getstr (tree src)
640
{
641
  tree offset_node;
642
 
643
  src = string_constant (src, &offset_node);
644
  if (src == 0)
645
    return 0;
646
 
647
  if (offset_node == 0)
648
    return TREE_STRING_POINTER (src);
649
  else if (!host_integerp (offset_node, 1)
650
           || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
651
    return 0;
652
 
653
  return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
654
}
655
 
656
/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
657
   GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
658
 
659
static rtx
660
c_readstr (const char *str, enum machine_mode mode)
661
{
662
  HOST_WIDE_INT c[2];
663
  HOST_WIDE_INT ch;
664
  unsigned int i, j;
665
 
666
  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
667
 
668
  c[0] = 0;
669
  c[1] = 0;
670
  ch = 1;
671
  for (i = 0; i < GET_MODE_SIZE (mode); i++)
672
    {
673
      j = i;
674
      if (WORDS_BIG_ENDIAN)
675
        j = GET_MODE_SIZE (mode) - i - 1;
676
      if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
677
          && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
678
        j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
679
      j *= BITS_PER_UNIT;
680
      gcc_assert (j < 2 * HOST_BITS_PER_WIDE_INT);
681
 
682
      if (ch)
683
        ch = (unsigned char) str[i];
684
      c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
685
    }
686
  return immed_double_const (c[0], c[1], mode);
687
}
688
 
689
/* Cast a target constant CST to target CHAR and if that value fits into
690
   host char type, return zero and put that value into variable pointed to by
691
   P.  */
692
 
693
static int
694
target_char_cast (tree cst, char *p)
695
{
696
  unsigned HOST_WIDE_INT val, hostval;
697
 
698
  if (TREE_CODE (cst) != INTEGER_CST
699
      || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
700
    return 1;
701
 
702
  val = TREE_INT_CST_LOW (cst);
703
  if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
704
    val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
705
 
706
  hostval = val;
707
  if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
708
    hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
709
 
710
  if (val != hostval)
711
    return 1;
712
 
713
  *p = hostval;
714
  return 0;
715
}
716
 
717
/* Similar to save_expr, but assumes that arbitrary code is not executed
718
   in between the multiple evaluations.  In particular, we assume that a
719
   non-addressable local variable will not be modified.  */
720
 
721
static tree
722
builtin_save_expr (tree exp)
723
{
724
  if (TREE_CODE (exp) == SSA_NAME
725
      || (TREE_ADDRESSABLE (exp) == 0
726
          && (TREE_CODE (exp) == PARM_DECL
727
              || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))))
728
    return exp;
729
 
730
  return save_expr (exp);
731
}
732
 
733
/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
734
   times to get the address of either a higher stack frame, or a return
735
   address located within it (depending on FNDECL_CODE).  */
736
 
737
static rtx
738
expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
739
{
740
  int i;
741
 
742
#ifdef INITIAL_FRAME_ADDRESS_RTX
743
  rtx tem = INITIAL_FRAME_ADDRESS_RTX;
744
#else
745
  rtx tem;
746
 
747
  /* For a zero count with __builtin_return_address, we don't care what
748
     frame address we return, because target-specific definitions will
749
     override us.  Therefore frame pointer elimination is OK, and using
750
     the soft frame pointer is OK.
751
 
752
     For a nonzero count, or a zero count with __builtin_frame_address,
753
     we require a stable offset from the current frame pointer to the
754
     previous one, so we must use the hard frame pointer, and
755
     we must disable frame pointer elimination.  */
756
  if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
757
    tem = frame_pointer_rtx;
758
  else
759
    {
760
      tem = hard_frame_pointer_rtx;
761
 
762
      /* Tell reload not to eliminate the frame pointer.  */
763
      crtl->accesses_prior_frames = 1;
764
    }
765
#endif
766
 
767
  /* Some machines need special handling before we can access
768
     arbitrary frames.  For example, on the SPARC, we must first flush
769
     all register windows to the stack.  */
770
#ifdef SETUP_FRAME_ADDRESSES
771
  if (count > 0)
772
    SETUP_FRAME_ADDRESSES ();
773
#endif
774
 
775
  /* On the SPARC, the return address is not in the frame, it is in a
776
     register.  There is no way to access it off of the current frame
777
     pointer, but it can be accessed off the previous frame pointer by
778
     reading the value from the register window save area.  */
779
#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
780
  if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
781
    count--;
782
#endif
783
 
784
  /* Scan back COUNT frames to the specified frame.  */
785
  for (i = 0; i < count; i++)
786
    {
787
      /* Assume the dynamic chain pointer is in the word that the
788
         frame address points to, unless otherwise specified.  */
789
#ifdef DYNAMIC_CHAIN_ADDRESS
790
      tem = DYNAMIC_CHAIN_ADDRESS (tem);
791
#endif
792
      tem = memory_address (Pmode, tem);
793
      tem = gen_frame_mem (Pmode, tem);
794
      tem = copy_to_reg (tem);
795
    }
796
 
797
  /* For __builtin_frame_address, return what we've got.  But, on
798
     the SPARC for example, we may have to add a bias.  */
799
  if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
800
#ifdef FRAME_ADDR_RTX
801
    return FRAME_ADDR_RTX (tem);
802
#else
803
    return tem;
804
#endif
805
 
806
  /* For __builtin_return_address, get the return address from that frame.  */
807
#ifdef RETURN_ADDR_RTX
808
  tem = RETURN_ADDR_RTX (count, tem);
809
#else
810
  tem = memory_address (Pmode,
811
                        plus_constant (tem, GET_MODE_SIZE (Pmode)));
812
  tem = gen_frame_mem (Pmode, tem);
813
#endif
814
  return tem;
815
}
816
 
817
/* Alias set used for setjmp buffer.  */
818
static alias_set_type setjmp_alias_set = -1;
819
 
820
/* Construct the leading half of a __builtin_setjmp call.  Control will
821
   return to RECEIVER_LABEL.  This is also called directly by the SJLJ
822
   exception handling code.  */
823
 
824
void
825
expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
826
{
827
  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
828
  rtx stack_save;
829
  rtx mem;
830
 
831
  if (setjmp_alias_set == -1)
832
    setjmp_alias_set = new_alias_set ();
833
 
834
  buf_addr = convert_memory_address (Pmode, buf_addr);
835
 
836
  buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
837
 
838
  /* We store the frame pointer and the address of receiver_label in
839
     the buffer and use the rest of it for the stack save area, which
840
     is machine-dependent.  */
841
 
842
  mem = gen_rtx_MEM (Pmode, buf_addr);
843
  set_mem_alias_set (mem, setjmp_alias_set);
844
  emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
845
 
846
  mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
847
  set_mem_alias_set (mem, setjmp_alias_set);
848
 
849
  emit_move_insn (validize_mem (mem),
850
                  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
851
 
852
  stack_save = gen_rtx_MEM (sa_mode,
853
                            plus_constant (buf_addr,
854
                                           2 * GET_MODE_SIZE (Pmode)));
855
  set_mem_alias_set (stack_save, setjmp_alias_set);
856
  emit_stack_save (SAVE_NONLOCAL, &stack_save);
857
 
858
  /* If there is further processing to do, do it.  */
859
#ifdef HAVE_builtin_setjmp_setup
860
  if (HAVE_builtin_setjmp_setup)
861
    emit_insn (gen_builtin_setjmp_setup (buf_addr));
862
#endif
863
 
864
  /* We have a nonlocal label.   */
865
  cfun->has_nonlocal_label = 1;
866
}
867
 
868
/* Construct the trailing part of a __builtin_setjmp call.  This is
869
   also called directly by the SJLJ exception handling code.  */
870
 
871
void
872
expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
873
{
874
  rtx chain;
875
 
876
  /* Clobber the FP when we get here, so we have to make sure it's
877
     marked as used by this function.  */
878
  emit_use (hard_frame_pointer_rtx);
879
 
880
  /* Mark the static chain as clobbered here so life information
881
     doesn't get messed up for it.  */
882
  chain = targetm.calls.static_chain (current_function_decl, true);
883
  if (chain && REG_P (chain))
884
    emit_clobber (chain);
885
 
886
  /* Now put in the code to restore the frame pointer, and argument
887
     pointer, if needed.  */
888
#ifdef HAVE_nonlocal_goto
889
  if (! HAVE_nonlocal_goto)
890
#endif
891
    {
892
      emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
893
      /* This might change the hard frame pointer in ways that aren't
894
         apparent to early optimization passes, so force a clobber.  */
895
      emit_clobber (hard_frame_pointer_rtx);
896
    }
897
 
898
#if !HARD_FRAME_POINTER_IS_ARG_POINTER
899
  if (fixed_regs[ARG_POINTER_REGNUM])
900
    {
901
#ifdef ELIMINABLE_REGS
902
      size_t i;
903
      static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
904
 
905
      for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
906
        if (elim_regs[i].from == ARG_POINTER_REGNUM
907
            && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
908
          break;
909
 
910
      if (i == ARRAY_SIZE (elim_regs))
911
#endif
912
        {
913
          /* Now restore our arg pointer from the address at which it
914
             was saved in our stack frame.  */
915
          emit_move_insn (crtl->args.internal_arg_pointer,
916
                          copy_to_reg (get_arg_pointer_save_area ()));
917
        }
918
    }
919
#endif
920
 
921
#ifdef HAVE_builtin_setjmp_receiver
922
  if (HAVE_builtin_setjmp_receiver)
923
    emit_insn (gen_builtin_setjmp_receiver (receiver_label));
924
  else
925
#endif
926
#ifdef HAVE_nonlocal_goto_receiver
927
    if (HAVE_nonlocal_goto_receiver)
928
      emit_insn (gen_nonlocal_goto_receiver ());
929
    else
930
#endif
931
      { /* Nothing */ }
932
 
933
  /* We must not allow the code we just generated to be reordered by
934
     scheduling.  Specifically, the update of the frame pointer must
935
     happen immediately, not later.  */
936
  emit_insn (gen_blockage ());
937
}
938
 
939
/* __builtin_longjmp is passed a pointer to an array of five words (not
940
   all will be used on all machines).  It operates similarly to the C
941
   library function of the same name, but is more efficient.  Much of
942
   the code below is copied from the handling of non-local gotos.  */
943
 
944
static void
945
expand_builtin_longjmp (rtx buf_addr, rtx value)
946
{
947
  rtx fp, lab, stack, insn, last;
948
  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
949
 
950
  /* DRAP is needed for stack realign if longjmp is expanded to current
951
     function  */
952
  if (SUPPORTS_STACK_ALIGNMENT)
953
    crtl->need_drap = true;
954
 
955
  if (setjmp_alias_set == -1)
956
    setjmp_alias_set = new_alias_set ();
957
 
958
  buf_addr = convert_memory_address (Pmode, buf_addr);
959
 
960
  buf_addr = force_reg (Pmode, buf_addr);
961
 
962
  /* We require that the user must pass a second argument of 1, because
963
     that is what builtin_setjmp will return.  */
964
  gcc_assert (value == const1_rtx);
965
 
966
  last = get_last_insn ();
967
#ifdef HAVE_builtin_longjmp
968
  if (HAVE_builtin_longjmp)
969
    emit_insn (gen_builtin_longjmp (buf_addr));
970
  else
971
#endif
972
    {
973
      fp = gen_rtx_MEM (Pmode, buf_addr);
974
      lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
975
                                               GET_MODE_SIZE (Pmode)));
976
 
977
      stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
978
                                                   2 * GET_MODE_SIZE (Pmode)));
979
      set_mem_alias_set (fp, setjmp_alias_set);
980
      set_mem_alias_set (lab, setjmp_alias_set);
981
      set_mem_alias_set (stack, setjmp_alias_set);
982
 
983
      /* Pick up FP, label, and SP from the block and jump.  This code is
984
         from expand_goto in stmt.c; see there for detailed comments.  */
985
#ifdef HAVE_nonlocal_goto
986
      if (HAVE_nonlocal_goto)
987
        /* We have to pass a value to the nonlocal_goto pattern that will
988
           get copied into the static_chain pointer, but it does not matter
989
           what that value is, because builtin_setjmp does not use it.  */
990
        emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
991
      else
992
#endif
993
        {
994
          lab = copy_to_reg (lab);
995
 
996
          emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
997
          emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
998
 
999
          emit_move_insn (hard_frame_pointer_rtx, fp);
1000
          emit_stack_restore (SAVE_NONLOCAL, stack);
1001
 
1002
          emit_use (hard_frame_pointer_rtx);
1003
          emit_use (stack_pointer_rtx);
1004
          emit_indirect_jump (lab);
1005
        }
1006
    }
1007
 
1008
  /* Search backwards and mark the jump insn as a non-local goto.
1009
     Note that this precludes the use of __builtin_longjmp to a
1010
     __builtin_setjmp target in the same function.  However, we've
1011
     already cautioned the user that these functions are for
1012
     internal exception handling use only.  */
1013
  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1014
    {
1015
      gcc_assert (insn != last);
1016
 
1017
      if (JUMP_P (insn))
1018
        {
1019
          add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1020
          break;
1021
        }
1022
      else if (CALL_P (insn))
1023
        break;
1024
    }
1025
}
1026
 
1027
/* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
1028
   and the address of the save area.  */
1029
 
1030
static rtx
1031
expand_builtin_nonlocal_goto (tree exp)
1032
{
1033
  tree t_label, t_save_area;
1034
  rtx r_label, r_save_area, r_fp, r_sp, insn;
1035
 
1036
  if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1037
    return NULL_RTX;
1038
 
1039
  t_label = CALL_EXPR_ARG (exp, 0);
1040
  t_save_area = CALL_EXPR_ARG (exp, 1);
1041
 
1042
  r_label = expand_normal (t_label);
1043
  r_label = convert_memory_address (Pmode, r_label);
1044
  r_save_area = expand_normal (t_save_area);
1045
  r_save_area = convert_memory_address (Pmode, r_save_area);
1046
  /* Copy the address of the save location to a register just in case it was
1047
     based on the frame pointer.   */
1048
  r_save_area = copy_to_reg (r_save_area);
1049
  r_fp = gen_rtx_MEM (Pmode, r_save_area);
1050
  r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
1051
                      plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
1052
 
1053
  crtl->has_nonlocal_goto = 1;
1054
 
1055
#ifdef HAVE_nonlocal_goto
1056
  /* ??? We no longer need to pass the static chain value, afaik.  */
1057
  if (HAVE_nonlocal_goto)
1058
    emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
1059
  else
1060
#endif
1061
    {
1062
      r_label = copy_to_reg (r_label);
1063
 
1064
      emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1065
      emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1066
 
1067
      /* Restore frame pointer for containing function.  */
1068
      emit_move_insn (hard_frame_pointer_rtx, r_fp);
1069
      emit_stack_restore (SAVE_NONLOCAL, r_sp);
1070
 
1071
      /* USE of hard_frame_pointer_rtx added for consistency;
1072
         not clear if really needed.  */
1073
      emit_use (hard_frame_pointer_rtx);
1074
      emit_use (stack_pointer_rtx);
1075
 
1076
      /* If the architecture is using a GP register, we must
1077
         conservatively assume that the target function makes use of it.
1078
         The prologue of functions with nonlocal gotos must therefore
1079
         initialize the GP register to the appropriate value, and we
1080
         must then make sure that this value is live at the point
1081
         of the jump.  (Note that this doesn't necessarily apply
1082
         to targets with a nonlocal_goto pattern; they are free
1083
         to implement it in their own way.  Note also that this is
1084
         a no-op if the GP register is a global invariant.)  */
1085
      if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
1086
          && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
1087
        emit_use (pic_offset_table_rtx);
1088
 
1089
      emit_indirect_jump (r_label);
1090
    }
1091
 
1092
  /* Search backwards to the jump insn and mark it as a
1093
     non-local goto.  */
1094
  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1095
    {
1096
      if (JUMP_P (insn))
1097
        {
1098
          add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1099
          break;
1100
        }
1101
      else if (CALL_P (insn))
1102
        break;
1103
    }
1104
 
1105
  return const0_rtx;
1106
}
1107
 
1108
/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
1109
   (not all will be used on all machines) that was passed to __builtin_setjmp.
1110
   It updates the stack pointer in that block to correspond to the current
1111
   stack pointer.  */
1112
 
1113
static void
1114
expand_builtin_update_setjmp_buf (rtx buf_addr)
1115
{
1116
  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1117
  rtx stack_save
1118
    = gen_rtx_MEM (sa_mode,
1119
                   memory_address
1120
                   (sa_mode,
1121
                    plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1122
 
1123
  emit_stack_save (SAVE_NONLOCAL, &stack_save);
1124
}
1125
 
1126
/* Expand a call to __builtin_prefetch.  For a target that does not support
1127
   data prefetch, evaluate the memory address argument in case it has side
1128
   effects.  */
1129
 
1130
static void
1131
expand_builtin_prefetch (tree exp)
1132
{
1133
  tree arg0, arg1, arg2;
1134
  int nargs;
1135
  rtx op0, op1, op2;
1136
 
1137
  if (!validate_arglist (exp, POINTER_TYPE, 0))
1138
    return;
1139
 
1140
  arg0 = CALL_EXPR_ARG (exp, 0);
1141
 
1142
  /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1143
     zero (read) and argument 2 (locality) defaults to 3 (high degree of
1144
     locality).  */
1145
  nargs = call_expr_nargs (exp);
1146
  if (nargs > 1)
1147
    arg1 = CALL_EXPR_ARG (exp, 1);
1148
  else
1149
    arg1 = integer_zero_node;
1150
  if (nargs > 2)
1151
    arg2 = CALL_EXPR_ARG (exp, 2);
1152
  else
1153
    arg2 = integer_three_node;
1154
 
1155
  /* Argument 0 is an address.  */
1156
  op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1157
 
1158
  /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1159
  if (TREE_CODE (arg1) != INTEGER_CST)
1160
    {
1161
      error ("second argument to %<__builtin_prefetch%> must be a constant");
1162
      arg1 = integer_zero_node;
1163
    }
1164
  op1 = expand_normal (arg1);
1165
  /* Argument 1 must be either zero or one.  */
1166
  if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1167
    {
1168
      warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1169
               " using zero");
1170
      op1 = const0_rtx;
1171
    }
1172
 
1173
  /* Argument 2 (locality) must be a compile-time constant int.  */
1174
  if (TREE_CODE (arg2) != INTEGER_CST)
1175
    {
1176
      error ("third argument to %<__builtin_prefetch%> must be a constant");
1177
      arg2 = integer_zero_node;
1178
    }
1179
  op2 = expand_normal (arg2);
1180
  /* Argument 2 must be 0, 1, 2, or 3.  */
1181
  if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1182
    {
1183
      warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1184
      op2 = const0_rtx;
1185
    }
1186
 
1187
#ifdef HAVE_prefetch
1188
  if (HAVE_prefetch)
1189
    {
1190
      struct expand_operand ops[3];
1191
 
1192
      create_address_operand (&ops[0], op0);
1193
      create_integer_operand (&ops[1], INTVAL (op1));
1194
      create_integer_operand (&ops[2], INTVAL (op2));
1195
      if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops))
1196
        return;
1197
    }
1198
#endif
1199
 
1200
  /* Don't do anything with direct references to volatile memory, but
1201
     generate code to handle other side effects.  */
1202
  if (!MEM_P (op0) && side_effects_p (op0))
1203
    emit_insn (op0);
1204
}
1205
 
1206
/* Get a MEM rtx for expression EXP which is the address of an operand
1207
   to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1208
   the maximum length of the block of memory that might be accessed or
1209
   NULL if unknown.  */
1210
 
1211
static rtx
1212
get_memory_rtx (tree exp, tree len)
1213
{
1214
  tree orig_exp = exp;
1215
  rtx addr, mem;
1216
  HOST_WIDE_INT off;
1217
 
1218
  /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1219
     from its expression, for expr->a.b only <variable>.a.b is recorded.  */
1220
  if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1221
    exp = TREE_OPERAND (exp, 0);
1222
 
1223
  addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1224
  mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1225
 
1226
  /* Get an expression we can use to find the attributes to assign to MEM.
1227
     If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1228
     we can.  First remove any nops.  */
1229
  while (CONVERT_EXPR_P (exp)
1230
         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1231
    exp = TREE_OPERAND (exp, 0);
1232
 
1233
  off = 0;
1234
  if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1235
      && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1236
      && host_integerp (TREE_OPERAND (exp, 1), 0)
1237
      && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1238
    exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1239
  else if (TREE_CODE (exp) == ADDR_EXPR)
1240
    exp = TREE_OPERAND (exp, 0);
1241
  else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1242
    exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1243
  else
1244
    exp = NULL;
1245
 
1246
  /* Honor attributes derived from exp, except for the alias set
1247
     (as builtin stringops may alias with anything) and the size
1248
     (as stringops may access multiple array elements).  */
1249
  if (exp)
1250
    {
1251
      set_mem_attributes (mem, exp, 0);
1252
 
1253
      if (off)
1254
        mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1255
 
1256
      /* Allow the string and memory builtins to overflow from one
1257
         field into another, see http://gcc.gnu.org/PR23561.
1258
         Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1259
         memory accessed by the string or memory builtin will fit
1260
         within the field.  */
1261
      if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1262
        {
1263
          tree mem_expr = MEM_EXPR (mem);
1264
          HOST_WIDE_INT offset = -1, length = -1;
1265
          tree inner = exp;
1266
 
1267
          while (TREE_CODE (inner) == ARRAY_REF
1268
                 || CONVERT_EXPR_P (inner)
1269
                 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1270
                 || TREE_CODE (inner) == SAVE_EXPR)
1271
            inner = TREE_OPERAND (inner, 0);
1272
 
1273
          gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1274
 
1275
          if (MEM_OFFSET_KNOWN_P (mem))
1276
            offset = MEM_OFFSET (mem);
1277
 
1278
          if (offset >= 0 && len && host_integerp (len, 0))
1279
            length = tree_low_cst (len, 0);
1280
 
1281
          while (TREE_CODE (inner) == COMPONENT_REF)
1282
            {
1283
              tree field = TREE_OPERAND (inner, 1);
1284
              gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1285
              gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1286
 
1287
              /* Bitfields are generally not byte-addressable.  */
1288
              gcc_assert (!DECL_BIT_FIELD (field)
1289
                          || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1290
                               % BITS_PER_UNIT) == 0
1291
                              && host_integerp (DECL_SIZE (field), 0)
1292
                              && (TREE_INT_CST_LOW (DECL_SIZE (field))
1293
                                  % BITS_PER_UNIT) == 0));
1294
 
1295
              /* If we can prove that the memory starting at XEXP (mem, 0) and
1296
                 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1297
                 can keep the COMPONENT_REF in MEM_EXPR.  But be careful with
1298
                 fields without DECL_SIZE_UNIT like flexible array members.  */
1299
              if (length >= 0
1300
                  && DECL_SIZE_UNIT (field)
1301
                  && host_integerp (DECL_SIZE_UNIT (field), 0))
1302
                {
1303
                  HOST_WIDE_INT size
1304
                    = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
1305
                  if (offset <= size
1306
                      && length <= size
1307
                      && offset + length <= size)
1308
                    break;
1309
                }
1310
 
1311
              if (offset >= 0
1312
                  && host_integerp (DECL_FIELD_OFFSET (field), 0))
1313
                offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
1314
                          + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1315
                            / BITS_PER_UNIT;
1316
              else
1317
                {
1318
                  offset = -1;
1319
                  length = -1;
1320
                }
1321
 
1322
              mem_expr = TREE_OPERAND (mem_expr, 0);
1323
              inner = TREE_OPERAND (inner, 0);
1324
            }
1325
 
1326
          if (mem_expr == NULL)
1327
            offset = -1;
1328
          if (mem_expr != MEM_EXPR (mem))
1329
            {
1330
              set_mem_expr (mem, mem_expr);
1331
              if (offset >= 0)
1332
                set_mem_offset (mem, offset);
1333
              else
1334
                clear_mem_offset (mem);
1335
            }
1336
        }
1337
      set_mem_alias_set (mem, 0);
1338
      clear_mem_size (mem);
1339
    }
1340
 
1341
  return mem;
1342
}
1343
 
1344
/* Built-in functions to perform an untyped call and return.  */
1345
 
1346
#define apply_args_mode \
1347
  (this_target_builtins->x_apply_args_mode)
1348
#define apply_result_mode \
1349
  (this_target_builtins->x_apply_result_mode)
1350
 
1351
/* Return the size required for the block returned by __builtin_apply_args,
1352
   and initialize apply_args_mode.  */
1353
 
1354
static int
1355
apply_args_size (void)
1356
{
1357
  static int size = -1;
1358
  int align;
1359
  unsigned int regno;
1360
  enum machine_mode mode;
1361
 
1362
  /* The values computed by this function never change.  */
1363
  if (size < 0)
1364
    {
1365
      /* The first value is the incoming arg-pointer.  */
1366
      size = GET_MODE_SIZE (Pmode);
1367
 
1368
      /* The second value is the structure value address unless this is
1369
         passed as an "invisible" first argument.  */
1370
      if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1371
        size += GET_MODE_SIZE (Pmode);
1372
 
1373
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1374
        if (FUNCTION_ARG_REGNO_P (regno))
1375
          {
1376
            mode = targetm.calls.get_raw_arg_mode (regno);
1377
 
1378
            gcc_assert (mode != VOIDmode);
1379
 
1380
            align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1381
            if (size % align != 0)
1382
              size = CEIL (size, align) * align;
1383
            size += GET_MODE_SIZE (mode);
1384
            apply_args_mode[regno] = mode;
1385
          }
1386
        else
1387
          {
1388
            apply_args_mode[regno] = VOIDmode;
1389
          }
1390
    }
1391
  return size;
1392
}
1393
 
1394
/* Return the size required for the block returned by __builtin_apply,
1395
   and initialize apply_result_mode.  */
1396
 
1397
static int
1398
apply_result_size (void)
1399
{
1400
  static int size = -1;
1401
  int align, regno;
1402
  enum machine_mode mode;
1403
 
1404
  /* The values computed by this function never change.  */
1405
  if (size < 0)
1406
    {
1407
      size = 0;
1408
 
1409
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1410
        if (targetm.calls.function_value_regno_p (regno))
1411
          {
1412
            mode = targetm.calls.get_raw_result_mode (regno);
1413
 
1414
            gcc_assert (mode != VOIDmode);
1415
 
1416
            align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1417
            if (size % align != 0)
1418
              size = CEIL (size, align) * align;
1419
            size += GET_MODE_SIZE (mode);
1420
            apply_result_mode[regno] = mode;
1421
          }
1422
        else
1423
          apply_result_mode[regno] = VOIDmode;
1424
 
1425
      /* Allow targets that use untyped_call and untyped_return to override
1426
         the size so that machine-specific information can be stored here.  */
1427
#ifdef APPLY_RESULT_SIZE
1428
      size = APPLY_RESULT_SIZE;
1429
#endif
1430
    }
1431
  return size;
1432
}
1433
 
1434
#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1435
/* Create a vector describing the result block RESULT.  If SAVEP is true,
1436
   the result block is used to save the values; otherwise it is used to
1437
   restore the values.  */
1438
 
1439
static rtx
1440
result_vector (int savep, rtx result)
1441
{
1442
  int regno, size, align, nelts;
1443
  enum machine_mode mode;
1444
  rtx reg, mem;
1445
  rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1446
 
1447
  size = nelts = 0;
1448
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1449
    if ((mode = apply_result_mode[regno]) != VOIDmode)
1450
      {
1451
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1452
        if (size % align != 0)
1453
          size = CEIL (size, align) * align;
1454
        reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1455
        mem = adjust_address (result, mode, size);
1456
        savevec[nelts++] = (savep
1457
                            ? gen_rtx_SET (VOIDmode, mem, reg)
1458
                            : gen_rtx_SET (VOIDmode, reg, mem));
1459
        size += GET_MODE_SIZE (mode);
1460
      }
1461
  return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1462
}
1463
#endif /* HAVE_untyped_call or HAVE_untyped_return */
1464
 
1465
/* Save the state required to perform an untyped call with the same
1466
   arguments as were passed to the current function.  */
1467
 
1468
static rtx
1469
expand_builtin_apply_args_1 (void)
1470
{
1471
  rtx registers, tem;
1472
  int size, align, regno;
1473
  enum machine_mode mode;
1474
  rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1475
 
1476
  /* Create a block where the arg-pointer, structure value address,
1477
     and argument registers can be saved.  */
1478
  registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1479
 
1480
  /* Walk past the arg-pointer and structure value address.  */
1481
  size = GET_MODE_SIZE (Pmode);
1482
  if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1483
    size += GET_MODE_SIZE (Pmode);
1484
 
1485
  /* Save each register used in calling a function to the block.  */
1486
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1487
    if ((mode = apply_args_mode[regno]) != VOIDmode)
1488
      {
1489
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1490
        if (size % align != 0)
1491
          size = CEIL (size, align) * align;
1492
 
1493
        tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1494
 
1495
        emit_move_insn (adjust_address (registers, mode, size), tem);
1496
        size += GET_MODE_SIZE (mode);
1497
      }
1498
 
1499
  /* Save the arg pointer to the block.  */
1500
  tem = copy_to_reg (crtl->args.internal_arg_pointer);
1501
#ifdef STACK_GROWS_DOWNWARD
1502
  /* We need the pointer as the caller actually passed them to us, not
1503
     as we might have pretended they were passed.  Make sure it's a valid
1504
     operand, as emit_move_insn isn't expected to handle a PLUS.  */
1505
  tem
1506
    = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
1507
                     NULL_RTX);
1508
#endif
1509
  emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1510
 
1511
  size = GET_MODE_SIZE (Pmode);
1512
 
1513
  /* Save the structure value address unless this is passed as an
1514
     "invisible" first argument.  */
1515
  if (struct_incoming_value)
1516
    {
1517
      emit_move_insn (adjust_address (registers, Pmode, size),
1518
                      copy_to_reg (struct_incoming_value));
1519
      size += GET_MODE_SIZE (Pmode);
1520
    }
1521
 
1522
  /* Return the address of the block.  */
1523
  return copy_addr_to_reg (XEXP (registers, 0));
1524
}
1525
 
1526
/* __builtin_apply_args returns block of memory allocated on
1527
   the stack into which is stored the arg pointer, structure
1528
   value address, static chain, and all the registers that might
1529
   possibly be used in performing a function call.  The code is
1530
   moved to the start of the function so the incoming values are
1531
   saved.  */
1532
 
1533
static rtx
1534
expand_builtin_apply_args (void)
1535
{
1536
  /* Don't do __builtin_apply_args more than once in a function.
1537
     Save the result of the first call and reuse it.  */
1538
  if (apply_args_value != 0)
1539
    return apply_args_value;
1540
  {
1541
    /* When this function is called, it means that registers must be
1542
       saved on entry to this function.  So we migrate the
1543
       call to the first insn of this function.  */
1544
    rtx temp;
1545
    rtx seq;
1546
 
1547
    start_sequence ();
1548
    temp = expand_builtin_apply_args_1 ();
1549
    seq = get_insns ();
1550
    end_sequence ();
1551
 
1552
    apply_args_value = temp;
1553
 
1554
    /* Put the insns after the NOTE that starts the function.
1555
       If this is inside a start_sequence, make the outer-level insn
1556
       chain current, so the code is placed at the start of the
1557
       function.  If internal_arg_pointer is a non-virtual pseudo,
1558
       it needs to be placed after the function that initializes
1559
       that pseudo.  */
1560
    push_topmost_sequence ();
1561
    if (REG_P (crtl->args.internal_arg_pointer)
1562
        && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1563
      emit_insn_before (seq, parm_birth_insn);
1564
    else
1565
      emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1566
    pop_topmost_sequence ();
1567
    return temp;
1568
  }
1569
}
1570
 
1571
/* Perform an untyped call and save the state required to perform an
1572
   untyped return of whatever value was returned by the given function.  */
1573
 
1574
static rtx
1575
expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1576
{
1577
  int size, align, regno;
1578
  enum machine_mode mode;
1579
  rtx incoming_args, result, reg, dest, src, call_insn;
1580
  rtx old_stack_level = 0;
1581
  rtx call_fusage = 0;
1582
  rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1583
 
1584
  arguments = convert_memory_address (Pmode, arguments);
1585
 
1586
  /* Create a block where the return registers can be saved.  */
1587
  result = assign_stack_local (BLKmode, apply_result_size (), -1);
1588
 
1589
  /* Fetch the arg pointer from the ARGUMENTS block.  */
1590
  incoming_args = gen_reg_rtx (Pmode);
1591
  emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1592
#ifndef STACK_GROWS_DOWNWARD
1593
  incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1594
                                       incoming_args, 0, OPTAB_LIB_WIDEN);
1595
#endif
1596
 
1597
  /* Push a new argument block and copy the arguments.  Do not allow
1598
     the (potential) memcpy call below to interfere with our stack
1599
     manipulations.  */
1600
  do_pending_stack_adjust ();
1601
  NO_DEFER_POP;
1602
 
1603
  /* Save the stack with nonlocal if available.  */
1604
#ifdef HAVE_save_stack_nonlocal
1605
  if (HAVE_save_stack_nonlocal)
1606
    emit_stack_save (SAVE_NONLOCAL, &old_stack_level);
1607
  else
1608
#endif
1609
    emit_stack_save (SAVE_BLOCK, &old_stack_level);
1610
 
1611
  /* Allocate a block of memory onto the stack and copy the memory
1612
     arguments to the outgoing arguments address.  We can pass TRUE
1613
     as the 4th argument because we just saved the stack pointer
1614
     and will restore it right after the call.  */
1615
  allocate_dynamic_stack_space (argsize, 0, BIGGEST_ALIGNMENT, true);
1616
 
1617
  /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1618
     may have already set current_function_calls_alloca to true.
1619
     current_function_calls_alloca won't be set if argsize is zero,
1620
     so we have to guarantee need_drap is true here.  */
1621
  if (SUPPORTS_STACK_ALIGNMENT)
1622
    crtl->need_drap = true;
1623
 
1624
  dest = virtual_outgoing_args_rtx;
1625
#ifndef STACK_GROWS_DOWNWARD
1626
  if (CONST_INT_P (argsize))
1627
    dest = plus_constant (dest, -INTVAL (argsize));
1628
  else
1629
    dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1630
#endif
1631
  dest = gen_rtx_MEM (BLKmode, dest);
1632
  set_mem_align (dest, PARM_BOUNDARY);
1633
  src = gen_rtx_MEM (BLKmode, incoming_args);
1634
  set_mem_align (src, PARM_BOUNDARY);
1635
  emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1636
 
1637
  /* Refer to the argument block.  */
1638
  apply_args_size ();
1639
  arguments = gen_rtx_MEM (BLKmode, arguments);
1640
  set_mem_align (arguments, PARM_BOUNDARY);
1641
 
1642
  /* Walk past the arg-pointer and structure value address.  */
1643
  size = GET_MODE_SIZE (Pmode);
1644
  if (struct_value)
1645
    size += GET_MODE_SIZE (Pmode);
1646
 
1647
  /* Restore each of the registers previously saved.  Make USE insns
1648
     for each of these registers for use in making the call.  */
1649
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1650
    if ((mode = apply_args_mode[regno]) != VOIDmode)
1651
      {
1652
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1653
        if (size % align != 0)
1654
          size = CEIL (size, align) * align;
1655
        reg = gen_rtx_REG (mode, regno);
1656
        emit_move_insn (reg, adjust_address (arguments, mode, size));
1657
        use_reg (&call_fusage, reg);
1658
        size += GET_MODE_SIZE (mode);
1659
      }
1660
 
1661
  /* Restore the structure value address unless this is passed as an
1662
     "invisible" first argument.  */
1663
  size = GET_MODE_SIZE (Pmode);
1664
  if (struct_value)
1665
    {
1666
      rtx value = gen_reg_rtx (Pmode);
1667
      emit_move_insn (value, adjust_address (arguments, Pmode, size));
1668
      emit_move_insn (struct_value, value);
1669
      if (REG_P (struct_value))
1670
        use_reg (&call_fusage, struct_value);
1671
      size += GET_MODE_SIZE (Pmode);
1672
    }
1673
 
1674
  /* All arguments and registers used for the call are set up by now!  */
1675
  function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
1676
 
1677
  /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1678
     and we don't want to load it into a register as an optimization,
1679
     because prepare_call_address already did it if it should be done.  */
1680
  if (GET_CODE (function) != SYMBOL_REF)
1681
    function = memory_address (FUNCTION_MODE, function);
1682
 
1683
  /* Generate the actual call instruction and save the return value.  */
1684
#ifdef HAVE_untyped_call
1685
  if (HAVE_untyped_call)
1686
    emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1687
                                      result, result_vector (1, result)));
1688
  else
1689
#endif
1690
#ifdef HAVE_call_value
1691
  if (HAVE_call_value)
1692
    {
1693
      rtx valreg = 0;
1694
 
1695
      /* Locate the unique return register.  It is not possible to
1696
         express a call that sets more than one return register using
1697
         call_value; use untyped_call for that.  In fact, untyped_call
1698
         only needs to save the return registers in the given block.  */
1699
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1700
        if ((mode = apply_result_mode[regno]) != VOIDmode)
1701
          {
1702
            gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1703
 
1704
            valreg = gen_rtx_REG (mode, regno);
1705
          }
1706
 
1707
      emit_call_insn (GEN_CALL_VALUE (valreg,
1708
                                      gen_rtx_MEM (FUNCTION_MODE, function),
1709
                                      const0_rtx, NULL_RTX, const0_rtx));
1710
 
1711
      emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1712
    }
1713
  else
1714
#endif
1715
    gcc_unreachable ();
1716
 
1717
  /* Find the CALL insn we just emitted, and attach the register usage
1718
     information.  */
1719
  call_insn = last_call_insn ();
1720
  add_function_usage_to (call_insn, call_fusage);
1721
 
1722
  /* Restore the stack.  */
1723
#ifdef HAVE_save_stack_nonlocal
1724
  if (HAVE_save_stack_nonlocal)
1725
    emit_stack_restore (SAVE_NONLOCAL, old_stack_level);
1726
  else
1727
#endif
1728
    emit_stack_restore (SAVE_BLOCK, old_stack_level);
1729
  fixup_args_size_notes (call_insn, get_last_insn(), 0);
1730
 
1731
  OK_DEFER_POP;
1732
 
1733
  /* Return the address of the result block.  */
1734
  result = copy_addr_to_reg (XEXP (result, 0));
1735
  return convert_memory_address (ptr_mode, result);
1736
}
1737
 
1738
/* Perform an untyped return.  */
1739
 
1740
static void
1741
expand_builtin_return (rtx result)
1742
{
1743
  int size, align, regno;
1744
  enum machine_mode mode;
1745
  rtx reg;
1746
  rtx call_fusage = 0;
1747
 
1748
  result = convert_memory_address (Pmode, result);
1749
 
1750
  apply_result_size ();
1751
  result = gen_rtx_MEM (BLKmode, result);
1752
 
1753
#ifdef HAVE_untyped_return
1754
  if (HAVE_untyped_return)
1755
    {
1756
      emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1757
      emit_barrier ();
1758
      return;
1759
    }
1760
#endif
1761
 
1762
  /* Restore the return value and note that each value is used.  */
1763
  size = 0;
1764
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1765
    if ((mode = apply_result_mode[regno]) != VOIDmode)
1766
      {
1767
        align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1768
        if (size % align != 0)
1769
          size = CEIL (size, align) * align;
1770
        reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1771
        emit_move_insn (reg, adjust_address (result, mode, size));
1772
 
1773
        push_to_sequence (call_fusage);
1774
        emit_use (reg);
1775
        call_fusage = get_insns ();
1776
        end_sequence ();
1777
        size += GET_MODE_SIZE (mode);
1778
      }
1779
 
1780
  /* Put the USE insns before the return.  */
1781
  emit_insn (call_fusage);
1782
 
1783
  /* Return whatever values was restored by jumping directly to the end
1784
     of the function.  */
1785
  expand_naked_return ();
1786
}
1787
 
1788
/* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1789
 
1790
static enum type_class
1791
type_to_class (tree type)
1792
{
1793
  switch (TREE_CODE (type))
1794
    {
1795
    case VOID_TYPE:        return void_type_class;
1796
    case INTEGER_TYPE:     return integer_type_class;
1797
    case ENUMERAL_TYPE:    return enumeral_type_class;
1798
    case BOOLEAN_TYPE:     return boolean_type_class;
1799
    case POINTER_TYPE:     return pointer_type_class;
1800
    case REFERENCE_TYPE:   return reference_type_class;
1801
    case OFFSET_TYPE:      return offset_type_class;
1802
    case REAL_TYPE:        return real_type_class;
1803
    case COMPLEX_TYPE:     return complex_type_class;
1804
    case FUNCTION_TYPE:    return function_type_class;
1805
    case METHOD_TYPE:      return method_type_class;
1806
    case RECORD_TYPE:      return record_type_class;
1807
    case UNION_TYPE:
1808
    case QUAL_UNION_TYPE:  return union_type_class;
1809
    case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1810
                                   ? string_type_class : array_type_class);
1811
    case LANG_TYPE:        return lang_type_class;
1812
    default:               return no_type_class;
1813
    }
1814
}
1815
 
1816
/* Expand a call EXP to __builtin_classify_type.  */
1817
 
1818
static rtx
1819
expand_builtin_classify_type (tree exp)
1820
{
1821
  if (call_expr_nargs (exp))
1822
    return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1823
  return GEN_INT (no_type_class);
1824
}
1825
 
1826
/* This helper macro, meant to be used in mathfn_built_in below,
1827
   determines which among a set of three builtin math functions is
1828
   appropriate for a given type mode.  The `F' and `L' cases are
1829
   automatically generated from the `double' case.  */
1830
#define CASE_MATHFN(BUILT_IN_MATHFN) \
1831
  case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1832
  fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1833
  fcodel = BUILT_IN_MATHFN##L ; break;
1834
/* Similar to above, but appends _R after any F/L suffix.  */
1835
#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1836
  case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1837
  fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1838
  fcodel = BUILT_IN_MATHFN##L_R ; break;
1839
 
1840
/* Return mathematic function equivalent to FN but operating directly on TYPE,
1841
   if available.  If IMPLICIT is true use the implicit builtin declaration,
1842
   otherwise use the explicit declaration.  If we can't do the conversion,
1843
   return zero.  */
1844
 
1845
static tree
1846
mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit_p)
1847
{
1848
  enum built_in_function fcode, fcodef, fcodel, fcode2;
1849
 
1850
  switch (fn)
1851
    {
1852
      CASE_MATHFN (BUILT_IN_ACOS)
1853
      CASE_MATHFN (BUILT_IN_ACOSH)
1854
      CASE_MATHFN (BUILT_IN_ASIN)
1855
      CASE_MATHFN (BUILT_IN_ASINH)
1856
      CASE_MATHFN (BUILT_IN_ATAN)
1857
      CASE_MATHFN (BUILT_IN_ATAN2)
1858
      CASE_MATHFN (BUILT_IN_ATANH)
1859
      CASE_MATHFN (BUILT_IN_CBRT)
1860
      CASE_MATHFN (BUILT_IN_CEIL)
1861
      CASE_MATHFN (BUILT_IN_CEXPI)
1862
      CASE_MATHFN (BUILT_IN_COPYSIGN)
1863
      CASE_MATHFN (BUILT_IN_COS)
1864
      CASE_MATHFN (BUILT_IN_COSH)
1865
      CASE_MATHFN (BUILT_IN_DREM)
1866
      CASE_MATHFN (BUILT_IN_ERF)
1867
      CASE_MATHFN (BUILT_IN_ERFC)
1868
      CASE_MATHFN (BUILT_IN_EXP)
1869
      CASE_MATHFN (BUILT_IN_EXP10)
1870
      CASE_MATHFN (BUILT_IN_EXP2)
1871
      CASE_MATHFN (BUILT_IN_EXPM1)
1872
      CASE_MATHFN (BUILT_IN_FABS)
1873
      CASE_MATHFN (BUILT_IN_FDIM)
1874
      CASE_MATHFN (BUILT_IN_FLOOR)
1875
      CASE_MATHFN (BUILT_IN_FMA)
1876
      CASE_MATHFN (BUILT_IN_FMAX)
1877
      CASE_MATHFN (BUILT_IN_FMIN)
1878
      CASE_MATHFN (BUILT_IN_FMOD)
1879
      CASE_MATHFN (BUILT_IN_FREXP)
1880
      CASE_MATHFN (BUILT_IN_GAMMA)
1881
      CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1882
      CASE_MATHFN (BUILT_IN_HUGE_VAL)
1883
      CASE_MATHFN (BUILT_IN_HYPOT)
1884
      CASE_MATHFN (BUILT_IN_ILOGB)
1885
      CASE_MATHFN (BUILT_IN_ICEIL)
1886
      CASE_MATHFN (BUILT_IN_IFLOOR)
1887
      CASE_MATHFN (BUILT_IN_INF)
1888
      CASE_MATHFN (BUILT_IN_IRINT)
1889
      CASE_MATHFN (BUILT_IN_IROUND)
1890
      CASE_MATHFN (BUILT_IN_ISINF)
1891
      CASE_MATHFN (BUILT_IN_J0)
1892
      CASE_MATHFN (BUILT_IN_J1)
1893
      CASE_MATHFN (BUILT_IN_JN)
1894
      CASE_MATHFN (BUILT_IN_LCEIL)
1895
      CASE_MATHFN (BUILT_IN_LDEXP)
1896
      CASE_MATHFN (BUILT_IN_LFLOOR)
1897
      CASE_MATHFN (BUILT_IN_LGAMMA)
1898
      CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1899
      CASE_MATHFN (BUILT_IN_LLCEIL)
1900
      CASE_MATHFN (BUILT_IN_LLFLOOR)
1901
      CASE_MATHFN (BUILT_IN_LLRINT)
1902
      CASE_MATHFN (BUILT_IN_LLROUND)
1903
      CASE_MATHFN (BUILT_IN_LOG)
1904
      CASE_MATHFN (BUILT_IN_LOG10)
1905
      CASE_MATHFN (BUILT_IN_LOG1P)
1906
      CASE_MATHFN (BUILT_IN_LOG2)
1907
      CASE_MATHFN (BUILT_IN_LOGB)
1908
      CASE_MATHFN (BUILT_IN_LRINT)
1909
      CASE_MATHFN (BUILT_IN_LROUND)
1910
      CASE_MATHFN (BUILT_IN_MODF)
1911
      CASE_MATHFN (BUILT_IN_NAN)
1912
      CASE_MATHFN (BUILT_IN_NANS)
1913
      CASE_MATHFN (BUILT_IN_NEARBYINT)
1914
      CASE_MATHFN (BUILT_IN_NEXTAFTER)
1915
      CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1916
      CASE_MATHFN (BUILT_IN_POW)
1917
      CASE_MATHFN (BUILT_IN_POWI)
1918
      CASE_MATHFN (BUILT_IN_POW10)
1919
      CASE_MATHFN (BUILT_IN_REMAINDER)
1920
      CASE_MATHFN (BUILT_IN_REMQUO)
1921
      CASE_MATHFN (BUILT_IN_RINT)
1922
      CASE_MATHFN (BUILT_IN_ROUND)
1923
      CASE_MATHFN (BUILT_IN_SCALB)
1924
      CASE_MATHFN (BUILT_IN_SCALBLN)
1925
      CASE_MATHFN (BUILT_IN_SCALBN)
1926
      CASE_MATHFN (BUILT_IN_SIGNBIT)
1927
      CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1928
      CASE_MATHFN (BUILT_IN_SIN)
1929
      CASE_MATHFN (BUILT_IN_SINCOS)
1930
      CASE_MATHFN (BUILT_IN_SINH)
1931
      CASE_MATHFN (BUILT_IN_SQRT)
1932
      CASE_MATHFN (BUILT_IN_TAN)
1933
      CASE_MATHFN (BUILT_IN_TANH)
1934
      CASE_MATHFN (BUILT_IN_TGAMMA)
1935
      CASE_MATHFN (BUILT_IN_TRUNC)
1936
      CASE_MATHFN (BUILT_IN_Y0)
1937
      CASE_MATHFN (BUILT_IN_Y1)
1938
      CASE_MATHFN (BUILT_IN_YN)
1939
 
1940
      default:
1941
        return NULL_TREE;
1942
      }
1943
 
1944
  if (TYPE_MAIN_VARIANT (type) == double_type_node)
1945
    fcode2 = fcode;
1946
  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1947
    fcode2 = fcodef;
1948
  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1949
    fcode2 = fcodel;
1950
  else
1951
    return NULL_TREE;
1952
 
1953
  if (implicit_p && !builtin_decl_implicit_p (fcode2))
1954
    return NULL_TREE;
1955
 
1956
  return builtin_decl_explicit (fcode2);
1957
}
1958
 
1959
/* Like mathfn_built_in_1(), but always use the implicit array.  */
1960
 
1961
tree
1962
mathfn_built_in (tree type, enum built_in_function fn)
1963
{
1964
  return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1965
}
1966
 
1967
/* If errno must be maintained, expand the RTL to check if the result,
1968
   TARGET, of a built-in function call, EXP, is NaN, and if so set
1969
   errno to EDOM.  */
1970
 
1971
static void
1972
expand_errno_check (tree exp, rtx target)
1973
{
1974
  rtx lab = gen_label_rtx ();
1975
 
1976
  /* Test the result; if it is NaN, set errno=EDOM because
1977
     the argument was not in the domain.  */
1978
  do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1979
                           NULL_RTX, NULL_RTX, lab,
1980
                           /* The jump is very likely.  */
1981
                           REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1));
1982
 
1983
#ifdef TARGET_EDOM
1984
  /* If this built-in doesn't throw an exception, set errno directly.  */
1985
  if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1986
    {
1987
#ifdef GEN_ERRNO_RTX
1988
      rtx errno_rtx = GEN_ERRNO_RTX;
1989
#else
1990
      rtx errno_rtx
1991
          = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1992
#endif
1993
      emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1994
      emit_label (lab);
1995
      return;
1996
    }
1997
#endif
1998
 
1999
  /* Make sure the library call isn't expanded as a tail call.  */
2000
  CALL_EXPR_TAILCALL (exp) = 0;
2001
 
2002
  /* We can't set errno=EDOM directly; let the library call do it.
2003
     Pop the arguments right away in case the call gets deleted.  */
2004
  NO_DEFER_POP;
2005
  expand_call (exp, target, 0);
2006
  OK_DEFER_POP;
2007
  emit_label (lab);
2008
}
2009
 
2010
/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
2011
   Return NULL_RTX if a normal call should be emitted rather than expanding
2012
   the function in-line.  EXP is the expression that is a call to the builtin
2013
   function; if convenient, the result should be placed in TARGET.
2014
   SUBTARGET may be used as the target for computing one of EXP's operands.  */
2015
 
2016
static rtx
2017
expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
2018
{
2019
  optab builtin_optab;
2020
  rtx op0, insns;
2021
  tree fndecl = get_callee_fndecl (exp);
2022
  enum machine_mode mode;
2023
  bool errno_set = false;
2024
  tree arg;
2025
 
2026
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2027
    return NULL_RTX;
2028
 
2029
  arg = CALL_EXPR_ARG (exp, 0);
2030
 
2031
  switch (DECL_FUNCTION_CODE (fndecl))
2032
    {
2033
    CASE_FLT_FN (BUILT_IN_SQRT):
2034
      errno_set = ! tree_expr_nonnegative_p (arg);
2035
      builtin_optab = sqrt_optab;
2036
      break;
2037
    CASE_FLT_FN (BUILT_IN_EXP):
2038
      errno_set = true; builtin_optab = exp_optab; break;
2039
    CASE_FLT_FN (BUILT_IN_EXP10):
2040
    CASE_FLT_FN (BUILT_IN_POW10):
2041
      errno_set = true; builtin_optab = exp10_optab; break;
2042
    CASE_FLT_FN (BUILT_IN_EXP2):
2043
      errno_set = true; builtin_optab = exp2_optab; break;
2044
    CASE_FLT_FN (BUILT_IN_EXPM1):
2045
      errno_set = true; builtin_optab = expm1_optab; break;
2046
    CASE_FLT_FN (BUILT_IN_LOGB):
2047
      errno_set = true; builtin_optab = logb_optab; break;
2048
    CASE_FLT_FN (BUILT_IN_LOG):
2049
      errno_set = true; builtin_optab = log_optab; break;
2050
    CASE_FLT_FN (BUILT_IN_LOG10):
2051
      errno_set = true; builtin_optab = log10_optab; break;
2052
    CASE_FLT_FN (BUILT_IN_LOG2):
2053
      errno_set = true; builtin_optab = log2_optab; break;
2054
    CASE_FLT_FN (BUILT_IN_LOG1P):
2055
      errno_set = true; builtin_optab = log1p_optab; break;
2056
    CASE_FLT_FN (BUILT_IN_ASIN):
2057
      builtin_optab = asin_optab; break;
2058
    CASE_FLT_FN (BUILT_IN_ACOS):
2059
      builtin_optab = acos_optab; break;
2060
    CASE_FLT_FN (BUILT_IN_TAN):
2061
      builtin_optab = tan_optab; break;
2062
    CASE_FLT_FN (BUILT_IN_ATAN):
2063
      builtin_optab = atan_optab; break;
2064
    CASE_FLT_FN (BUILT_IN_FLOOR):
2065
      builtin_optab = floor_optab; break;
2066
    CASE_FLT_FN (BUILT_IN_CEIL):
2067
      builtin_optab = ceil_optab; break;
2068
    CASE_FLT_FN (BUILT_IN_TRUNC):
2069
      builtin_optab = btrunc_optab; break;
2070
    CASE_FLT_FN (BUILT_IN_ROUND):
2071
      builtin_optab = round_optab; break;
2072
    CASE_FLT_FN (BUILT_IN_NEARBYINT):
2073
      builtin_optab = nearbyint_optab;
2074
      if (flag_trapping_math)
2075
        break;
2076
      /* Else fallthrough and expand as rint.  */
2077
    CASE_FLT_FN (BUILT_IN_RINT):
2078
      builtin_optab = rint_optab; break;
2079
    CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
2080
      builtin_optab = significand_optab; break;
2081
    default:
2082
      gcc_unreachable ();
2083
    }
2084
 
2085
  /* Make a suitable register to place result in.  */
2086
  mode = TYPE_MODE (TREE_TYPE (exp));
2087
 
2088
  if (! flag_errno_math || ! HONOR_NANS (mode))
2089
    errno_set = false;
2090
 
2091
  /* Before working hard, check whether the instruction is available.  */
2092
  if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
2093
      && (!errno_set || !optimize_insn_for_size_p ()))
2094
    {
2095
      target = gen_reg_rtx (mode);
2096
 
2097
      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2098
         need to expand the argument again.  This way, we will not perform
2099
         side-effects more the once.  */
2100
      CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2101
 
2102
      op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2103
 
2104
      start_sequence ();
2105
 
2106
      /* Compute into TARGET.
2107
         Set TARGET to wherever the result comes back.  */
2108
      target = expand_unop (mode, builtin_optab, op0, target, 0);
2109
 
2110
      if (target != 0)
2111
        {
2112
          if (errno_set)
2113
            expand_errno_check (exp, target);
2114
 
2115
          /* Output the entire sequence.  */
2116
          insns = get_insns ();
2117
          end_sequence ();
2118
          emit_insn (insns);
2119
          return target;
2120
        }
2121
 
2122
      /* If we were unable to expand via the builtin, stop the sequence
2123
         (without outputting the insns) and call to the library function
2124
         with the stabilized argument list.  */
2125
      end_sequence ();
2126
    }
2127
 
2128
  return expand_call (exp, target, target == const0_rtx);
2129
}
2130
 
2131
/* Expand a call to the builtin binary math functions (pow and atan2).
2132
   Return NULL_RTX if a normal call should be emitted rather than expanding the
2133
   function in-line.  EXP is the expression that is a call to the builtin
2134
   function; if convenient, the result should be placed in TARGET.
2135
   SUBTARGET may be used as the target for computing one of EXP's
2136
   operands.  */
2137
 
2138
static rtx
2139
expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2140
{
2141
  optab builtin_optab;
2142
  rtx op0, op1, insns;
2143
  int op1_type = REAL_TYPE;
2144
  tree fndecl = get_callee_fndecl (exp);
2145
  tree arg0, arg1;
2146
  enum machine_mode mode;
2147
  bool errno_set = true;
2148
 
2149
  switch (DECL_FUNCTION_CODE (fndecl))
2150
    {
2151
    CASE_FLT_FN (BUILT_IN_SCALBN):
2152
    CASE_FLT_FN (BUILT_IN_SCALBLN):
2153
    CASE_FLT_FN (BUILT_IN_LDEXP):
2154
      op1_type = INTEGER_TYPE;
2155
    default:
2156
      break;
2157
    }
2158
 
2159
  if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2160
    return NULL_RTX;
2161
 
2162
  arg0 = CALL_EXPR_ARG (exp, 0);
2163
  arg1 = CALL_EXPR_ARG (exp, 1);
2164
 
2165
  switch (DECL_FUNCTION_CODE (fndecl))
2166
    {
2167
    CASE_FLT_FN (BUILT_IN_POW):
2168
      builtin_optab = pow_optab; break;
2169
    CASE_FLT_FN (BUILT_IN_ATAN2):
2170
      builtin_optab = atan2_optab; break;
2171
    CASE_FLT_FN (BUILT_IN_SCALB):
2172
      if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2173
        return 0;
2174
      builtin_optab = scalb_optab; break;
2175
    CASE_FLT_FN (BUILT_IN_SCALBN):
2176
    CASE_FLT_FN (BUILT_IN_SCALBLN):
2177
      if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2178
        return 0;
2179
    /* Fall through... */
2180
    CASE_FLT_FN (BUILT_IN_LDEXP):
2181
      builtin_optab = ldexp_optab; break;
2182
    CASE_FLT_FN (BUILT_IN_FMOD):
2183
      builtin_optab = fmod_optab; break;
2184
    CASE_FLT_FN (BUILT_IN_REMAINDER):
2185
    CASE_FLT_FN (BUILT_IN_DREM):
2186
      builtin_optab = remainder_optab; break;
2187
    default:
2188
      gcc_unreachable ();
2189
    }
2190
 
2191
  /* Make a suitable register to place result in.  */
2192
  mode = TYPE_MODE (TREE_TYPE (exp));
2193
 
2194
  /* Before working hard, check whether the instruction is available.  */
2195
  if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2196
    return NULL_RTX;
2197
 
2198
  target = gen_reg_rtx (mode);
2199
 
2200
  if (! flag_errno_math || ! HONOR_NANS (mode))
2201
    errno_set = false;
2202
 
2203
  if (errno_set && optimize_insn_for_size_p ())
2204
    return 0;
2205
 
2206
  /* Always stabilize the argument list.  */
2207
  CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2208
  CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2209
 
2210
  op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2211
  op1 = expand_normal (arg1);
2212
 
2213
  start_sequence ();
2214
 
2215
  /* Compute into TARGET.
2216
     Set TARGET to wherever the result comes back.  */
2217
  target = expand_binop (mode, builtin_optab, op0, op1,
2218
                         target, 0, OPTAB_DIRECT);
2219
 
2220
  /* If we were unable to expand via the builtin, stop the sequence
2221
     (without outputting the insns) and call to the library function
2222
     with the stabilized argument list.  */
2223
  if (target == 0)
2224
    {
2225
      end_sequence ();
2226
      return expand_call (exp, target, target == const0_rtx);
2227
    }
2228
 
2229
  if (errno_set)
2230
    expand_errno_check (exp, target);
2231
 
2232
  /* Output the entire sequence.  */
2233
  insns = get_insns ();
2234
  end_sequence ();
2235
  emit_insn (insns);
2236
 
2237
  return target;
2238
}
2239
 
2240
/* Expand a call to the builtin trinary math functions (fma).
2241
   Return NULL_RTX if a normal call should be emitted rather than expanding the
2242
   function in-line.  EXP is the expression that is a call to the builtin
2243
   function; if convenient, the result should be placed in TARGET.
2244
   SUBTARGET may be used as the target for computing one of EXP's
2245
   operands.  */
2246
 
2247
static rtx
2248
expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
2249
{
2250
  optab builtin_optab;
2251
  rtx op0, op1, op2, insns;
2252
  tree fndecl = get_callee_fndecl (exp);
2253
  tree arg0, arg1, arg2;
2254
  enum machine_mode mode;
2255
 
2256
  if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2257
    return NULL_RTX;
2258
 
2259
  arg0 = CALL_EXPR_ARG (exp, 0);
2260
  arg1 = CALL_EXPR_ARG (exp, 1);
2261
  arg2 = CALL_EXPR_ARG (exp, 2);
2262
 
2263
  switch (DECL_FUNCTION_CODE (fndecl))
2264
    {
2265
    CASE_FLT_FN (BUILT_IN_FMA):
2266
      builtin_optab = fma_optab; break;
2267
    default:
2268
      gcc_unreachable ();
2269
    }
2270
 
2271
  /* Make a suitable register to place result in.  */
2272
  mode = TYPE_MODE (TREE_TYPE (exp));
2273
 
2274
  /* Before working hard, check whether the instruction is available.  */
2275
  if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2276
    return NULL_RTX;
2277
 
2278
  target = gen_reg_rtx (mode);
2279
 
2280
  /* Always stabilize the argument list.  */
2281
  CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2282
  CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2283
  CALL_EXPR_ARG (exp, 2) = arg2 = builtin_save_expr (arg2);
2284
 
2285
  op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2286
  op1 = expand_normal (arg1);
2287
  op2 = expand_normal (arg2);
2288
 
2289
  start_sequence ();
2290
 
2291
  /* Compute into TARGET.
2292
     Set TARGET to wherever the result comes back.  */
2293
  target = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
2294
                              target, 0);
2295
 
2296
  /* If we were unable to expand via the builtin, stop the sequence
2297
     (without outputting the insns) and call to the library function
2298
     with the stabilized argument list.  */
2299
  if (target == 0)
2300
    {
2301
      end_sequence ();
2302
      return expand_call (exp, target, target == const0_rtx);
2303
    }
2304
 
2305
  /* Output the entire sequence.  */
2306
  insns = get_insns ();
2307
  end_sequence ();
2308
  emit_insn (insns);
2309
 
2310
  return target;
2311
}
2312
 
2313
/* Expand a call to the builtin sin and cos math functions.
2314
   Return NULL_RTX if a normal call should be emitted rather than expanding the
2315
   function in-line.  EXP is the expression that is a call to the builtin
2316
   function; if convenient, the result should be placed in TARGET.
2317
   SUBTARGET may be used as the target for computing one of EXP's
2318
   operands.  */
2319
 
2320
static rtx
2321
expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2322
{
2323
  optab builtin_optab;
2324
  rtx op0, insns;
2325
  tree fndecl = get_callee_fndecl (exp);
2326
  enum machine_mode mode;
2327
  tree arg;
2328
 
2329
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2330
    return NULL_RTX;
2331
 
2332
  arg = CALL_EXPR_ARG (exp, 0);
2333
 
2334
  switch (DECL_FUNCTION_CODE (fndecl))
2335
    {
2336
    CASE_FLT_FN (BUILT_IN_SIN):
2337
    CASE_FLT_FN (BUILT_IN_COS):
2338
      builtin_optab = sincos_optab; break;
2339
    default:
2340
      gcc_unreachable ();
2341
    }
2342
 
2343
  /* Make a suitable register to place result in.  */
2344
  mode = TYPE_MODE (TREE_TYPE (exp));
2345
 
2346
  /* Check if sincos insn is available, otherwise fallback
2347
     to sin or cos insn.  */
2348
  if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2349
    switch (DECL_FUNCTION_CODE (fndecl))
2350
      {
2351
      CASE_FLT_FN (BUILT_IN_SIN):
2352
        builtin_optab = sin_optab; break;
2353
      CASE_FLT_FN (BUILT_IN_COS):
2354
        builtin_optab = cos_optab; break;
2355
      default:
2356
        gcc_unreachable ();
2357
      }
2358
 
2359
  /* Before working hard, check whether the instruction is available.  */
2360
  if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing)
2361
    {
2362
      target = gen_reg_rtx (mode);
2363
 
2364
      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2365
         need to expand the argument again.  This way, we will not perform
2366
         side-effects more the once.  */
2367
      CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2368
 
2369
      op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2370
 
2371
      start_sequence ();
2372
 
2373
      /* Compute into TARGET.
2374
         Set TARGET to wherever the result comes back.  */
2375
      if (builtin_optab == sincos_optab)
2376
        {
2377
          int result;
2378
 
2379
          switch (DECL_FUNCTION_CODE (fndecl))
2380
            {
2381
            CASE_FLT_FN (BUILT_IN_SIN):
2382
              result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2383
              break;
2384
            CASE_FLT_FN (BUILT_IN_COS):
2385
              result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2386
              break;
2387
            default:
2388
              gcc_unreachable ();
2389
            }
2390
          gcc_assert (result);
2391
        }
2392
      else
2393
        {
2394
          target = expand_unop (mode, builtin_optab, op0, target, 0);
2395
        }
2396
 
2397
      if (target != 0)
2398
        {
2399
          /* Output the entire sequence.  */
2400
          insns = get_insns ();
2401
          end_sequence ();
2402
          emit_insn (insns);
2403
          return target;
2404
        }
2405
 
2406
      /* If we were unable to expand via the builtin, stop the sequence
2407
         (without outputting the insns) and call to the library function
2408
         with the stabilized argument list.  */
2409
      end_sequence ();
2410
    }
2411
 
2412
  target = expand_call (exp, target, target == const0_rtx);
2413
 
2414
  return target;
2415
}
2416
 
2417
/* Given an interclass math builtin decl FNDECL and it's argument ARG
2418
   return an RTL instruction code that implements the functionality.
2419
   If that isn't possible or available return CODE_FOR_nothing.  */
2420
 
2421
static enum insn_code
2422
interclass_mathfn_icode (tree arg, tree fndecl)
2423
{
2424
  bool errno_set = false;
2425
  optab builtin_optab = 0;
2426
  enum machine_mode mode;
2427
 
2428
  switch (DECL_FUNCTION_CODE (fndecl))
2429
    {
2430
    CASE_FLT_FN (BUILT_IN_ILOGB):
2431
      errno_set = true; builtin_optab = ilogb_optab; break;
2432
    CASE_FLT_FN (BUILT_IN_ISINF):
2433
      builtin_optab = isinf_optab; break;
2434
    case BUILT_IN_ISNORMAL:
2435
    case BUILT_IN_ISFINITE:
2436
    CASE_FLT_FN (BUILT_IN_FINITE):
2437
    case BUILT_IN_FINITED32:
2438
    case BUILT_IN_FINITED64:
2439
    case BUILT_IN_FINITED128:
2440
    case BUILT_IN_ISINFD32:
2441
    case BUILT_IN_ISINFD64:
2442
    case BUILT_IN_ISINFD128:
2443
      /* These builtins have no optabs (yet).  */
2444
      break;
2445
    default:
2446
      gcc_unreachable ();
2447
    }
2448
 
2449
  /* There's no easy way to detect the case we need to set EDOM.  */
2450
  if (flag_errno_math && errno_set)
2451
    return CODE_FOR_nothing;
2452
 
2453
  /* Optab mode depends on the mode of the input argument.  */
2454
  mode = TYPE_MODE (TREE_TYPE (arg));
2455
 
2456
  if (builtin_optab)
2457
    return optab_handler (builtin_optab, mode);
2458
  return CODE_FOR_nothing;
2459
}
2460
 
2461
/* Expand a call to one of the builtin math functions that operate on
2462
   floating point argument and output an integer result (ilogb, isinf,
2463
   isnan, etc).
2464
   Return 0 if a normal call should be emitted rather than expanding the
2465
   function in-line.  EXP is the expression that is a call to the builtin
2466
   function; if convenient, the result should be placed in TARGET.  */
2467
 
2468
static rtx
2469
expand_builtin_interclass_mathfn (tree exp, rtx target)
2470
{
2471
  enum insn_code icode = CODE_FOR_nothing;
2472
  rtx op0;
2473
  tree fndecl = get_callee_fndecl (exp);
2474
  enum machine_mode mode;
2475
  tree arg;
2476
 
2477
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2478
    return NULL_RTX;
2479
 
2480
  arg = CALL_EXPR_ARG (exp, 0);
2481
  icode = interclass_mathfn_icode (arg, fndecl);
2482
  mode = TYPE_MODE (TREE_TYPE (arg));
2483
 
2484
  if (icode != CODE_FOR_nothing)
2485
    {
2486
      struct expand_operand ops[1];
2487
      rtx last = get_last_insn ();
2488
      tree orig_arg = arg;
2489
 
2490
      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2491
         need to expand the argument again.  This way, we will not perform
2492
         side-effects more the once.  */
2493
      CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2494
 
2495
      op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2496
 
2497
      if (mode != GET_MODE (op0))
2498
        op0 = convert_to_mode (mode, op0, 0);
2499
 
2500
      create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
2501
      if (maybe_legitimize_operands (icode, 0, 1, ops)
2502
          && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN))
2503
        return ops[0].value;
2504
 
2505
      delete_insns_since (last);
2506
      CALL_EXPR_ARG (exp, 0) = orig_arg;
2507
    }
2508
 
2509
  return NULL_RTX;
2510
}
2511
 
2512
/* Expand a call to the builtin sincos math function.
2513
   Return NULL_RTX if a normal call should be emitted rather than expanding the
2514
   function in-line.  EXP is the expression that is a call to the builtin
2515
   function.  */
2516
 
2517
static rtx
2518
expand_builtin_sincos (tree exp)
2519
{
2520
  rtx op0, op1, op2, target1, target2;
2521
  enum machine_mode mode;
2522
  tree arg, sinp, cosp;
2523
  int result;
2524
  location_t loc = EXPR_LOCATION (exp);
2525
  tree alias_type, alias_off;
2526
 
2527
  if (!validate_arglist (exp, REAL_TYPE,
2528
                         POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2529
    return NULL_RTX;
2530
 
2531
  arg = CALL_EXPR_ARG (exp, 0);
2532
  sinp = CALL_EXPR_ARG (exp, 1);
2533
  cosp = CALL_EXPR_ARG (exp, 2);
2534
 
2535
  /* Make a suitable register to place result in.  */
2536
  mode = TYPE_MODE (TREE_TYPE (arg));
2537
 
2538
  /* Check if sincos insn is available, otherwise emit the call.  */
2539
  if (optab_handler (sincos_optab, mode) == CODE_FOR_nothing)
2540
    return NULL_RTX;
2541
 
2542
  target1 = gen_reg_rtx (mode);
2543
  target2 = gen_reg_rtx (mode);
2544
 
2545
  op0 = expand_normal (arg);
2546
  alias_type = build_pointer_type_for_mode (TREE_TYPE (arg), ptr_mode, true);
2547
  alias_off = build_int_cst (alias_type, 0);
2548
  op1 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2549
                                        sinp, alias_off));
2550
  op2 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2551
                                        cosp, alias_off));
2552
 
2553
  /* Compute into target1 and target2.
2554
     Set TARGET to wherever the result comes back.  */
2555
  result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2556
  gcc_assert (result);
2557
 
2558
  /* Move target1 and target2 to the memory locations indicated
2559
     by op1 and op2.  */
2560
  emit_move_insn (op1, target1);
2561
  emit_move_insn (op2, target2);
2562
 
2563
  return const0_rtx;
2564
}
2565
 
2566
/* Expand a call to the internal cexpi builtin to the sincos math function.
2567
   EXP is the expression that is a call to the builtin function; if convenient,
2568
   the result should be placed in TARGET.  */
2569
 
2570
static rtx
2571
expand_builtin_cexpi (tree exp, rtx target)
2572
{
2573
  tree fndecl = get_callee_fndecl (exp);
2574
  tree arg, type;
2575
  enum machine_mode mode;
2576
  rtx op0, op1, op2;
2577
  location_t loc = EXPR_LOCATION (exp);
2578
 
2579
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2580
    return NULL_RTX;
2581
 
2582
  arg = CALL_EXPR_ARG (exp, 0);
2583
  type = TREE_TYPE (arg);
2584
  mode = TYPE_MODE (TREE_TYPE (arg));
2585
 
2586
  /* Try expanding via a sincos optab, fall back to emitting a libcall
2587
     to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2588
     is only generated from sincos, cexp or if we have either of them.  */
2589
  if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing)
2590
    {
2591
      op1 = gen_reg_rtx (mode);
2592
      op2 = gen_reg_rtx (mode);
2593
 
2594
      op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2595
 
2596
      /* Compute into op1 and op2.  */
2597
      expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2598
    }
2599
  else if (TARGET_HAS_SINCOS)
2600
    {
2601
      tree call, fn = NULL_TREE;
2602
      tree top1, top2;
2603
      rtx op1a, op2a;
2604
 
2605
      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2606
        fn = builtin_decl_explicit (BUILT_IN_SINCOSF);
2607
      else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2608
        fn = builtin_decl_explicit (BUILT_IN_SINCOS);
2609
      else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2610
        fn = builtin_decl_explicit (BUILT_IN_SINCOSL);
2611
      else
2612
        gcc_unreachable ();
2613
 
2614
      op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2615
      op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2616
      op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2617
      op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2618
      top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2619
      top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2620
 
2621
      /* Make sure not to fold the sincos call again.  */
2622
      call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2623
      expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2624
                                      call, 3, arg, top1, top2));
2625
    }
2626
  else
2627
    {
2628
      tree call, fn = NULL_TREE, narg;
2629
      tree ctype = build_complex_type (type);
2630
 
2631
      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2632
        fn = builtin_decl_explicit (BUILT_IN_CEXPF);
2633
      else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2634
        fn = builtin_decl_explicit (BUILT_IN_CEXP);
2635
      else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2636
        fn = builtin_decl_explicit (BUILT_IN_CEXPL);
2637
      else
2638
        gcc_unreachable ();
2639
 
2640
      /* If we don't have a decl for cexp create one.  This is the
2641
         friendliest fallback if the user calls __builtin_cexpi
2642
         without full target C99 function support.  */
2643
      if (fn == NULL_TREE)
2644
        {
2645
          tree fntype;
2646
          const char *name = NULL;
2647
 
2648
          if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2649
            name = "cexpf";
2650
          else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2651
            name = "cexp";
2652
          else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2653
            name = "cexpl";
2654
 
2655
          fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2656
          fn = build_fn_decl (name, fntype);
2657
        }
2658
 
2659
      narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
2660
                          build_real (type, dconst0), arg);
2661
 
2662
      /* Make sure not to fold the cexp call again.  */
2663
      call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2664
      return expand_expr (build_call_nary (ctype, call, 1, narg),
2665
                          target, VOIDmode, EXPAND_NORMAL);
2666
    }
2667
 
2668
  /* Now build the proper return type.  */
2669
  return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2670
                              make_tree (TREE_TYPE (arg), op2),
2671
                              make_tree (TREE_TYPE (arg), op1)),
2672
                      target, VOIDmode, EXPAND_NORMAL);
2673
}
2674
 
2675
/* Conveniently construct a function call expression.  FNDECL names the
2676
   function to be called, N is the number of arguments, and the "..."
2677
   parameters are the argument expressions.  Unlike build_call_exr
2678
   this doesn't fold the call, hence it will always return a CALL_EXPR.  */
2679
 
2680
static tree
2681
build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2682
{
2683
  va_list ap;
2684
  tree fntype = TREE_TYPE (fndecl);
2685
  tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2686
 
2687
  va_start (ap, n);
2688
  fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2689
  va_end (ap);
2690
  SET_EXPR_LOCATION (fn, loc);
2691
  return fn;
2692
}
2693
 
2694
/* Expand a call to one of the builtin rounding functions gcc defines
2695
   as an extension (lfloor and lceil).  As these are gcc extensions we
2696
   do not need to worry about setting errno to EDOM.
2697
   If expanding via optab fails, lower expression to (int)(floor(x)).
2698
   EXP is the expression that is a call to the builtin function;
2699
   if convenient, the result should be placed in TARGET.  */
2700
 
2701
static rtx
2702
expand_builtin_int_roundingfn (tree exp, rtx target)
2703
{
2704
  convert_optab builtin_optab;
2705
  rtx op0, insns, tmp;
2706
  tree fndecl = get_callee_fndecl (exp);
2707
  enum built_in_function fallback_fn;
2708
  tree fallback_fndecl;
2709
  enum machine_mode mode;
2710
  tree arg;
2711
 
2712
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2713
    gcc_unreachable ();
2714
 
2715
  arg = CALL_EXPR_ARG (exp, 0);
2716
 
2717
  switch (DECL_FUNCTION_CODE (fndecl))
2718
    {
2719
    CASE_FLT_FN (BUILT_IN_ICEIL):
2720
    CASE_FLT_FN (BUILT_IN_LCEIL):
2721
    CASE_FLT_FN (BUILT_IN_LLCEIL):
2722
      builtin_optab = lceil_optab;
2723
      fallback_fn = BUILT_IN_CEIL;
2724
      break;
2725
 
2726
    CASE_FLT_FN (BUILT_IN_IFLOOR):
2727
    CASE_FLT_FN (BUILT_IN_LFLOOR):
2728
    CASE_FLT_FN (BUILT_IN_LLFLOOR):
2729
      builtin_optab = lfloor_optab;
2730
      fallback_fn = BUILT_IN_FLOOR;
2731
      break;
2732
 
2733
    default:
2734
      gcc_unreachable ();
2735
    }
2736
 
2737
  /* Make a suitable register to place result in.  */
2738
  mode = TYPE_MODE (TREE_TYPE (exp));
2739
 
2740
  target = gen_reg_rtx (mode);
2741
 
2742
  /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2743
     need to expand the argument again.  This way, we will not perform
2744
     side-effects more the once.  */
2745
  CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2746
 
2747
  op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2748
 
2749
  start_sequence ();
2750
 
2751
  /* Compute into TARGET.  */
2752
  if (expand_sfix_optab (target, op0, builtin_optab))
2753
    {
2754
      /* Output the entire sequence.  */
2755
      insns = get_insns ();
2756
      end_sequence ();
2757
      emit_insn (insns);
2758
      return target;
2759
    }
2760
 
2761
  /* If we were unable to expand via the builtin, stop the sequence
2762
     (without outputting the insns).  */
2763
  end_sequence ();
2764
 
2765
  /* Fall back to floating point rounding optab.  */
2766
  fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2767
 
2768
  /* For non-C99 targets we may end up without a fallback fndecl here
2769
     if the user called __builtin_lfloor directly.  In this case emit
2770
     a call to the floor/ceil variants nevertheless.  This should result
2771
     in the best user experience for not full C99 targets.  */
2772
  if (fallback_fndecl == NULL_TREE)
2773
    {
2774
      tree fntype;
2775
      const char *name = NULL;
2776
 
2777
      switch (DECL_FUNCTION_CODE (fndecl))
2778
        {
2779
        case BUILT_IN_ICEIL:
2780
        case BUILT_IN_LCEIL:
2781
        case BUILT_IN_LLCEIL:
2782
          name = "ceil";
2783
          break;
2784
        case BUILT_IN_ICEILF:
2785
        case BUILT_IN_LCEILF:
2786
        case BUILT_IN_LLCEILF:
2787
          name = "ceilf";
2788
          break;
2789
        case BUILT_IN_ICEILL:
2790
        case BUILT_IN_LCEILL:
2791
        case BUILT_IN_LLCEILL:
2792
          name = "ceill";
2793
          break;
2794
        case BUILT_IN_IFLOOR:
2795
        case BUILT_IN_LFLOOR:
2796
        case BUILT_IN_LLFLOOR:
2797
          name = "floor";
2798
          break;
2799
        case BUILT_IN_IFLOORF:
2800
        case BUILT_IN_LFLOORF:
2801
        case BUILT_IN_LLFLOORF:
2802
          name = "floorf";
2803
          break;
2804
        case BUILT_IN_IFLOORL:
2805
        case BUILT_IN_LFLOORL:
2806
        case BUILT_IN_LLFLOORL:
2807
          name = "floorl";
2808
          break;
2809
        default:
2810
          gcc_unreachable ();
2811
        }
2812
 
2813
      fntype = build_function_type_list (TREE_TYPE (arg),
2814
                                         TREE_TYPE (arg), NULL_TREE);
2815
      fallback_fndecl = build_fn_decl (name, fntype);
2816
    }
2817
 
2818
  exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg);
2819
 
2820
  tmp = expand_normal (exp);
2821
 
2822
  /* Truncate the result of floating point optab to integer
2823
     via expand_fix ().  */
2824
  target = gen_reg_rtx (mode);
2825
  expand_fix (target, tmp, 0);
2826
 
2827
  return target;
2828
}
2829
 
2830
/* Expand a call to one of the builtin math functions doing integer
2831
   conversion (lrint).
2832
   Return 0 if a normal call should be emitted rather than expanding the
2833
   function in-line.  EXP is the expression that is a call to the builtin
2834
   function; if convenient, the result should be placed in TARGET.  */
2835
 
2836
static rtx
2837
expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2838
{
2839
  convert_optab builtin_optab;
2840
  rtx op0, insns;
2841
  tree fndecl = get_callee_fndecl (exp);
2842
  tree arg;
2843
  enum machine_mode mode;
2844
 
2845
  /* There's no easy way to detect the case we need to set EDOM.  */
2846
  if (flag_errno_math)
2847
    return NULL_RTX;
2848
 
2849
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2850
     gcc_unreachable ();
2851
 
2852
  arg = CALL_EXPR_ARG (exp, 0);
2853
 
2854
  switch (DECL_FUNCTION_CODE (fndecl))
2855
    {
2856
    CASE_FLT_FN (BUILT_IN_IRINT):
2857
    CASE_FLT_FN (BUILT_IN_LRINT):
2858
    CASE_FLT_FN (BUILT_IN_LLRINT):
2859
      builtin_optab = lrint_optab; break;
2860
 
2861
    CASE_FLT_FN (BUILT_IN_IROUND):
2862
    CASE_FLT_FN (BUILT_IN_LROUND):
2863
    CASE_FLT_FN (BUILT_IN_LLROUND):
2864
      builtin_optab = lround_optab; break;
2865
 
2866
    default:
2867
      gcc_unreachable ();
2868
    }
2869
 
2870
  /* Make a suitable register to place result in.  */
2871
  mode = TYPE_MODE (TREE_TYPE (exp));
2872
 
2873
  target = gen_reg_rtx (mode);
2874
 
2875
  /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2876
     need to expand the argument again.  This way, we will not perform
2877
     side-effects more the once.  */
2878
  CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2879
 
2880
  op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2881
 
2882
  start_sequence ();
2883
 
2884
  if (expand_sfix_optab (target, op0, builtin_optab))
2885
    {
2886
      /* Output the entire sequence.  */
2887
      insns = get_insns ();
2888
      end_sequence ();
2889
      emit_insn (insns);
2890
      return target;
2891
    }
2892
 
2893
  /* If we were unable to expand via the builtin, stop the sequence
2894
     (without outputting the insns) and call to the library function
2895
     with the stabilized argument list.  */
2896
  end_sequence ();
2897
 
2898
  target = expand_call (exp, target, target == const0_rtx);
2899
 
2900
  return target;
2901
}
2902
 
2903
/* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
2904
   a normal call should be emitted rather than expanding the function
2905
   in-line.  EXP is the expression that is a call to the builtin
2906
   function; if convenient, the result should be placed in TARGET.  */
2907
 
2908
static rtx
2909
expand_builtin_powi (tree exp, rtx target)
2910
{
2911
  tree arg0, arg1;
2912
  rtx op0, op1;
2913
  enum machine_mode mode;
2914
  enum machine_mode mode2;
2915
 
2916
  if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2917
    return NULL_RTX;
2918
 
2919
  arg0 = CALL_EXPR_ARG (exp, 0);
2920
  arg1 = CALL_EXPR_ARG (exp, 1);
2921
  mode = TYPE_MODE (TREE_TYPE (exp));
2922
 
2923
  /* Emit a libcall to libgcc.  */
2924
 
2925
  /* Mode of the 2nd argument must match that of an int.  */
2926
  mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2927
 
2928
  if (target == NULL_RTX)
2929
    target = gen_reg_rtx (mode);
2930
 
2931
  op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL);
2932
  if (GET_MODE (op0) != mode)
2933
    op0 = convert_to_mode (mode, op0, 0);
2934
  op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
2935
  if (GET_MODE (op1) != mode2)
2936
    op1 = convert_to_mode (mode2, op1, 0);
2937
 
2938
  target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2939
                                    target, LCT_CONST, mode, 2,
2940
                                    op0, mode, op1, mode2);
2941
 
2942
  return target;
2943
}
2944
 
2945
/* Expand expression EXP which is a call to the strlen builtin.  Return
2946
   NULL_RTX if we failed the caller should emit a normal call, otherwise
2947
   try to get the result in TARGET, if convenient.  */
2948
 
2949
static rtx
2950
expand_builtin_strlen (tree exp, rtx target,
2951
                       enum machine_mode target_mode)
2952
{
2953
  if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2954
    return NULL_RTX;
2955
  else
2956
    {
2957
      struct expand_operand ops[4];
2958
      rtx pat;
2959
      tree len;
2960
      tree src = CALL_EXPR_ARG (exp, 0);
2961
      rtx src_reg, before_strlen;
2962
      enum machine_mode insn_mode = target_mode;
2963
      enum insn_code icode = CODE_FOR_nothing;
2964
      unsigned int align;
2965
 
2966
      /* If the length can be computed at compile-time, return it.  */
2967
      len = c_strlen (src, 0);
2968
      if (len)
2969
        return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2970
 
2971
      /* If the length can be computed at compile-time and is constant
2972
         integer, but there are side-effects in src, evaluate
2973
         src for side-effects, then return len.
2974
         E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2975
         can be optimized into: i++; x = 3;  */
2976
      len = c_strlen (src, 1);
2977
      if (len && TREE_CODE (len) == INTEGER_CST)
2978
        {
2979
          expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2980
          return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2981
        }
2982
 
2983
      align = get_pointer_alignment (src) / BITS_PER_UNIT;
2984
 
2985
      /* If SRC is not a pointer type, don't do this operation inline.  */
2986
      if (align == 0)
2987
        return NULL_RTX;
2988
 
2989
      /* Bail out if we can't compute strlen in the right mode.  */
2990
      while (insn_mode != VOIDmode)
2991
        {
2992
          icode = optab_handler (strlen_optab, insn_mode);
2993
          if (icode != CODE_FOR_nothing)
2994
            break;
2995
 
2996
          insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2997
        }
2998
      if (insn_mode == VOIDmode)
2999
        return NULL_RTX;
3000
 
3001
      /* Make a place to hold the source address.  We will not expand
3002
         the actual source until we are sure that the expansion will
3003
         not fail -- there are trees that cannot be expanded twice.  */
3004
      src_reg = gen_reg_rtx (Pmode);
3005
 
3006
      /* Mark the beginning of the strlen sequence so we can emit the
3007
         source operand later.  */
3008
      before_strlen = get_last_insn ();
3009
 
3010
      create_output_operand (&ops[0], target, insn_mode);
3011
      create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg));
3012
      create_integer_operand (&ops[2], 0);
3013
      create_integer_operand (&ops[3], align);
3014
      if (!maybe_expand_insn (icode, 4, ops))
3015
        return NULL_RTX;
3016
 
3017
      /* Now that we are assured of success, expand the source.  */
3018
      start_sequence ();
3019
      pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL);
3020
      if (pat != src_reg)
3021
        {
3022
#ifdef POINTERS_EXTEND_UNSIGNED
3023
          if (GET_MODE (pat) != Pmode)
3024
            pat = convert_to_mode (Pmode, pat,
3025
                                   POINTERS_EXTEND_UNSIGNED);
3026
#endif
3027
          emit_move_insn (src_reg, pat);
3028
        }
3029
      pat = get_insns ();
3030
      end_sequence ();
3031
 
3032
      if (before_strlen)
3033
        emit_insn_after (pat, before_strlen);
3034
      else
3035
        emit_insn_before (pat, get_insns ());
3036
 
3037
      /* Return the value in the proper mode for this function.  */
3038
      if (GET_MODE (ops[0].value) == target_mode)
3039
        target = ops[0].value;
3040
      else if (target != 0)
3041
        convert_move (target, ops[0].value, 0);
3042
      else
3043
        target = convert_to_mode (target_mode, ops[0].value, 0);
3044
 
3045
      return target;
3046
    }
3047
}
3048
 
3049
/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3050
   bytes from constant string DATA + OFFSET and return it as target
3051
   constant.  */
3052
 
3053
static rtx
3054
builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3055
                         enum machine_mode mode)
3056
{
3057
  const char *str = (const char *) data;
3058
 
3059
  gcc_assert (offset >= 0
3060
              && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3061
                  <= strlen (str) + 1));
3062
 
3063
  return c_readstr (str + offset, mode);
3064
}
3065
 
3066
/* Expand a call EXP to the memcpy builtin.
3067
   Return NULL_RTX if we failed, the caller should emit a normal call,
3068
   otherwise try to get the result in TARGET, if convenient (and in
3069
   mode MODE if that's convenient).  */
3070
 
3071
static rtx
3072
expand_builtin_memcpy (tree exp, rtx target)
3073
{
3074
  if (!validate_arglist (exp,
3075
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3076
    return NULL_RTX;
3077
  else
3078
    {
3079
      tree dest = CALL_EXPR_ARG (exp, 0);
3080
      tree src = CALL_EXPR_ARG (exp, 1);
3081
      tree len = CALL_EXPR_ARG (exp, 2);
3082
      const char *src_str;
3083
      unsigned int src_align = get_pointer_alignment (src);
3084
      unsigned int dest_align = get_pointer_alignment (dest);
3085
      rtx dest_mem, src_mem, dest_addr, len_rtx;
3086
      HOST_WIDE_INT expected_size = -1;
3087
      unsigned int expected_align = 0;
3088
 
3089
      /* If DEST is not a pointer type, call the normal function.  */
3090
      if (dest_align == 0)
3091
        return NULL_RTX;
3092
 
3093
      /* If either SRC is not a pointer type, don't do this
3094
         operation in-line.  */
3095
      if (src_align == 0)
3096
        return NULL_RTX;
3097
 
3098
      if (currently_expanding_gimple_stmt)
3099
        stringop_block_profile (currently_expanding_gimple_stmt,
3100
                                &expected_align, &expected_size);
3101
 
3102
      if (expected_align < dest_align)
3103
        expected_align = dest_align;
3104
      dest_mem = get_memory_rtx (dest, len);
3105
      set_mem_align (dest_mem, dest_align);
3106
      len_rtx = expand_normal (len);
3107
      src_str = c_getstr (src);
3108
 
3109
      /* If SRC is a string constant and block move would be done
3110
         by pieces, we can avoid loading the string from memory
3111
         and only stored the computed constants.  */
3112
      if (src_str
3113
          && CONST_INT_P (len_rtx)
3114
          && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3115
          && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3116
                                  CONST_CAST (char *, src_str),
3117
                                  dest_align, false))
3118
        {
3119
          dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3120
                                      builtin_memcpy_read_str,
3121
                                      CONST_CAST (char *, src_str),
3122
                                      dest_align, false, 0);
3123
          dest_mem = force_operand (XEXP (dest_mem, 0), target);
3124
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3125
          return dest_mem;
3126
        }
3127
 
3128
      src_mem = get_memory_rtx (src, len);
3129
      set_mem_align (src_mem, src_align);
3130
 
3131
      /* Copy word part most expediently.  */
3132
      dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3133
                                         CALL_EXPR_TAILCALL (exp)
3134
                                         ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3135
                                         expected_align, expected_size);
3136
 
3137
      if (dest_addr == 0)
3138
        {
3139
          dest_addr = force_operand (XEXP (dest_mem, 0), target);
3140
          dest_addr = convert_memory_address (ptr_mode, dest_addr);
3141
        }
3142
      return dest_addr;
3143
    }
3144
}
3145
 
3146
/* Expand a call EXP to the mempcpy builtin.
3147
   Return NULL_RTX if we failed; the caller should emit a normal call,
3148
   otherwise try to get the result in TARGET, if convenient (and in
3149
   mode MODE if that's convenient).  If ENDP is 0 return the
3150
   destination pointer, if ENDP is 1 return the end pointer ala
3151
   mempcpy, and if ENDP is 2 return the end pointer minus one ala
3152
   stpcpy.  */
3153
 
3154
static rtx
3155
expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3156
{
3157
  if (!validate_arglist (exp,
3158
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3159
    return NULL_RTX;
3160
  else
3161
    {
3162
      tree dest = CALL_EXPR_ARG (exp, 0);
3163
      tree src = CALL_EXPR_ARG (exp, 1);
3164
      tree len = CALL_EXPR_ARG (exp, 2);
3165
      return expand_builtin_mempcpy_args (dest, src, len,
3166
                                          target, mode, /*endp=*/ 1);
3167
    }
3168
}
3169
 
3170
/* Helper function to do the actual work for expand_builtin_mempcpy.  The
3171
   arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3172
   so that this can also be called without constructing an actual CALL_EXPR.
3173
   The other arguments and return value are the same as for
3174
   expand_builtin_mempcpy.  */
3175
 
3176
static rtx
3177
expand_builtin_mempcpy_args (tree dest, tree src, tree len,
3178
                             rtx target, enum machine_mode mode, int endp)
3179
{
3180
    /* If return value is ignored, transform mempcpy into memcpy.  */
3181
  if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
3182
    {
3183
      tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3184
      tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
3185
                                           dest, src, len);
3186
      return expand_expr (result, target, mode, EXPAND_NORMAL);
3187
    }
3188
  else
3189
    {
3190
      const char *src_str;
3191
      unsigned int src_align = get_pointer_alignment (src);
3192
      unsigned int dest_align = get_pointer_alignment (dest);
3193
      rtx dest_mem, src_mem, len_rtx;
3194
 
3195
      /* If either SRC or DEST is not a pointer type, don't do this
3196
         operation in-line.  */
3197
      if (dest_align == 0 || src_align == 0)
3198
        return NULL_RTX;
3199
 
3200
      /* If LEN is not constant, call the normal function.  */
3201
      if (! host_integerp (len, 1))
3202
        return NULL_RTX;
3203
 
3204
      len_rtx = expand_normal (len);
3205
      src_str = c_getstr (src);
3206
 
3207
      /* If SRC is a string constant and block move would be done
3208
         by pieces, we can avoid loading the string from memory
3209
         and only stored the computed constants.  */
3210
      if (src_str
3211
          && CONST_INT_P (len_rtx)
3212
          && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3213
          && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3214
                                  CONST_CAST (char *, src_str),
3215
                                  dest_align, false))
3216
        {
3217
          dest_mem = get_memory_rtx (dest, len);
3218
          set_mem_align (dest_mem, dest_align);
3219
          dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3220
                                      builtin_memcpy_read_str,
3221
                                      CONST_CAST (char *, src_str),
3222
                                      dest_align, false, endp);
3223
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3224
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3225
          return dest_mem;
3226
        }
3227
 
3228
      if (CONST_INT_P (len_rtx)
3229
          && can_move_by_pieces (INTVAL (len_rtx),
3230
                                 MIN (dest_align, src_align)))
3231
        {
3232
          dest_mem = get_memory_rtx (dest, len);
3233
          set_mem_align (dest_mem, dest_align);
3234
          src_mem = get_memory_rtx (src, len);
3235
          set_mem_align (src_mem, src_align);
3236
          dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3237
                                     MIN (dest_align, src_align), endp);
3238
          dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3239
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3240
          return dest_mem;
3241
        }
3242
 
3243
      return NULL_RTX;
3244
    }
3245
}
3246
 
3247
#ifndef HAVE_movstr
3248
# define HAVE_movstr 0
3249
# define CODE_FOR_movstr CODE_FOR_nothing
3250
#endif
3251
 
3252
/* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3253
   we failed, the caller should emit a normal call, otherwise try to
3254
   get the result in TARGET, if convenient.  If ENDP is 0 return the
3255
   destination pointer, if ENDP is 1 return the end pointer ala
3256
   mempcpy, and if ENDP is 2 return the end pointer minus one ala
3257
   stpcpy.  */
3258
 
3259
static rtx
3260
expand_movstr (tree dest, tree src, rtx target, int endp)
3261
{
3262
  struct expand_operand ops[3];
3263
  rtx dest_mem;
3264
  rtx src_mem;
3265
 
3266
  if (!HAVE_movstr)
3267
    return NULL_RTX;
3268
 
3269
  dest_mem = get_memory_rtx (dest, NULL);
3270
  src_mem = get_memory_rtx (src, NULL);
3271
  if (!endp)
3272
    {
3273
      target = force_reg (Pmode, XEXP (dest_mem, 0));
3274
      dest_mem = replace_equiv_address (dest_mem, target);
3275
    }
3276
 
3277
  create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode);
3278
  create_fixed_operand (&ops[1], dest_mem);
3279
  create_fixed_operand (&ops[2], src_mem);
3280
  expand_insn (CODE_FOR_movstr, 3, ops);
3281
 
3282
  if (endp && target != const0_rtx)
3283
    {
3284
      target = ops[0].value;
3285
      /* movstr is supposed to set end to the address of the NUL
3286
         terminator.  If the caller requested a mempcpy-like return value,
3287
         adjust it.  */
3288
      if (endp == 1)
3289
        {
3290
          rtx tem = plus_constant (gen_lowpart (GET_MODE (target), target), 1);
3291
          emit_move_insn (target, force_operand (tem, NULL_RTX));
3292
        }
3293
    }
3294
  return target;
3295
}
3296
 
3297
/* Expand expression EXP, which is a call to the strcpy builtin.  Return
3298
   NULL_RTX if we failed the caller should emit a normal call, otherwise
3299
   try to get the result in TARGET, if convenient (and in mode MODE if that's
3300
   convenient).  */
3301
 
3302
static rtx
3303
expand_builtin_strcpy (tree exp, rtx target)
3304
{
3305
  if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3306
   {
3307
     tree dest = CALL_EXPR_ARG (exp, 0);
3308
     tree src = CALL_EXPR_ARG (exp, 1);
3309
     return expand_builtin_strcpy_args (dest, src, target);
3310
   }
3311
   return NULL_RTX;
3312
}
3313
 
3314
/* Helper function to do the actual work for expand_builtin_strcpy.  The
3315
   arguments to the builtin_strcpy call DEST and SRC are broken out
3316
   so that this can also be called without constructing an actual CALL_EXPR.
3317
   The other arguments and return value are the same as for
3318
   expand_builtin_strcpy.  */
3319
 
3320
static rtx
3321
expand_builtin_strcpy_args (tree dest, tree src, rtx target)
3322
{
3323
  return expand_movstr (dest, src, target, /*endp=*/0);
3324
}
3325
 
3326
/* Expand a call EXP to the stpcpy builtin.
3327
   Return NULL_RTX if we failed the caller should emit a normal call,
3328
   otherwise try to get the result in TARGET, if convenient (and in
3329
   mode MODE if that's convenient).  */
3330
 
3331
static rtx
3332
expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3333
{
3334
  tree dst, src;
3335
  location_t loc = EXPR_LOCATION (exp);
3336
 
3337
  if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3338
    return NULL_RTX;
3339
 
3340
  dst = CALL_EXPR_ARG (exp, 0);
3341
  src = CALL_EXPR_ARG (exp, 1);
3342
 
3343
  /* If return value is ignored, transform stpcpy into strcpy.  */
3344
  if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY))
3345
    {
3346
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3347
      tree result = build_call_nofold_loc (loc, fn, 2, dst, src);
3348
      return expand_expr (result, target, mode, EXPAND_NORMAL);
3349
    }
3350
  else
3351
    {
3352
      tree len, lenp1;
3353
      rtx ret;
3354
 
3355
      /* Ensure we get an actual string whose length can be evaluated at
3356
         compile-time, not an expression containing a string.  This is
3357
         because the latter will potentially produce pessimized code
3358
         when used to produce the return value.  */
3359
      if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3360
        return expand_movstr (dst, src, target, /*endp=*/2);
3361
 
3362
      lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
3363
      ret = expand_builtin_mempcpy_args (dst, src, lenp1,
3364
                                         target, mode, /*endp=*/2);
3365
 
3366
      if (ret)
3367
        return ret;
3368
 
3369
      if (TREE_CODE (len) == INTEGER_CST)
3370
        {
3371
          rtx len_rtx = expand_normal (len);
3372
 
3373
          if (CONST_INT_P (len_rtx))
3374
            {
3375
              ret = expand_builtin_strcpy_args (dst, src, target);
3376
 
3377
              if (ret)
3378
                {
3379
                  if (! target)
3380
                    {
3381
                      if (mode != VOIDmode)
3382
                        target = gen_reg_rtx (mode);
3383
                      else
3384
                        target = gen_reg_rtx (GET_MODE (ret));
3385
                    }
3386
                  if (GET_MODE (target) != GET_MODE (ret))
3387
                    ret = gen_lowpart (GET_MODE (target), ret);
3388
 
3389
                  ret = plus_constant (ret, INTVAL (len_rtx));
3390
                  ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3391
                  gcc_assert (ret);
3392
 
3393
                  return target;
3394
                }
3395
            }
3396
        }
3397
 
3398
      return expand_movstr (dst, src, target, /*endp=*/2);
3399
    }
3400
}
3401
 
3402
/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3403
   bytes from constant string DATA + OFFSET and return it as target
3404
   constant.  */
3405
 
3406
rtx
3407
builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3408
                          enum machine_mode mode)
3409
{
3410
  const char *str = (const char *) data;
3411
 
3412
  if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3413
    return const0_rtx;
3414
 
3415
  return c_readstr (str + offset, mode);
3416
}
3417
 
3418
/* Expand expression EXP, which is a call to the strncpy builtin.  Return
3419
   NULL_RTX if we failed the caller should emit a normal call.  */
3420
 
3421
static rtx
3422
expand_builtin_strncpy (tree exp, rtx target)
3423
{
3424
  location_t loc = EXPR_LOCATION (exp);
3425
 
3426
  if (validate_arglist (exp,
3427
                        POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3428
    {
3429
      tree dest = CALL_EXPR_ARG (exp, 0);
3430
      tree src = CALL_EXPR_ARG (exp, 1);
3431
      tree len = CALL_EXPR_ARG (exp, 2);
3432
      tree slen = c_strlen (src, 1);
3433
 
3434
      /* We must be passed a constant len and src parameter.  */
3435
      if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3436
        return NULL_RTX;
3437
 
3438
      slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
3439
 
3440
      /* We're required to pad with trailing zeros if the requested
3441
         len is greater than strlen(s2)+1.  In that case try to
3442
         use store_by_pieces, if it fails, punt.  */
3443
      if (tree_int_cst_lt (slen, len))
3444
        {
3445
          unsigned int dest_align = get_pointer_alignment (dest);
3446
          const char *p = c_getstr (src);
3447
          rtx dest_mem;
3448
 
3449
          if (!p || dest_align == 0 || !host_integerp (len, 1)
3450
              || !can_store_by_pieces (tree_low_cst (len, 1),
3451
                                       builtin_strncpy_read_str,
3452
                                       CONST_CAST (char *, p),
3453
                                       dest_align, false))
3454
            return NULL_RTX;
3455
 
3456
          dest_mem = get_memory_rtx (dest, len);
3457
          store_by_pieces (dest_mem, tree_low_cst (len, 1),
3458
                           builtin_strncpy_read_str,
3459
                           CONST_CAST (char *, p), dest_align, false, 0);
3460
          dest_mem = force_operand (XEXP (dest_mem, 0), target);
3461
          dest_mem = convert_memory_address (ptr_mode, dest_mem);
3462
          return dest_mem;
3463
        }
3464
    }
3465
  return NULL_RTX;
3466
}
3467
 
3468
/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3469
   bytes from constant string DATA + OFFSET and return it as target
3470
   constant.  */
3471
 
3472
rtx
3473
builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3474
                         enum machine_mode mode)
3475
{
3476
  const char *c = (const char *) data;
3477
  char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3478
 
3479
  memset (p, *c, GET_MODE_SIZE (mode));
3480
 
3481
  return c_readstr (p, mode);
3482
}
3483
 
3484
/* Callback routine for store_by_pieces.  Return the RTL of a register
3485
   containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3486
   char value given in the RTL register data.  For example, if mode is
3487
   4 bytes wide, return the RTL for 0x01010101*data.  */
3488
 
3489
static rtx
3490
builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3491
                        enum machine_mode mode)
3492
{
3493
  rtx target, coeff;
3494
  size_t size;
3495
  char *p;
3496
 
3497
  size = GET_MODE_SIZE (mode);
3498
  if (size == 1)
3499
    return (rtx) data;
3500
 
3501
  p = XALLOCAVEC (char, size);
3502
  memset (p, 1, size);
3503
  coeff = c_readstr (p, mode);
3504
 
3505
  target = convert_to_mode (mode, (rtx) data, 1);
3506
  target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3507
  return force_reg (mode, target);
3508
}
3509
 
3510
/* Expand expression EXP, which is a call to the memset builtin.  Return
3511
   NULL_RTX if we failed the caller should emit a normal call, otherwise
3512
   try to get the result in TARGET, if convenient (and in mode MODE if that's
3513
   convenient).  */
3514
 
3515
static rtx
3516
expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3517
{
3518
  if (!validate_arglist (exp,
3519
                         POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3520
    return NULL_RTX;
3521
  else
3522
    {
3523
      tree dest = CALL_EXPR_ARG (exp, 0);
3524
      tree val = CALL_EXPR_ARG (exp, 1);
3525
      tree len = CALL_EXPR_ARG (exp, 2);
3526
      return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3527
    }
3528
}
3529
 
3530
/* Helper function to do the actual work for expand_builtin_memset.  The
3531
   arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3532
   so that this can also be called without constructing an actual CALL_EXPR.
3533
   The other arguments and return value are the same as for
3534
   expand_builtin_memset.  */
3535
 
3536
static rtx
3537
expand_builtin_memset_args (tree dest, tree val, tree len,
3538
                            rtx target, enum machine_mode mode, tree orig_exp)
3539
{
3540
  tree fndecl, fn;
3541
  enum built_in_function fcode;
3542
  enum machine_mode val_mode;
3543
  char c;
3544
  unsigned int dest_align;
3545
  rtx dest_mem, dest_addr, len_rtx;
3546
  HOST_WIDE_INT expected_size = -1;
3547
  unsigned int expected_align = 0;
3548
 
3549
  dest_align = get_pointer_alignment (dest);
3550
 
3551
  /* If DEST is not a pointer type, don't do this operation in-line.  */
3552
  if (dest_align == 0)
3553
    return NULL_RTX;
3554
 
3555
  if (currently_expanding_gimple_stmt)
3556
    stringop_block_profile (currently_expanding_gimple_stmt,
3557
                            &expected_align, &expected_size);
3558
 
3559
  if (expected_align < dest_align)
3560
    expected_align = dest_align;
3561
 
3562
  /* If the LEN parameter is zero, return DEST.  */
3563
  if (integer_zerop (len))
3564
    {
3565
      /* Evaluate and ignore VAL in case it has side-effects.  */
3566
      expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3567
      return expand_expr (dest, target, mode, EXPAND_NORMAL);
3568
    }
3569
 
3570
  /* Stabilize the arguments in case we fail.  */
3571
  dest = builtin_save_expr (dest);
3572
  val = builtin_save_expr (val);
3573
  len = builtin_save_expr (len);
3574
 
3575
  len_rtx = expand_normal (len);
3576
  dest_mem = get_memory_rtx (dest, len);
3577
  val_mode = TYPE_MODE (unsigned_char_type_node);
3578
 
3579
  if (TREE_CODE (val) != INTEGER_CST)
3580
    {
3581
      rtx val_rtx;
3582
 
3583
      val_rtx = expand_normal (val);
3584
      val_rtx = convert_to_mode (val_mode, val_rtx, 0);
3585
 
3586
      /* Assume that we can memset by pieces if we can store
3587
       * the coefficients by pieces (in the required modes).
3588
       * We can't pass builtin_memset_gen_str as that emits RTL.  */
3589
      c = 1;
3590
      if (host_integerp (len, 1)
3591
          && can_store_by_pieces (tree_low_cst (len, 1),
3592
                                  builtin_memset_read_str, &c, dest_align,
3593
                                  true))
3594
        {
3595
          val_rtx = force_reg (val_mode, val_rtx);
3596
          store_by_pieces (dest_mem, tree_low_cst (len, 1),
3597
                           builtin_memset_gen_str, val_rtx, dest_align,
3598
                           true, 0);
3599
        }
3600
      else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3601
                                        dest_align, expected_align,
3602
                                        expected_size))
3603
        goto do_libcall;
3604
 
3605
      dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3606
      dest_mem = convert_memory_address (ptr_mode, dest_mem);
3607
      return dest_mem;
3608
    }
3609
 
3610
  if (target_char_cast (val, &c))
3611
    goto do_libcall;
3612
 
3613
  if (c)
3614
    {
3615
      if (host_integerp (len, 1)
3616
          && can_store_by_pieces (tree_low_cst (len, 1),
3617
                                  builtin_memset_read_str, &c, dest_align,
3618
                                  true))
3619
        store_by_pieces (dest_mem, tree_low_cst (len, 1),
3620
                         builtin_memset_read_str, &c, dest_align, true, 0);
3621
      else if (!set_storage_via_setmem (dest_mem, len_rtx,
3622
                                        gen_int_mode (c, val_mode),
3623
                                        dest_align, expected_align,
3624
                                        expected_size))
3625
        goto do_libcall;
3626
 
3627
      dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3628
      dest_mem = convert_memory_address (ptr_mode, dest_mem);
3629
      return dest_mem;
3630
    }
3631
 
3632
  set_mem_align (dest_mem, dest_align);
3633
  dest_addr = clear_storage_hints (dest_mem, len_rtx,
3634
                                   CALL_EXPR_TAILCALL (orig_exp)
3635
                                   ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3636
                                   expected_align, expected_size);
3637
 
3638
  if (dest_addr == 0)
3639
    {
3640
      dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3641
      dest_addr = convert_memory_address (ptr_mode, dest_addr);
3642
    }
3643
 
3644
  return dest_addr;
3645
 
3646
 do_libcall:
3647
  fndecl = get_callee_fndecl (orig_exp);
3648
  fcode = DECL_FUNCTION_CODE (fndecl);
3649
  if (fcode == BUILT_IN_MEMSET)
3650
    fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3,
3651
                                dest, val, len);
3652
  else if (fcode == BUILT_IN_BZERO)
3653
    fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2,
3654
                                dest, len);
3655
  else
3656
    gcc_unreachable ();
3657
  gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3658
  CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3659
  return expand_call (fn, target, target == const0_rtx);
3660
}
3661
 
3662
/* Expand expression EXP, which is a call to the bzero builtin.  Return
3663
   NULL_RTX if we failed the caller should emit a normal call.  */
3664
 
3665
static rtx
3666
expand_builtin_bzero (tree exp)
3667
{
3668
  tree dest, size;
3669
  location_t loc = EXPR_LOCATION (exp);
3670
 
3671
  if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3672
    return NULL_RTX;
3673
 
3674
  dest = CALL_EXPR_ARG (exp, 0);
3675
  size = CALL_EXPR_ARG (exp, 1);
3676
 
3677
  /* New argument list transforming bzero(ptr x, int y) to
3678
     memset(ptr x, int 0, size_t y).   This is done this way
3679
     so that if it isn't expanded inline, we fallback to
3680
     calling bzero instead of memset.  */
3681
 
3682
  return expand_builtin_memset_args (dest, integer_zero_node,
3683
                                     fold_convert_loc (loc,
3684
                                                       size_type_node, size),
3685
                                     const0_rtx, VOIDmode, exp);
3686
}
3687
 
3688
/* Expand expression EXP, which is a call to the memcmp built-in function.
3689
   Return NULL_RTX if we failed and the caller should emit a normal call,
3690
   otherwise try to get the result in TARGET, if convenient (and in mode
3691
   MODE, if that's convenient).  */
3692
 
3693
static rtx
3694
expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3695
                       ATTRIBUTE_UNUSED enum machine_mode mode)
3696
{
3697
  location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3698
 
3699
  if (!validate_arglist (exp,
3700
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3701
    return NULL_RTX;
3702
 
3703
  /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
3704
     implementing memcmp because it will stop if it encounters two
3705
     zero bytes.  */
3706
#if defined HAVE_cmpmemsi
3707
  {
3708
    rtx arg1_rtx, arg2_rtx, arg3_rtx;
3709
    rtx result;
3710
    rtx insn;
3711
    tree arg1 = CALL_EXPR_ARG (exp, 0);
3712
    tree arg2 = CALL_EXPR_ARG (exp, 1);
3713
    tree len = CALL_EXPR_ARG (exp, 2);
3714
 
3715
    unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3716
    unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3717
    enum machine_mode insn_mode;
3718
 
3719
    if (HAVE_cmpmemsi)
3720
      insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3721
    else
3722
      return NULL_RTX;
3723
 
3724
    /* If we don't have POINTER_TYPE, call the function.  */
3725
    if (arg1_align == 0 || arg2_align == 0)
3726
      return NULL_RTX;
3727
 
3728
    /* Make a place to write the result of the instruction.  */
3729
    result = target;
3730
    if (! (result != 0
3731
           && REG_P (result) && GET_MODE (result) == insn_mode
3732
           && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3733
      result = gen_reg_rtx (insn_mode);
3734
 
3735
    arg1_rtx = get_memory_rtx (arg1, len);
3736
    arg2_rtx = get_memory_rtx (arg2, len);
3737
    arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
3738
 
3739
    /* Set MEM_SIZE as appropriate.  */
3740
    if (CONST_INT_P (arg3_rtx))
3741
      {
3742
        set_mem_size (arg1_rtx, INTVAL (arg3_rtx));
3743
        set_mem_size (arg2_rtx, INTVAL (arg3_rtx));
3744
      }
3745
 
3746
    if (HAVE_cmpmemsi)
3747
      insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3748
                           GEN_INT (MIN (arg1_align, arg2_align)));
3749
    else
3750
      gcc_unreachable ();
3751
 
3752
    if (insn)
3753
      emit_insn (insn);
3754
    else
3755
      emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
3756
                               TYPE_MODE (integer_type_node), 3,
3757
                               XEXP (arg1_rtx, 0), Pmode,
3758
                               XEXP (arg2_rtx, 0), Pmode,
3759
                               convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3760
                                                TYPE_UNSIGNED (sizetype)),
3761
                               TYPE_MODE (sizetype));
3762
 
3763
    /* Return the value in the proper mode for this function.  */
3764
    mode = TYPE_MODE (TREE_TYPE (exp));
3765
    if (GET_MODE (result) == mode)
3766
      return result;
3767
    else if (target != 0)
3768
      {
3769
        convert_move (target, result, 0);
3770
        return target;
3771
      }
3772
    else
3773
      return convert_to_mode (mode, result, 0);
3774
  }
3775
#endif /* HAVE_cmpmemsi.  */
3776
 
3777
  return NULL_RTX;
3778
}
3779
 
3780
/* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
3781
   if we failed the caller should emit a normal call, otherwise try to get
3782
   the result in TARGET, if convenient.  */
3783
 
3784
static rtx
3785
expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
3786
{
3787
  if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3788
    return NULL_RTX;
3789
 
3790
#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3791
  if (direct_optab_handler (cmpstr_optab, SImode) != CODE_FOR_nothing
3792
      || direct_optab_handler (cmpstrn_optab, SImode) != CODE_FOR_nothing)
3793
    {
3794
      rtx arg1_rtx, arg2_rtx;
3795
      rtx result, insn = NULL_RTX;
3796
      tree fndecl, fn;
3797
      tree arg1 = CALL_EXPR_ARG (exp, 0);
3798
      tree arg2 = CALL_EXPR_ARG (exp, 1);
3799
 
3800
      unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3801
      unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3802
 
3803
      /* If we don't have POINTER_TYPE, call the function.  */
3804
      if (arg1_align == 0 || arg2_align == 0)
3805
        return NULL_RTX;
3806
 
3807
      /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3808
      arg1 = builtin_save_expr (arg1);
3809
      arg2 = builtin_save_expr (arg2);
3810
 
3811
      arg1_rtx = get_memory_rtx (arg1, NULL);
3812
      arg2_rtx = get_memory_rtx (arg2, NULL);
3813
 
3814
#ifdef HAVE_cmpstrsi
3815
      /* Try to call cmpstrsi.  */
3816
      if (HAVE_cmpstrsi)
3817
        {
3818
          enum machine_mode insn_mode
3819
            = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3820
 
3821
          /* Make a place to write the result of the instruction.  */
3822
          result = target;
3823
          if (! (result != 0
3824
                 && REG_P (result) && GET_MODE (result) == insn_mode
3825
                 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3826
            result = gen_reg_rtx (insn_mode);
3827
 
3828
          insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3829
                               GEN_INT (MIN (arg1_align, arg2_align)));
3830
        }
3831
#endif
3832
#ifdef HAVE_cmpstrnsi
3833
      /* Try to determine at least one length and call cmpstrnsi.  */
3834
      if (!insn && HAVE_cmpstrnsi)
3835
        {
3836
          tree len;
3837
          rtx arg3_rtx;
3838
 
3839
          enum machine_mode insn_mode
3840
            = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3841
          tree len1 = c_strlen (arg1, 1);
3842
          tree len2 = c_strlen (arg2, 1);
3843
 
3844
          if (len1)
3845
            len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3846
          if (len2)
3847
            len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3848
 
3849
          /* If we don't have a constant length for the first, use the length
3850
             of the second, if we know it.  We don't require a constant for
3851
             this case; some cost analysis could be done if both are available
3852
             but neither is constant.  For now, assume they're equally cheap,
3853
             unless one has side effects.  If both strings have constant lengths,
3854
             use the smaller.  */
3855
 
3856
          if (!len1)
3857
            len = len2;
3858
          else if (!len2)
3859
            len = len1;
3860
          else if (TREE_SIDE_EFFECTS (len1))
3861
            len = len2;
3862
          else if (TREE_SIDE_EFFECTS (len2))
3863
            len = len1;
3864
          else if (TREE_CODE (len1) != INTEGER_CST)
3865
            len = len2;
3866
          else if (TREE_CODE (len2) != INTEGER_CST)
3867
            len = len1;
3868
          else if (tree_int_cst_lt (len1, len2))
3869
            len = len1;
3870
          else
3871
            len = len2;
3872
 
3873
          /* If both arguments have side effects, we cannot optimize.  */
3874
          if (!len || TREE_SIDE_EFFECTS (len))
3875
            goto do_libcall;
3876
 
3877
          arg3_rtx = expand_normal (len);
3878
 
3879
          /* Make a place to write the result of the instruction.  */
3880
          result = target;
3881
          if (! (result != 0
3882
                 && REG_P (result) && GET_MODE (result) == insn_mode
3883
                 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3884
            result = gen_reg_rtx (insn_mode);
3885
 
3886
          insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3887
                                GEN_INT (MIN (arg1_align, arg2_align)));
3888
        }
3889
#endif
3890
 
3891
      if (insn)
3892
        {
3893
          enum machine_mode mode;
3894
          emit_insn (insn);
3895
 
3896
          /* Return the value in the proper mode for this function.  */
3897
          mode = TYPE_MODE (TREE_TYPE (exp));
3898
          if (GET_MODE (result) == mode)
3899
            return result;
3900
          if (target == 0)
3901
            return convert_to_mode (mode, result, 0);
3902
          convert_move (target, result, 0);
3903
          return target;
3904
        }
3905
 
3906
      /* Expand the library call ourselves using a stabilized argument
3907
         list to avoid re-evaluating the function's arguments twice.  */
3908
#ifdef HAVE_cmpstrnsi
3909
    do_libcall:
3910
#endif
3911
      fndecl = get_callee_fndecl (exp);
3912
      fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
3913
      gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3914
      CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3915
      return expand_call (fn, target, target == const0_rtx);
3916
    }
3917
#endif
3918
  return NULL_RTX;
3919
}
3920
 
3921
/* Expand expression EXP, which is a call to the strncmp builtin. Return
3922
   NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
3923
   the result in TARGET, if convenient.  */
3924
 
3925
static rtx
3926
expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3927
                        ATTRIBUTE_UNUSED enum machine_mode mode)
3928
{
3929
  location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3930
 
3931
  if (!validate_arglist (exp,
3932
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3933
    return NULL_RTX;
3934
 
3935
  /* If c_strlen can determine an expression for one of the string
3936
     lengths, and it doesn't have side effects, then emit cmpstrnsi
3937
     using length MIN(strlen(string)+1, arg3).  */
3938
#ifdef HAVE_cmpstrnsi
3939
  if (HAVE_cmpstrnsi)
3940
  {
3941
    tree len, len1, len2;
3942
    rtx arg1_rtx, arg2_rtx, arg3_rtx;
3943
    rtx result, insn;
3944
    tree fndecl, fn;
3945
    tree arg1 = CALL_EXPR_ARG (exp, 0);
3946
    tree arg2 = CALL_EXPR_ARG (exp, 1);
3947
    tree arg3 = CALL_EXPR_ARG (exp, 2);
3948
 
3949
    unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3950
    unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3951
    enum machine_mode insn_mode
3952
      = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3953
 
3954
    len1 = c_strlen (arg1, 1);
3955
    len2 = c_strlen (arg2, 1);
3956
 
3957
    if (len1)
3958
      len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
3959
    if (len2)
3960
      len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
3961
 
3962
    /* If we don't have a constant length for the first, use the length
3963
       of the second, if we know it.  We don't require a constant for
3964
       this case; some cost analysis could be done if both are available
3965
       but neither is constant.  For now, assume they're equally cheap,
3966
       unless one has side effects.  If both strings have constant lengths,
3967
       use the smaller.  */
3968
 
3969
    if (!len1)
3970
      len = len2;
3971
    else if (!len2)
3972
      len = len1;
3973
    else if (TREE_SIDE_EFFECTS (len1))
3974
      len = len2;
3975
    else if (TREE_SIDE_EFFECTS (len2))
3976
      len = len1;
3977
    else if (TREE_CODE (len1) != INTEGER_CST)
3978
      len = len2;
3979
    else if (TREE_CODE (len2) != INTEGER_CST)
3980
      len = len1;
3981
    else if (tree_int_cst_lt (len1, len2))
3982
      len = len1;
3983
    else
3984
      len = len2;
3985
 
3986
    /* If both arguments have side effects, we cannot optimize.  */
3987
    if (!len || TREE_SIDE_EFFECTS (len))
3988
      return NULL_RTX;
3989
 
3990
    /* The actual new length parameter is MIN(len,arg3).  */
3991
    len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
3992
                       fold_convert_loc (loc, TREE_TYPE (len), arg3));
3993
 
3994
    /* If we don't have POINTER_TYPE, call the function.  */
3995
    if (arg1_align == 0 || arg2_align == 0)
3996
      return NULL_RTX;
3997
 
3998
    /* Make a place to write the result of the instruction.  */
3999
    result = target;
4000
    if (! (result != 0
4001
           && REG_P (result) && GET_MODE (result) == insn_mode
4002
           && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4003
      result = gen_reg_rtx (insn_mode);
4004
 
4005
    /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
4006
    arg1 = builtin_save_expr (arg1);
4007
    arg2 = builtin_save_expr (arg2);
4008
    len = builtin_save_expr (len);
4009
 
4010
    arg1_rtx = get_memory_rtx (arg1, len);
4011
    arg2_rtx = get_memory_rtx (arg2, len);
4012
    arg3_rtx = expand_normal (len);
4013
    insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4014
                          GEN_INT (MIN (arg1_align, arg2_align)));
4015
    if (insn)
4016
      {
4017
        emit_insn (insn);
4018
 
4019
        /* Return the value in the proper mode for this function.  */
4020
        mode = TYPE_MODE (TREE_TYPE (exp));
4021
        if (GET_MODE (result) == mode)
4022
          return result;
4023
        if (target == 0)
4024
          return convert_to_mode (mode, result, 0);
4025
        convert_move (target, result, 0);
4026
        return target;
4027
      }
4028
 
4029
    /* Expand the library call ourselves using a stabilized argument
4030
       list to avoid re-evaluating the function's arguments twice.  */
4031
    fndecl = get_callee_fndecl (exp);
4032
    fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
4033
                                arg1, arg2, len);
4034
    gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4035
    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4036
    return expand_call (fn, target, target == const0_rtx);
4037
  }
4038
#endif
4039
  return NULL_RTX;
4040
}
4041
 
4042
/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4043
   if that's convenient.  */
4044
 
4045
rtx
4046
expand_builtin_saveregs (void)
4047
{
4048
  rtx val, seq;
4049
 
4050
  /* Don't do __builtin_saveregs more than once in a function.
4051
     Save the result of the first call and reuse it.  */
4052
  if (saveregs_value != 0)
4053
    return saveregs_value;
4054
 
4055
  /* When this function is called, it means that registers must be
4056
     saved on entry to this function.  So we migrate the call to the
4057
     first insn of this function.  */
4058
 
4059
  start_sequence ();
4060
 
4061
  /* Do whatever the machine needs done in this case.  */
4062
  val = targetm.calls.expand_builtin_saveregs ();
4063
 
4064
  seq = get_insns ();
4065
  end_sequence ();
4066
 
4067
  saveregs_value = val;
4068
 
4069
  /* Put the insns after the NOTE that starts the function.  If this
4070
     is inside a start_sequence, make the outer-level insn chain current, so
4071
     the code is placed at the start of the function.  */
4072
  push_topmost_sequence ();
4073
  emit_insn_after (seq, entry_of_function ());
4074
  pop_topmost_sequence ();
4075
 
4076
  return val;
4077
}
4078
 
4079
/* Expand a call to __builtin_next_arg.  */
4080
 
4081
static rtx
4082
expand_builtin_next_arg (void)
4083
{
4084
  /* Checking arguments is already done in fold_builtin_next_arg
4085
     that must be called before this function.  */
4086
  return expand_binop (ptr_mode, add_optab,
4087
                       crtl->args.internal_arg_pointer,
4088
                       crtl->args.arg_offset_rtx,
4089
                       NULL_RTX, 0, OPTAB_LIB_WIDEN);
4090
}
4091
 
4092
/* Make it easier for the backends by protecting the valist argument
4093
   from multiple evaluations.  */
4094
 
4095
static tree
4096
stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
4097
{
4098
  tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4099
 
4100
  /* The current way of determining the type of valist is completely
4101
     bogus.  We should have the information on the va builtin instead.  */
4102
  if (!vatype)
4103
    vatype = targetm.fn_abi_va_list (cfun->decl);
4104
 
4105
  if (TREE_CODE (vatype) == ARRAY_TYPE)
4106
    {
4107
      if (TREE_SIDE_EFFECTS (valist))
4108
        valist = save_expr (valist);
4109
 
4110
      /* For this case, the backends will be expecting a pointer to
4111
         vatype, but it's possible we've actually been given an array
4112
         (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4113
         So fix it.  */
4114
      if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4115
        {
4116
          tree p1 = build_pointer_type (TREE_TYPE (vatype));
4117
          valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
4118
        }
4119
    }
4120
  else
4121
    {
4122
      tree pt = build_pointer_type (vatype);
4123
 
4124
      if (! needs_lvalue)
4125
        {
4126
          if (! TREE_SIDE_EFFECTS (valist))
4127
            return valist;
4128
 
4129
          valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
4130
          TREE_SIDE_EFFECTS (valist) = 1;
4131
        }
4132
 
4133
      if (TREE_SIDE_EFFECTS (valist))
4134
        valist = save_expr (valist);
4135
      valist = fold_build2_loc (loc, MEM_REF,
4136
                                vatype, valist, build_int_cst (pt, 0));
4137
    }
4138
 
4139
  return valist;
4140
}
4141
 
4142
/* The "standard" definition of va_list is void*.  */
4143
 
4144
tree
4145
std_build_builtin_va_list (void)
4146
{
4147
  return ptr_type_node;
4148
}
4149
 
4150
/* The "standard" abi va_list is va_list_type_node.  */
4151
 
4152
tree
4153
std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4154
{
4155
  return va_list_type_node;
4156
}
4157
 
4158
/* The "standard" type of va_list is va_list_type_node.  */
4159
 
4160
tree
4161
std_canonical_va_list_type (tree type)
4162
{
4163
  tree wtype, htype;
4164
 
4165
  if (INDIRECT_REF_P (type))
4166
    type = TREE_TYPE (type);
4167
  else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4168
    type = TREE_TYPE (type);
4169
  wtype = va_list_type_node;
4170
  htype = type;
4171
  /* Treat structure va_list types.  */
4172
  if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4173
    htype = TREE_TYPE (htype);
4174
  else if (TREE_CODE (wtype) == ARRAY_TYPE)
4175
    {
4176
      /* If va_list is an array type, the argument may have decayed
4177
         to a pointer type, e.g. by being passed to another function.
4178
         In that case, unwrap both types so that we can compare the
4179
         underlying records.  */
4180
      if (TREE_CODE (htype) == ARRAY_TYPE
4181
          || POINTER_TYPE_P (htype))
4182
        {
4183
          wtype = TREE_TYPE (wtype);
4184
          htype = TREE_TYPE (htype);
4185
        }
4186
    }
4187
  if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4188
    return va_list_type_node;
4189
 
4190
  return NULL_TREE;
4191
}
4192
 
4193
/* The "standard" implementation of va_start: just assign `nextarg' to
4194
   the variable.  */
4195
 
4196
void
4197
std_expand_builtin_va_start (tree valist, rtx nextarg)
4198
{
4199
  rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4200
  convert_move (va_r, nextarg, 0);
4201
}
4202
 
4203
/* Expand EXP, a call to __builtin_va_start.  */
4204
 
4205
static rtx
4206
expand_builtin_va_start (tree exp)
4207
{
4208
  rtx nextarg;
4209
  tree valist;
4210
  location_t loc = EXPR_LOCATION (exp);
4211
 
4212
  if (call_expr_nargs (exp) < 2)
4213
    {
4214
      error_at (loc, "too few arguments to function %<va_start%>");
4215
      return const0_rtx;
4216
    }
4217
 
4218
  if (fold_builtin_next_arg (exp, true))
4219
    return const0_rtx;
4220
 
4221
  nextarg = expand_builtin_next_arg ();
4222
  valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
4223
 
4224
  if (targetm.expand_builtin_va_start)
4225
    targetm.expand_builtin_va_start (valist, nextarg);
4226
  else
4227
    std_expand_builtin_va_start (valist, nextarg);
4228
 
4229
  return const0_rtx;
4230
}
4231
 
4232
/* The "standard" implementation of va_arg: read the value from the
4233
   current (padded) address and increment by the (padded) size.  */
4234
 
4235
tree
4236
std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4237
                          gimple_seq *post_p)
4238
{
4239
  tree addr, t, type_size, rounded_size, valist_tmp;
4240
  unsigned HOST_WIDE_INT align, boundary;
4241
  bool indirect;
4242
 
4243
#ifdef ARGS_GROW_DOWNWARD
4244
  /* All of the alignment and movement below is for args-grow-up machines.
4245
     As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4246
     implement their own specialized gimplify_va_arg_expr routines.  */
4247
  gcc_unreachable ();
4248
#endif
4249
 
4250
  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4251
  if (indirect)
4252
    type = build_pointer_type (type);
4253
 
4254
  align = PARM_BOUNDARY / BITS_PER_UNIT;
4255
  boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
4256
 
4257
  /* When we align parameter on stack for caller, if the parameter
4258
     alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4259
     aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
4260
     here with caller.  */
4261
  if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4262
    boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4263
 
4264
  boundary /= 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 = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4275
                  fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
4276
      gimplify_and_add (t, pre_p);
4277
 
4278
      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4279
                  fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
4280
                               valist_tmp,
4281
                               build_int_cst (TREE_TYPE (valist), -boundary)));
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 dereferencing 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_loc (input_location, GT_EXPR, sizetype,
4310
                       rounded_size, size_int (align));
4311
      t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4312
                       size_binop (MINUS_EXPR, rounded_size, type_size));
4313
      addr = fold_build_pointer_plus (addr, t);
4314
    }
4315
 
4316
  /* Compute new value for AP.  */
4317
  t = fold_build_pointer_plus (valist_tmp, rounded_size);
4318
  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4319
  gimplify_and_add (t, pre_p);
4320
 
4321
  addr = fold_convert (build_pointer_type (type), addr);
4322
 
4323
  if (indirect)
4324
    addr = build_va_arg_indirect_ref (addr);
4325
 
4326
  return build_va_arg_indirect_ref (addr);
4327
}
4328
 
4329
/* Build an indirect-ref expression over the given TREE, which represents a
4330
   piece of a va_arg() expansion.  */
4331
tree
4332
build_va_arg_indirect_ref (tree addr)
4333
{
4334
  addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
4335
 
4336
  if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4337
    mf_mark (addr);
4338
 
4339
  return addr;
4340
}
4341
 
4342
/* Return a dummy expression of type TYPE in order to keep going after an
4343
   error.  */
4344
 
4345
static tree
4346
dummy_object (tree type)
4347
{
4348
  tree t = build_int_cst (build_pointer_type (type), 0);
4349
  return build2 (MEM_REF, type, t, t);
4350
}
4351
 
4352
/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4353
   builtin function, but a very special sort of operator.  */
4354
 
4355
enum gimplify_status
4356
gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4357
{
4358
  tree promoted_type, have_va_type;
4359
  tree valist = TREE_OPERAND (*expr_p, 0);
4360
  tree type = TREE_TYPE (*expr_p);
4361
  tree t;
4362
  location_t loc = EXPR_LOCATION (*expr_p);
4363
 
4364
  /* Verify that valist is of the proper type.  */
4365
  have_va_type = TREE_TYPE (valist);
4366
  if (have_va_type == error_mark_node)
4367
    return GS_ERROR;
4368
  have_va_type = targetm.canonical_va_list_type (have_va_type);
4369
 
4370
  if (have_va_type == NULL_TREE)
4371
    {
4372
      error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
4373
      return GS_ERROR;
4374
    }
4375
 
4376
  /* Generate a diagnostic for requesting data of a type that cannot
4377
     be passed through `...' due to type promotion at the call site.  */
4378
  if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4379
           != type)
4380
    {
4381
      static bool gave_help;
4382
      bool warned;
4383
 
4384
      /* Unfortunately, this is merely undefined, rather than a constraint
4385
         violation, so we cannot make this an error.  If this call is never
4386
         executed, the program is still strictly conforming.  */
4387
      warned = warning_at (loc, 0,
4388
                           "%qT is promoted to %qT when passed through %<...%>",
4389
                           type, promoted_type);
4390
      if (!gave_help && warned)
4391
        {
4392
          gave_help = true;
4393
          inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4394
                  promoted_type, type);
4395
        }
4396
 
4397
      /* We can, however, treat "undefined" any way we please.
4398
         Call abort to encourage the user to fix the program.  */
4399
      if (warned)
4400
        inform (loc, "if this code is reached, the program will abort");
4401
      /* Before the abort, allow the evaluation of the va_list
4402
         expression to exit or longjmp.  */
4403
      gimplify_and_add (valist, pre_p);
4404
      t = build_call_expr_loc (loc,
4405
                               builtin_decl_implicit (BUILT_IN_TRAP), 0);
4406
      gimplify_and_add (t, pre_p);
4407
 
4408
      /* This is dead code, but go ahead and finish so that the
4409
         mode of the result comes out right.  */
4410
      *expr_p = dummy_object (type);
4411
      return GS_ALL_DONE;
4412
    }
4413
  else
4414
    {
4415
      /* Make it easier for the backends by protecting the valist argument
4416
         from multiple evaluations.  */
4417
      if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4418
        {
4419
          /* For this case, the backends will be expecting a pointer to
4420
             TREE_TYPE (abi), but it's possible we've
4421
             actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4422
             So fix it.  */
4423
          if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4424
            {
4425
              tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4426
              valist = fold_convert_loc (loc, p1,
4427
                                         build_fold_addr_expr_loc (loc, valist));
4428
            }
4429
 
4430
          gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4431
        }
4432
      else
4433
        gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4434
 
4435
      if (!targetm.gimplify_va_arg_expr)
4436
        /* FIXME: Once most targets are converted we should merely
4437
           assert this is non-null.  */
4438
        return GS_ALL_DONE;
4439
 
4440
      *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4441
      return GS_OK;
4442
    }
4443
}
4444
 
4445
/* Expand EXP, a call to __builtin_va_end.  */
4446
 
4447
static rtx
4448
expand_builtin_va_end (tree exp)
4449
{
4450
  tree valist = CALL_EXPR_ARG (exp, 0);
4451
 
4452
  /* Evaluate for side effects, if needed.  I hate macros that don't
4453
     do that.  */
4454
  if (TREE_SIDE_EFFECTS (valist))
4455
    expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4456
 
4457
  return const0_rtx;
4458
}
4459
 
4460
/* Expand EXP, a call to __builtin_va_copy.  We do this as a
4461
   builtin rather than just as an assignment in stdarg.h because of the
4462
   nastiness of array-type va_list types.  */
4463
 
4464
static rtx
4465
expand_builtin_va_copy (tree exp)
4466
{
4467
  tree dst, src, t;
4468
  location_t loc = EXPR_LOCATION (exp);
4469
 
4470
  dst = CALL_EXPR_ARG (exp, 0);
4471
  src = CALL_EXPR_ARG (exp, 1);
4472
 
4473
  dst = stabilize_va_list_loc (loc, dst, 1);
4474
  src = stabilize_va_list_loc (loc, src, 0);
4475
 
4476
  gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4477
 
4478
  if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4479
    {
4480
      t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4481
      TREE_SIDE_EFFECTS (t) = 1;
4482
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4483
    }
4484
  else
4485
    {
4486
      rtx dstb, srcb, size;
4487
 
4488
      /* Evaluate to pointers.  */
4489
      dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4490
      srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4491
      size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4492
                  NULL_RTX, VOIDmode, EXPAND_NORMAL);
4493
 
4494
      dstb = convert_memory_address (Pmode, dstb);
4495
      srcb = convert_memory_address (Pmode, srcb);
4496
 
4497
      /* "Dereference" to BLKmode memories.  */
4498
      dstb = gen_rtx_MEM (BLKmode, dstb);
4499
      set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4500
      set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4501
      srcb = gen_rtx_MEM (BLKmode, srcb);
4502
      set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4503
      set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4504
 
4505
      /* Copy.  */
4506
      emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4507
    }
4508
 
4509
  return const0_rtx;
4510
}
4511
 
4512
/* Expand a call to one of the builtin functions __builtin_frame_address or
4513
   __builtin_return_address.  */
4514
 
4515
static rtx
4516
expand_builtin_frame_address (tree fndecl, tree exp)
4517
{
4518
  /* The argument must be a nonnegative integer constant.
4519
     It counts the number of frames to scan up the stack.
4520
     The value is the return address saved in that frame.  */
4521
  if (call_expr_nargs (exp) == 0)
4522
    /* Warning about missing arg was already issued.  */
4523
    return const0_rtx;
4524
  else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4525
    {
4526
      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4527
        error ("invalid argument to %<__builtin_frame_address%>");
4528
      else
4529
        error ("invalid argument to %<__builtin_return_address%>");
4530
      return const0_rtx;
4531
    }
4532
  else
4533
    {
4534
      rtx tem
4535
        = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4536
                                      tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
4537
 
4538
      /* Some ports cannot access arbitrary stack frames.  */
4539
      if (tem == NULL)
4540
        {
4541
          if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4542
            warning (0, "unsupported argument to %<__builtin_frame_address%>");
4543
          else
4544
            warning (0, "unsupported argument to %<__builtin_return_address%>");
4545
          return const0_rtx;
4546
        }
4547
 
4548
      /* For __builtin_frame_address, return what we've got.  */
4549
      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4550
        return tem;
4551
 
4552
      if (!REG_P (tem)
4553
          && ! CONSTANT_P (tem))
4554
        tem = copy_to_mode_reg (Pmode, tem);
4555
      return tem;
4556
    }
4557
}
4558
 
4559
/* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if we
4560
   failed and the caller should emit a normal call.  CANNOT_ACCUMULATE
4561
   is the same as for allocate_dynamic_stack_space.  */
4562
 
4563
static rtx
4564
expand_builtin_alloca (tree exp, bool cannot_accumulate)
4565
{
4566
  rtx op0;
4567
  rtx result;
4568
  bool valid_arglist;
4569
  unsigned int align;
4570
  bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp))
4571
                            == BUILT_IN_ALLOCA_WITH_ALIGN);
4572
 
4573
  /* Emit normal call if we use mudflap.  */
4574
  if (flag_mudflap)
4575
    return NULL_RTX;
4576
 
4577
  valid_arglist
4578
    = (alloca_with_align
4579
       ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)
4580
       : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE));
4581
 
4582
  if (!valid_arglist)
4583
    return NULL_RTX;
4584
 
4585
  /* Compute the argument.  */
4586
  op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
4587
 
4588
  /* Compute the alignment.  */
4589
  align = (alloca_with_align
4590
           ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1))
4591
           : BIGGEST_ALIGNMENT);
4592
 
4593
  /* Allocate the desired space.  */
4594
  result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate);
4595
  result = convert_memory_address (ptr_mode, result);
4596
 
4597
  return result;
4598
}
4599
 
4600
/* Expand a call to a bswap builtin with argument ARG0.  MODE
4601
   is the mode to expand with.  */
4602
 
4603
static rtx
4604
expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
4605
{
4606
  enum machine_mode mode;
4607
  tree arg;
4608
  rtx op0;
4609
 
4610
  if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4611
    return NULL_RTX;
4612
 
4613
  arg = CALL_EXPR_ARG (exp, 0);
4614
  mode = TYPE_MODE (TREE_TYPE (arg));
4615
  op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4616
 
4617
  target = expand_unop (mode, bswap_optab, op0, target, 1);
4618
 
4619
  gcc_assert (target);
4620
 
4621
  return convert_to_mode (mode, target, 0);
4622
}
4623
 
4624
/* Expand a call to a unary builtin in EXP.
4625
   Return NULL_RTX if a normal call should be emitted rather than expanding the
4626
   function in-line.  If convenient, the result should be placed in TARGET.
4627
   SUBTARGET may be used as the target for computing one of EXP's operands.  */
4628
 
4629
static rtx
4630
expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4631
                     rtx subtarget, optab op_optab)
4632
{
4633
  rtx op0;
4634
 
4635
  if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4636
    return NULL_RTX;
4637
 
4638
  /* Compute the argument.  */
4639
  op0 = expand_expr (CALL_EXPR_ARG (exp, 0),
4640
                     (subtarget
4641
                      && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))
4642
                          == GET_MODE (subtarget))) ? subtarget : NULL_RTX,
4643
                     VOIDmode, EXPAND_NORMAL);
4644
  /* Compute op, into TARGET if possible.
4645
     Set TARGET to wherever the result comes back.  */
4646
  target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
4647
                        op_optab, op0, target, op_optab != clrsb_optab);
4648
  gcc_assert (target);
4649
 
4650
  return convert_to_mode (target_mode, target, 0);
4651
}
4652
 
4653
/* Expand a call to __builtin_expect.  We just return our argument
4654
   as the builtin_expect semantic should've been already executed by
4655
   tree branch prediction pass. */
4656
 
4657
static rtx
4658
expand_builtin_expect (tree exp, rtx target)
4659
{
4660
  tree arg;
4661
 
4662
  if (call_expr_nargs (exp) < 2)
4663
    return const0_rtx;
4664
  arg = CALL_EXPR_ARG (exp, 0);
4665
 
4666
  target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4667
  /* When guessing was done, the hints should be already stripped away.  */
4668
  gcc_assert (!flag_guess_branch_prob
4669
              || optimize == 0 || seen_error ());
4670
  return target;
4671
}
4672
 
4673
/* Expand a call to __builtin_assume_aligned.  We just return our first
4674
   argument as the builtin_assume_aligned semantic should've been already
4675
   executed by CCP.  */
4676
 
4677
static rtx
4678
expand_builtin_assume_aligned (tree exp, rtx target)
4679
{
4680
  if (call_expr_nargs (exp) < 2)
4681
    return const0_rtx;
4682
  target = expand_expr (CALL_EXPR_ARG (exp, 0), target, VOIDmode,
4683
                        EXPAND_NORMAL);
4684
  gcc_assert (!TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 1))
4685
              && (call_expr_nargs (exp) < 3
4686
                  || !TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 2))));
4687
  return target;
4688
}
4689
 
4690
void
4691
expand_builtin_trap (void)
4692
{
4693
#ifdef HAVE_trap
4694
  if (HAVE_trap)
4695
    emit_insn (gen_trap ());
4696
  else
4697
#endif
4698
    emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4699
  emit_barrier ();
4700
}
4701
 
4702
/* Expand a call to __builtin_unreachable.  We do nothing except emit
4703
   a barrier saying that control flow will not pass here.
4704
 
4705
   It is the responsibility of the program being compiled to ensure
4706
   that control flow does never reach __builtin_unreachable.  */
4707
static void
4708
expand_builtin_unreachable (void)
4709
{
4710
  emit_barrier ();
4711
}
4712
 
4713
/* Expand EXP, a call to fabs, fabsf or fabsl.
4714
   Return NULL_RTX if a normal call should be emitted rather than expanding
4715
   the function inline.  If convenient, the result should be placed
4716
   in TARGET.  SUBTARGET may be used as the target for computing
4717
   the operand.  */
4718
 
4719
static rtx
4720
expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
4721
{
4722
  enum machine_mode mode;
4723
  tree arg;
4724
  rtx op0;
4725
 
4726
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4727
    return NULL_RTX;
4728
 
4729
  arg = CALL_EXPR_ARG (exp, 0);
4730
  CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
4731
  mode = TYPE_MODE (TREE_TYPE (arg));
4732
  op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4733
  return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4734
}
4735
 
4736
/* Expand EXP, a call to copysign, copysignf, or copysignl.
4737
   Return NULL is a normal call should be emitted rather than expanding the
4738
   function inline.  If convenient, the result should be placed in TARGET.
4739
   SUBTARGET may be used as the target for computing the operand.  */
4740
 
4741
static rtx
4742
expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
4743
{
4744
  rtx op0, op1;
4745
  tree arg;
4746
 
4747
  if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4748
    return NULL_RTX;
4749
 
4750
  arg = CALL_EXPR_ARG (exp, 0);
4751
  op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4752
 
4753
  arg = CALL_EXPR_ARG (exp, 1);
4754
  op1 = expand_normal (arg);
4755
 
4756
  return expand_copysign (op0, op1, target);
4757
}
4758
 
4759
/* Create a new constant string literal and return a char* pointer to it.
4760
   The STRING_CST value is the LEN characters at STR.  */
4761
tree
4762
build_string_literal (int len, const char *str)
4763
{
4764
  tree t, elem, index, type;
4765
 
4766
  t = build_string (len, str);
4767
  elem = build_type_variant (char_type_node, 1, 0);
4768
  index = build_index_type (size_int (len - 1));
4769
  type = build_array_type (elem, index);
4770
  TREE_TYPE (t) = type;
4771
  TREE_CONSTANT (t) = 1;
4772
  TREE_READONLY (t) = 1;
4773
  TREE_STATIC (t) = 1;
4774
 
4775
  type = build_pointer_type (elem);
4776
  t = build1 (ADDR_EXPR, type,
4777
              build4 (ARRAY_REF, elem,
4778
                      t, integer_zero_node, NULL_TREE, NULL_TREE));
4779
  return t;
4780
}
4781
 
4782
/* Expand a call to __builtin___clear_cache.  */
4783
 
4784
static rtx
4785
expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
4786
{
4787
#ifndef HAVE_clear_cache
4788
#ifdef CLEAR_INSN_CACHE
4789
  /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4790
     does something.  Just do the default expansion to a call to
4791
     __clear_cache().  */
4792
  return NULL_RTX;
4793
#else
4794
  /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4795
     does nothing.  There is no need to call it.  Do nothing.  */
4796
  return const0_rtx;
4797
#endif /* CLEAR_INSN_CACHE */
4798
#else
4799
  /* We have a "clear_cache" insn, and it will handle everything.  */
4800
  tree begin, end;
4801
  rtx begin_rtx, end_rtx;
4802
 
4803
  /* We must not expand to a library call.  If we did, any
4804
     fallback library function in libgcc that might contain a call to
4805
     __builtin___clear_cache() would recurse infinitely.  */
4806
  if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4807
    {
4808
      error ("both arguments to %<__builtin___clear_cache%> must be pointers");
4809
      return const0_rtx;
4810
    }
4811
 
4812
  if (HAVE_clear_cache)
4813
    {
4814
      struct expand_operand ops[2];
4815
 
4816
      begin = CALL_EXPR_ARG (exp, 0);
4817
      begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
4818
 
4819
      end = CALL_EXPR_ARG (exp, 1);
4820
      end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
4821
 
4822
      create_address_operand (&ops[0], begin_rtx);
4823
      create_address_operand (&ops[1], end_rtx);
4824
      if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops))
4825
        return const0_rtx;
4826
    }
4827
  return const0_rtx;
4828
#endif /* HAVE_clear_cache */
4829
}
4830
 
4831
/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
4832
 
4833
static rtx
4834
round_trampoline_addr (rtx tramp)
4835
{
4836
  rtx temp, addend, mask;
4837
 
4838
  /* If we don't need too much alignment, we'll have been guaranteed
4839
     proper alignment by get_trampoline_type.  */
4840
  if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4841
    return tramp;
4842
 
4843
  /* Round address up to desired boundary.  */
4844
  temp = gen_reg_rtx (Pmode);
4845
  addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4846
  mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4847
 
4848
  temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
4849
                               temp, 0, OPTAB_LIB_WIDEN);
4850
  tramp = expand_simple_binop (Pmode, AND, temp, mask,
4851
                               temp, 0, OPTAB_LIB_WIDEN);
4852
 
4853
  return tramp;
4854
}
4855
 
4856
static rtx
4857
expand_builtin_init_trampoline (tree exp, bool onstack)
4858
{
4859
  tree t_tramp, t_func, t_chain;
4860
  rtx m_tramp, r_tramp, r_chain, tmp;
4861
 
4862
  if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4863
                         POINTER_TYPE, VOID_TYPE))
4864
    return NULL_RTX;
4865
 
4866
  t_tramp = CALL_EXPR_ARG (exp, 0);
4867
  t_func = CALL_EXPR_ARG (exp, 1);
4868
  t_chain = CALL_EXPR_ARG (exp, 2);
4869
 
4870
  r_tramp = expand_normal (t_tramp);
4871
  m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
4872
  MEM_NOTRAP_P (m_tramp) = 1;
4873
 
4874
  /* If ONSTACK, the TRAMP argument should be the address of a field
4875
     within the local function's FRAME decl.  Either way, let's see if
4876
     we can fill in the MEM_ATTRs for this memory.  */
4877
  if (TREE_CODE (t_tramp) == ADDR_EXPR)
4878
    set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
4879
                                     true, 0);
4880
 
4881
  /* Creator of a heap trampoline is responsible for making sure the
4882
     address is aligned to at least STACK_BOUNDARY.  Normally malloc
4883
     will ensure this anyhow.  */
4884
  tmp = round_trampoline_addr (r_tramp);
4885
  if (tmp != r_tramp)
4886
    {
4887
      m_tramp = change_address (m_tramp, BLKmode, tmp);
4888
      set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
4889
      set_mem_size (m_tramp, TRAMPOLINE_SIZE);
4890
    }
4891
 
4892
  /* The FUNC argument should be the address of the nested function.
4893
     Extract the actual function decl to pass to the hook.  */
4894
  gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
4895
  t_func = TREE_OPERAND (t_func, 0);
4896
  gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
4897
 
4898
  r_chain = expand_normal (t_chain);
4899
 
4900
  /* Generate insns to initialize the trampoline.  */
4901
  targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4902
 
4903
  if (onstack)
4904
    {
4905
      trampolines_created = 1;
4906
 
4907
      warning_at (DECL_SOURCE_LOCATION (t_func), OPT_Wtrampolines,
4908
                  "trampoline generated for nested function %qD", t_func);
4909
    }
4910
 
4911
  return const0_rtx;
4912
}
4913
 
4914
static rtx
4915
expand_builtin_adjust_trampoline (tree exp)
4916
{
4917
  rtx tramp;
4918
 
4919
  if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4920
    return NULL_RTX;
4921
 
4922
  tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4923
  tramp = round_trampoline_addr (tramp);
4924
  if (targetm.calls.trampoline_adjust_address)
4925
    tramp = targetm.calls.trampoline_adjust_address (tramp);
4926
 
4927
  return tramp;
4928
}
4929
 
4930
/* Expand the call EXP to the built-in signbit, signbitf or signbitl
4931
   function.  The function first checks whether the back end provides
4932
   an insn to implement signbit for the respective mode.  If not, it
4933
   checks whether the floating point format of the value is such that
4934
   the sign bit can be extracted.  If that is not the case, the
4935
   function returns NULL_RTX to indicate that a normal call should be
4936
   emitted rather than expanding the function in-line.  EXP is the
4937
   expression that is a call to the builtin function; if convenient,
4938
   the result should be placed in TARGET.  */
4939
static rtx
4940
expand_builtin_signbit (tree exp, rtx target)
4941
{
4942
  const struct real_format *fmt;
4943
  enum machine_mode fmode, imode, rmode;
4944
  tree arg;
4945
  int word, bitpos;
4946
  enum insn_code icode;
4947
  rtx temp;
4948
  location_t loc = EXPR_LOCATION (exp);
4949
 
4950
  if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4951
    return NULL_RTX;
4952
 
4953
  arg = CALL_EXPR_ARG (exp, 0);
4954
  fmode = TYPE_MODE (TREE_TYPE (arg));
4955
  rmode = TYPE_MODE (TREE_TYPE (exp));
4956
  fmt = REAL_MODE_FORMAT (fmode);
4957
 
4958
  arg = builtin_save_expr (arg);
4959
 
4960
  /* Expand the argument yielding a RTX expression. */
4961
  temp = expand_normal (arg);
4962
 
4963
  /* Check if the back end provides an insn that handles signbit for the
4964
     argument's mode. */
4965
  icode = optab_handler (signbit_optab, fmode);
4966
  if (icode != CODE_FOR_nothing)
4967
    {
4968
      rtx last = get_last_insn ();
4969
      target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
4970
      if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN))
4971
        return target;
4972
      delete_insns_since (last);
4973
    }
4974
 
4975
  /* For floating point formats without a sign bit, implement signbit
4976
     as "ARG < 0.0".  */
4977
  bitpos = fmt->signbit_ro;
4978
  if (bitpos < 0)
4979
  {
4980
    /* But we can't do this if the format supports signed zero.  */
4981
    if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4982
      return NULL_RTX;
4983
 
4984
    arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
4985
                       build_real (TREE_TYPE (arg), dconst0));
4986
    return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4987
  }
4988
 
4989
  if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
4990
    {
4991
      imode = int_mode_for_mode (fmode);
4992
      if (imode == BLKmode)
4993
        return NULL_RTX;
4994
      temp = gen_lowpart (imode, temp);
4995
    }
4996
  else
4997
    {
4998
      imode = word_mode;
4999
      /* Handle targets with different FP word orders.  */
5000
      if (FLOAT_WORDS_BIG_ENDIAN)
5001
        word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5002
      else
5003
        word = bitpos / BITS_PER_WORD;
5004
      temp = operand_subword_force (temp, word, fmode);
5005
      bitpos = bitpos % BITS_PER_WORD;
5006
    }
5007
 
5008
  /* Force the intermediate word_mode (or narrower) result into a
5009
     register.  This avoids attempting to create paradoxical SUBREGs
5010
     of floating point modes below.  */
5011
  temp = force_reg (imode, temp);
5012
 
5013
  /* If the bitpos is within the "result mode" lowpart, the operation
5014
     can be implement with a single bitwise AND.  Otherwise, we need
5015
     a right shift and an AND.  */
5016
 
5017
  if (bitpos < GET_MODE_BITSIZE (rmode))
5018
    {
5019
      double_int mask = double_int_setbit (double_int_zero, bitpos);
5020
 
5021
      if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5022
        temp = gen_lowpart (rmode, temp);
5023
      temp = expand_binop (rmode, and_optab, temp,
5024
                           immed_double_int_const (mask, rmode),
5025
                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
5026
    }
5027
  else
5028
    {
5029
      /* Perform a logical right shift to place the signbit in the least
5030
         significant bit, then truncate the result to the desired mode
5031
         and mask just this bit.  */
5032
      temp = expand_shift (RSHIFT_EXPR, imode, temp, bitpos, NULL_RTX, 1);
5033
      temp = gen_lowpart (rmode, temp);
5034
      temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5035
                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
5036
    }
5037
 
5038
  return temp;
5039
}
5040
 
5041
/* Expand fork or exec calls.  TARGET is the desired target of the
5042
   call.  EXP is the call. FN is the
5043
   identificator of the actual function.  IGNORE is nonzero if the
5044
   value is to be ignored.  */
5045
 
5046
static rtx
5047
expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5048
{
5049
  tree id, decl;
5050
  tree call;
5051
 
5052
  /* If we are not profiling, just call the function.  */
5053
  if (!profile_arc_flag)
5054
    return NULL_RTX;
5055
 
5056
  /* Otherwise call the wrapper.  This should be equivalent for the rest of
5057
     compiler, so the code does not diverge, and the wrapper may run the
5058
     code necessary for keeping the profiling sane.  */
5059
 
5060
  switch (DECL_FUNCTION_CODE (fn))
5061
    {
5062
    case BUILT_IN_FORK:
5063
      id = get_identifier ("__gcov_fork");
5064
      break;
5065
 
5066
    case BUILT_IN_EXECL:
5067
      id = get_identifier ("__gcov_execl");
5068
      break;
5069
 
5070
    case BUILT_IN_EXECV:
5071
      id = get_identifier ("__gcov_execv");
5072
      break;
5073
 
5074
    case BUILT_IN_EXECLP:
5075
      id = get_identifier ("__gcov_execlp");
5076
      break;
5077
 
5078
    case BUILT_IN_EXECLE:
5079
      id = get_identifier ("__gcov_execle");
5080
      break;
5081
 
5082
    case BUILT_IN_EXECVP:
5083
      id = get_identifier ("__gcov_execvp");
5084
      break;
5085
 
5086
    case BUILT_IN_EXECVE:
5087
      id = get_identifier ("__gcov_execve");
5088
      break;
5089
 
5090
    default:
5091
      gcc_unreachable ();
5092
    }
5093
 
5094
  decl = build_decl (DECL_SOURCE_LOCATION (fn),
5095
                     FUNCTION_DECL, id, TREE_TYPE (fn));
5096
  DECL_EXTERNAL (decl) = 1;
5097
  TREE_PUBLIC (decl) = 1;
5098
  DECL_ARTIFICIAL (decl) = 1;
5099
  TREE_NOTHROW (decl) = 1;
5100
  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5101
  DECL_VISIBILITY_SPECIFIED (decl) = 1;
5102
  call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
5103
  return expand_call (call, target, ignore);
5104
 }
5105
 
5106
 
5107
 
5108
/* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5109
   the pointer in these functions is void*, the tree optimizers may remove
5110
   casts.  The mode computed in expand_builtin isn't reliable either, due
5111
   to __sync_bool_compare_and_swap.
5112
 
5113
   FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5114
   group of builtins.  This gives us log2 of the mode size.  */
5115
 
5116
static inline enum machine_mode
5117
get_builtin_sync_mode (int fcode_diff)
5118
{
5119
  /* The size is not negotiable, so ask not to get BLKmode in return
5120
     if the target indicates that a smaller size would be better.  */
5121
  return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5122
}
5123
 
5124
/* Expand the memory expression LOC and return the appropriate memory operand
5125
   for the builtin_sync operations.  */
5126
 
5127
static rtx
5128
get_builtin_sync_mem (tree loc, enum machine_mode mode)
5129
{
5130
  rtx addr, mem;
5131
 
5132
  addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5133
  addr = convert_memory_address (Pmode, addr);
5134
 
5135
  /* Note that we explicitly do not want any alias information for this
5136
     memory, so that we kill all other live memories.  Otherwise we don't
5137
     satisfy the full barrier semantics of the intrinsic.  */
5138
  mem = validize_mem (gen_rtx_MEM (mode, addr));
5139
 
5140
  /* The alignment needs to be at least according to that of the mode.  */
5141
  set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
5142
                           get_pointer_alignment (loc)));
5143
  set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5144
  MEM_VOLATILE_P (mem) = 1;
5145
 
5146
  return mem;
5147
}
5148
 
5149
/* Make sure an argument is in the right mode.
5150
   EXP is the tree argument.
5151
   MODE is the mode it should be in.  */
5152
 
5153
static rtx
5154
expand_expr_force_mode (tree exp, enum machine_mode mode)
5155
{
5156
  rtx val;
5157
  enum machine_mode old_mode;
5158
 
5159
  val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
5160
  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5161
     of CONST_INTs, where we know the old_mode only from the call argument.  */
5162
 
5163
  old_mode = GET_MODE (val);
5164
  if (old_mode == VOIDmode)
5165
    old_mode = TYPE_MODE (TREE_TYPE (exp));
5166
  val = convert_modes (mode, old_mode, val, 1);
5167
  return val;
5168
}
5169
 
5170
 
5171
/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5172
   EXP is the CALL_EXPR.  CODE is the rtx code
5173
   that corresponds to the arithmetic or logical operation from the name;
5174
   an exception here is that NOT actually means NAND.  TARGET is an optional
5175
   place for us to store the results; AFTER is true if this is the
5176
   fetch_and_xxx form.  */
5177
 
5178
static rtx
5179
expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5180
                               enum rtx_code code, bool after,
5181
                               rtx target)
5182
{
5183
  rtx val, mem;
5184
  location_t loc = EXPR_LOCATION (exp);
5185
 
5186
  if (code == NOT && warn_sync_nand)
5187
    {
5188
      tree fndecl = get_callee_fndecl (exp);
5189
      enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5190
 
5191
      static bool warned_f_a_n, warned_n_a_f;
5192
 
5193
      switch (fcode)
5194
        {
5195
        case BUILT_IN_SYNC_FETCH_AND_NAND_1:
5196
        case BUILT_IN_SYNC_FETCH_AND_NAND_2:
5197
        case BUILT_IN_SYNC_FETCH_AND_NAND_4:
5198
        case BUILT_IN_SYNC_FETCH_AND_NAND_8:
5199
        case BUILT_IN_SYNC_FETCH_AND_NAND_16:
5200
          if (warned_f_a_n)
5201
            break;
5202
 
5203
          fndecl = builtin_decl_implicit (BUILT_IN_SYNC_FETCH_AND_NAND_N);
5204
          inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5205
          warned_f_a_n = true;
5206
          break;
5207
 
5208
        case BUILT_IN_SYNC_NAND_AND_FETCH_1:
5209
        case BUILT_IN_SYNC_NAND_AND_FETCH_2:
5210
        case BUILT_IN_SYNC_NAND_AND_FETCH_4:
5211
        case BUILT_IN_SYNC_NAND_AND_FETCH_8:
5212
        case BUILT_IN_SYNC_NAND_AND_FETCH_16:
5213
          if (warned_n_a_f)
5214
            break;
5215
 
5216
         fndecl = builtin_decl_implicit (BUILT_IN_SYNC_NAND_AND_FETCH_N);
5217
          inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5218
          warned_n_a_f = true;
5219
          break;
5220
 
5221
        default:
5222
          gcc_unreachable ();
5223
        }
5224
    }
5225
 
5226
  /* Expand the operands.  */
5227
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5228
  val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5229
 
5230
  return expand_atomic_fetch_op (target, mem, val, code, MEMMODEL_SEQ_CST,
5231
                                 after);
5232
}
5233
 
5234
/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5235
   intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
5236
   true if this is the boolean form.  TARGET is a place for us to store the
5237
   results; this is NOT optional if IS_BOOL is true.  */
5238
 
5239
static rtx
5240
expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5241
                                 bool is_bool, rtx target)
5242
{
5243
  rtx old_val, new_val, mem;
5244
  rtx *pbool, *poval;
5245
 
5246
  /* Expand the operands.  */
5247
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5248
  old_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5249
  new_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5250
 
5251
  pbool = poval = NULL;
5252
  if (target != const0_rtx)
5253
    {
5254
      if (is_bool)
5255
        pbool = &target;
5256
      else
5257
        poval = &target;
5258
    }
5259
  if (!expand_atomic_compare_and_swap (pbool, poval, mem, old_val, new_val,
5260
                                       false, MEMMODEL_SEQ_CST,
5261
                                       MEMMODEL_SEQ_CST))
5262
    return NULL_RTX;
5263
 
5264
  return target;
5265
}
5266
 
5267
/* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5268
   general form is actually an atomic exchange, and some targets only
5269
   support a reduced form with the second argument being a constant 1.
5270
   EXP is the CALL_EXPR; TARGET is an optional place for us to store
5271
   the results.  */
5272
 
5273
static rtx
5274
expand_builtin_sync_lock_test_and_set (enum machine_mode mode, tree exp,
5275
                                       rtx target)
5276
{
5277
  rtx val, mem;
5278
 
5279
  /* Expand the operands.  */
5280
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5281
  val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5282
 
5283
  return expand_sync_lock_test_and_set (target, mem, val);
5284
}
5285
 
5286
/* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
5287
 
5288
static void
5289
expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
5290
{
5291
  rtx mem;
5292
 
5293
  /* Expand the operands.  */
5294
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5295
 
5296
  expand_atomic_store (mem, const0_rtx, MEMMODEL_RELEASE, true);
5297
}
5298
 
5299
/* Given an integer representing an ``enum memmodel'', verify its
5300
   correctness and return the memory model enum.  */
5301
 
5302
static enum memmodel
5303
get_memmodel (tree exp)
5304
{
5305
  rtx op;
5306
 
5307
  /* If the parameter is not a constant, it's a run time value so we'll just
5308
     convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking.  */
5309
  if (TREE_CODE (exp) != INTEGER_CST)
5310
    return MEMMODEL_SEQ_CST;
5311
 
5312
  op = expand_normal (exp);
5313
  if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
5314
    {
5315
      warning (OPT_Winvalid_memory_model,
5316
               "invalid memory model argument to builtin");
5317
      return MEMMODEL_SEQ_CST;
5318
    }
5319
  return (enum memmodel) INTVAL (op);
5320
}
5321
 
5322
/* Expand the __atomic_exchange intrinsic:
5323
        TYPE __atomic_exchange (TYPE *object, TYPE desired, enum memmodel)
5324
   EXP is the CALL_EXPR.
5325
   TARGET is an optional place for us to store the results.  */
5326
 
5327
static rtx
5328
expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target)
5329
{
5330
  rtx val, mem;
5331
  enum memmodel model;
5332
 
5333
  model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5334
  if (model == MEMMODEL_CONSUME)
5335
    {
5336
      error ("invalid memory model for %<__atomic_exchange%>");
5337
      return NULL_RTX;
5338
    }
5339
 
5340
  if (!flag_inline_atomics)
5341
    return NULL_RTX;
5342
 
5343
  /* Expand the operands.  */
5344
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5345
  val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5346
 
5347
  return expand_atomic_exchange (target, mem, val, model);
5348
}
5349
 
5350
/* Expand the __atomic_compare_exchange intrinsic:
5351
        bool __atomic_compare_exchange (TYPE *object, TYPE *expect,
5352
                                        TYPE desired, BOOL weak,
5353
                                        enum memmodel success,
5354
                                        enum memmodel failure)
5355
   EXP is the CALL_EXPR.
5356
   TARGET is an optional place for us to store the results.  */
5357
 
5358
static rtx
5359
expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
5360
                                        rtx target)
5361
{
5362
  rtx expect, desired, mem, oldval;
5363
  enum memmodel success, failure;
5364
  tree weak;
5365
  bool is_weak;
5366
 
5367
  success = get_memmodel (CALL_EXPR_ARG (exp, 4));
5368
  failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
5369
 
5370
  if (failure == MEMMODEL_RELEASE || failure == MEMMODEL_ACQ_REL)
5371
    {
5372
      error ("invalid failure memory model for %<__atomic_compare_exchange%>");
5373
      return NULL_RTX;
5374
    }
5375
 
5376
  if (failure > success)
5377
    {
5378
      error ("failure memory model cannot be stronger than success "
5379
             "memory model for %<__atomic_compare_exchange%>");
5380
      return NULL_RTX;
5381
    }
5382
 
5383
  if (!flag_inline_atomics)
5384
    return NULL_RTX;
5385
 
5386
  /* Expand the operands.  */
5387
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5388
 
5389
  expect = expand_normal (CALL_EXPR_ARG (exp, 1));
5390
  expect = convert_memory_address (Pmode, expect);
5391
  desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5392
 
5393
  weak = CALL_EXPR_ARG (exp, 3);
5394
  is_weak = false;
5395
  if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
5396
    is_weak = true;
5397
 
5398
  oldval = copy_to_reg (gen_rtx_MEM (mode, expect));
5399
 
5400
  if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
5401
                                       &oldval, mem, oldval, desired,
5402
                                       is_weak, success, failure))
5403
    return NULL_RTX;
5404
 
5405
  emit_move_insn (gen_rtx_MEM (mode, expect), oldval);
5406
  return target;
5407
}
5408
 
5409
/* Expand the __atomic_load intrinsic:
5410
        TYPE __atomic_load (TYPE *object, enum memmodel)
5411
   EXP is the CALL_EXPR.
5412
   TARGET is an optional place for us to store the results.  */
5413
 
5414
static rtx
5415
expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target)
5416
{
5417
  rtx mem;
5418
  enum memmodel model;
5419
 
5420
  model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5421
  if (model == MEMMODEL_RELEASE
5422
      || model == MEMMODEL_ACQ_REL)
5423
    {
5424
      error ("invalid memory model for %<__atomic_load%>");
5425
      return NULL_RTX;
5426
    }
5427
 
5428
  if (!flag_inline_atomics)
5429
    return NULL_RTX;
5430
 
5431
  /* Expand the operand.  */
5432
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5433
 
5434
  return expand_atomic_load (target, mem, model);
5435
}
5436
 
5437
 
5438
/* Expand the __atomic_store intrinsic:
5439
        void __atomic_store (TYPE *object, TYPE desired, enum memmodel)
5440
   EXP is the CALL_EXPR.
5441
   TARGET is an optional place for us to store the results.  */
5442
 
5443
static rtx
5444
expand_builtin_atomic_store (enum machine_mode mode, tree exp)
5445
{
5446
  rtx mem, val;
5447
  enum memmodel model;
5448
 
5449
  model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5450
  if (model != MEMMODEL_RELAXED
5451
      && model != MEMMODEL_SEQ_CST
5452
      && model != MEMMODEL_RELEASE)
5453
    {
5454
      error ("invalid memory model for %<__atomic_store%>");
5455
      return NULL_RTX;
5456
    }
5457
 
5458
  if (!flag_inline_atomics)
5459
    return NULL_RTX;
5460
 
5461
  /* Expand the operands.  */
5462
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5463
  val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5464
 
5465
  return expand_atomic_store (mem, val, model, false);
5466
}
5467
 
5468
/* Expand the __atomic_fetch_XXX intrinsic:
5469
        TYPE __atomic_fetch_XXX (TYPE *object, TYPE val, enum memmodel)
5470
   EXP is the CALL_EXPR.
5471
   TARGET is an optional place for us to store the results.
5472
   CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR.
5473
   FETCH_AFTER is true if returning the result of the operation.
5474
   FETCH_AFTER is false if returning the value before the operation.
5475
   IGNORE is true if the result is not used.
5476
   EXT_CALL is the correct builtin for an external call if this cannot be
5477
   resolved to an instruction sequence.  */
5478
 
5479
static rtx
5480
expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
5481
                                enum rtx_code code, bool fetch_after,
5482
                                bool ignore, enum built_in_function ext_call)
5483
{
5484
  rtx val, mem, ret;
5485
  enum memmodel model;
5486
  tree fndecl;
5487
  tree addr;
5488
 
5489
  model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5490
 
5491
  /* Expand the operands.  */
5492
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5493
  val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5494
 
5495
  /* Only try generating instructions if inlining is turned on.  */
5496
  if (flag_inline_atomics)
5497
    {
5498
      ret = expand_atomic_fetch_op (target, mem, val, code, model, fetch_after);
5499
      if (ret)
5500
        return ret;
5501
    }
5502
 
5503
  /* Return if a different routine isn't needed for the library call.  */
5504
  if (ext_call == BUILT_IN_NONE)
5505
    return NULL_RTX;
5506
 
5507
  /* Change the call to the specified function.  */
5508
  fndecl = get_callee_fndecl (exp);
5509
  addr = CALL_EXPR_FN (exp);
5510
  STRIP_NOPS (addr);
5511
 
5512
  gcc_assert (TREE_OPERAND (addr, 0) == fndecl);
5513
  TREE_OPERAND (addr, 0) = builtin_decl_explicit(ext_call);
5514
 
5515
  /* Expand the call here so we can emit trailing code.  */
5516
  ret = expand_call (exp, target, ignore);
5517
 
5518
  /* Replace the original function just in case it matters.  */
5519
  TREE_OPERAND (addr, 0) = fndecl;
5520
 
5521
  /* Then issue the arithmetic correction to return the right result.  */
5522
  if (!ignore)
5523
    {
5524
      if (code == NOT)
5525
        {
5526
          ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
5527
                                     OPTAB_LIB_WIDEN);
5528
          ret = expand_simple_unop (mode, NOT, ret, target, true);
5529
        }
5530
      else
5531
        ret = expand_simple_binop (mode, code, ret, val, target, true,
5532
                                   OPTAB_LIB_WIDEN);
5533
    }
5534
  return ret;
5535
}
5536
 
5537
 
5538
#ifndef HAVE_atomic_clear
5539
# define HAVE_atomic_clear 0
5540
# define gen_atomic_clear(x,y) (gcc_unreachable (), NULL_RTX)
5541
#endif
5542
 
5543
/* Expand an atomic clear operation.
5544
        void _atomic_clear (BOOL *obj, enum memmodel)
5545
   EXP is the call expression.  */
5546
 
5547
static rtx
5548
expand_builtin_atomic_clear (tree exp)
5549
{
5550
  enum machine_mode mode;
5551
  rtx mem, ret;
5552
  enum memmodel model;
5553
 
5554
  mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5555
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5556
  model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5557
 
5558
  if (model == MEMMODEL_ACQUIRE || model == MEMMODEL_ACQ_REL)
5559
    {
5560
      error ("invalid memory model for %<__atomic_store%>");
5561
      return const0_rtx;
5562
    }
5563
 
5564
  if (HAVE_atomic_clear)
5565
    {
5566
      emit_insn (gen_atomic_clear (mem, model));
5567
      return const0_rtx;
5568
    }
5569
 
5570
  /* Try issuing an __atomic_store, and allow fallback to __sync_lock_release.
5571
     Failing that, a store is issued by __atomic_store.  The only way this can
5572
     fail is if the bool type is larger than a word size.  Unlikely, but
5573
     handle it anyway for completeness.  Assume a single threaded model since
5574
     there is no atomic support in this case, and no barriers are required.  */
5575
  ret = expand_atomic_store (mem, const0_rtx, model, true);
5576
  if (!ret)
5577
    emit_move_insn (mem, const0_rtx);
5578
  return const0_rtx;
5579
}
5580
 
5581
/* Expand an atomic test_and_set operation.
5582
        bool _atomic_test_and_set (BOOL *obj, enum memmodel)
5583
   EXP is the call expression.  */
5584
 
5585
static rtx
5586
expand_builtin_atomic_test_and_set (tree exp, rtx target)
5587
{
5588
  rtx mem;
5589
  enum memmodel model;
5590
  enum machine_mode mode;
5591
 
5592
  mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5593
  mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5594
  model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5595
 
5596
  return expand_atomic_test_and_set (target, mem, model);
5597
}
5598
 
5599
 
5600
/* Return true if (optional) argument ARG1 of size ARG0 is always lock free on
5601
   this architecture.  If ARG1 is NULL, use typical alignment for size ARG0.  */
5602
 
5603
static tree
5604
fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
5605
{
5606
  int size;
5607
  enum machine_mode mode;
5608
  unsigned int mode_align, type_align;
5609
 
5610
  if (TREE_CODE (arg0) != INTEGER_CST)
5611
    return NULL_TREE;
5612
 
5613
  size = INTVAL (expand_normal (arg0)) * BITS_PER_UNIT;
5614
  mode = mode_for_size (size, MODE_INT, 0);
5615
  mode_align = GET_MODE_ALIGNMENT (mode);
5616
 
5617
  if (TREE_CODE (arg1) == INTEGER_CST && INTVAL (expand_normal (arg1)) == 0)
5618
    type_align = mode_align;
5619
  else
5620
    {
5621
      tree ttype = TREE_TYPE (arg1);
5622
 
5623
      /* This function is usually invoked and folded immediately by the front
5624
         end before anything else has a chance to look at it.  The pointer
5625
         parameter at this point is usually cast to a void *, so check for that
5626
         and look past the cast.  */
5627
      if (TREE_CODE (arg1) == NOP_EXPR && POINTER_TYPE_P (ttype)
5628
          && VOID_TYPE_P (TREE_TYPE (ttype)))
5629
        arg1 = TREE_OPERAND (arg1, 0);
5630
 
5631
      ttype = TREE_TYPE (arg1);
5632
      gcc_assert (POINTER_TYPE_P (ttype));
5633
 
5634
      /* Get the underlying type of the object.  */
5635
      ttype = TREE_TYPE (ttype);
5636
      type_align = TYPE_ALIGN (ttype);
5637
    }
5638
 
5639
  /* If the object has smaller alignment, the the lock free routines cannot
5640
     be used.  */
5641
  if (type_align < mode_align)
5642
    return boolean_false_node;
5643
 
5644
  /* Check if a compare_and_swap pattern exists for the mode which represents
5645
     the required size.  The pattern is not allowed to fail, so the existence
5646
     of the pattern indicates support is present.  */
5647
  if (can_compare_and_swap_p (mode, true))
5648
    return boolean_true_node;
5649
  else
5650
    return boolean_false_node;
5651
}
5652
 
5653
/* Return true if the parameters to call EXP represent an object which will
5654
   always generate lock free instructions.  The first argument represents the
5655
   size of the object, and the second parameter is a pointer to the object
5656
   itself.  If NULL is passed for the object, then the result is based on
5657
   typical alignment for an object of the specified size.  Otherwise return
5658
   false.  */
5659
 
5660
static rtx
5661
expand_builtin_atomic_always_lock_free (tree exp)
5662
{
5663
  tree size;
5664
  tree arg0 = CALL_EXPR_ARG (exp, 0);
5665
  tree arg1 = CALL_EXPR_ARG (exp, 1);
5666
 
5667
  if (TREE_CODE (arg0) != INTEGER_CST)
5668
    {
5669
      error ("non-constant argument 1 to __atomic_always_lock_free");
5670
      return const0_rtx;
5671
    }
5672
 
5673
  size = fold_builtin_atomic_always_lock_free (arg0, arg1);
5674
  if (size == boolean_true_node)
5675
    return const1_rtx;
5676
  return const0_rtx;
5677
}
5678
 
5679
/* Return a one or zero if it can be determined that object ARG1 of size ARG
5680
   is lock free on this architecture.  */
5681
 
5682
static tree
5683
fold_builtin_atomic_is_lock_free (tree arg0, tree arg1)
5684
{
5685
  if (!flag_inline_atomics)
5686
    return NULL_TREE;
5687
 
5688
  /* If it isn't always lock free, don't generate a result.  */
5689
  if (fold_builtin_atomic_always_lock_free (arg0, arg1) == boolean_true_node)
5690
    return boolean_true_node;
5691
 
5692
  return NULL_TREE;
5693
}
5694
 
5695
/* Return true if the parameters to call EXP represent an object which will
5696
   always generate lock free instructions.  The first argument represents the
5697
   size of the object, and the second parameter is a pointer to the object
5698
   itself.  If NULL is passed for the object, then the result is based on
5699
   typical alignment for an object of the specified size.  Otherwise return
5700
   NULL*/
5701
 
5702
static rtx
5703
expand_builtin_atomic_is_lock_free (tree exp)
5704
{
5705
  tree size;
5706
  tree arg0 = CALL_EXPR_ARG (exp, 0);
5707
  tree arg1 = CALL_EXPR_ARG (exp, 1);
5708
 
5709
  if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
5710
    {
5711
      error ("non-integer argument 1 to __atomic_is_lock_free");
5712
      return NULL_RTX;
5713
    }
5714
 
5715
  if (!flag_inline_atomics)
5716
    return NULL_RTX;
5717
 
5718
  /* If the value is known at compile time, return the RTX for it.  */
5719
  size = fold_builtin_atomic_is_lock_free (arg0, arg1);
5720
  if (size == boolean_true_node)
5721
    return const1_rtx;
5722
 
5723
  return NULL_RTX;
5724
}
5725
 
5726
/* Expand the __atomic_thread_fence intrinsic:
5727
        void __atomic_thread_fence (enum memmodel)
5728
   EXP is the CALL_EXPR.  */
5729
 
5730
static void
5731
expand_builtin_atomic_thread_fence (tree exp)
5732
{
5733
  enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5734
  expand_mem_thread_fence (model);
5735
}
5736
 
5737
/* Expand the __atomic_signal_fence intrinsic:
5738
        void __atomic_signal_fence (enum memmodel)
5739
   EXP is the CALL_EXPR.  */
5740
 
5741
static void
5742
expand_builtin_atomic_signal_fence (tree exp)
5743
{
5744
  enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5745
  expand_mem_signal_fence (model);
5746
}
5747
 
5748
/* Expand the __sync_synchronize intrinsic.  */
5749
 
5750
static void
5751
expand_builtin_sync_synchronize (void)
5752
{
5753
  expand_mem_thread_fence (MEMMODEL_SEQ_CST);
5754
}
5755
 
5756
 
5757
/* Expand an expression EXP that calls a built-in function,
5758
   with result going to TARGET if that's convenient
5759
   (and in mode MODE if that's convenient).
5760
   SUBTARGET may be used as the target for computing one of EXP's operands.
5761
   IGNORE is nonzero if the value is to be ignored.  */
5762
 
5763
rtx
5764
expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5765
                int ignore)
5766
{
5767
  tree fndecl = get_callee_fndecl (exp);
5768
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5769
  enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5770
  int flags;
5771
 
5772
  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5773
    return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5774
 
5775
  /* When not optimizing, generate calls to library functions for a certain
5776
     set of builtins.  */
5777
  if (!optimize
5778
      && !called_as_built_in (fndecl)
5779
      && fcode != BUILT_IN_ALLOCA
5780
      && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
5781
      && fcode != BUILT_IN_FREE)
5782
    return expand_call (exp, target, ignore);
5783
 
5784
  /* The built-in function expanders test for target == const0_rtx
5785
     to determine whether the function's result will be ignored.  */
5786
  if (ignore)
5787
    target = const0_rtx;
5788
 
5789
  /* If the result of a pure or const built-in function is ignored, and
5790
     none of its arguments are volatile, we can avoid expanding the
5791
     built-in call and just evaluate the arguments for side-effects.  */
5792
  if (target == const0_rtx
5793
      && ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE))
5794
      && !(flags & ECF_LOOPING_CONST_OR_PURE))
5795
    {
5796
      bool volatilep = false;
5797
      tree arg;
5798
      call_expr_arg_iterator iter;
5799
 
5800
      FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5801
        if (TREE_THIS_VOLATILE (arg))
5802
          {
5803
            volatilep = true;
5804
            break;
5805
          }
5806
 
5807
      if (! volatilep)
5808
        {
5809
          FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5810
            expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
5811
          return const0_rtx;
5812
        }
5813
    }
5814
 
5815
  switch (fcode)
5816
    {
5817
    CASE_FLT_FN (BUILT_IN_FABS):
5818
      target = expand_builtin_fabs (exp, target, subtarget);
5819
      if (target)
5820
        return target;
5821
      break;
5822
 
5823
    CASE_FLT_FN (BUILT_IN_COPYSIGN):
5824
      target = expand_builtin_copysign (exp, target, subtarget);
5825
      if (target)
5826
        return target;
5827
      break;
5828
 
5829
      /* Just do a normal library call if we were unable to fold
5830
         the values.  */
5831
    CASE_FLT_FN (BUILT_IN_CABS):
5832
      break;
5833
 
5834
    CASE_FLT_FN (BUILT_IN_EXP):
5835
    CASE_FLT_FN (BUILT_IN_EXP10):
5836
    CASE_FLT_FN (BUILT_IN_POW10):
5837
    CASE_FLT_FN (BUILT_IN_EXP2):
5838
    CASE_FLT_FN (BUILT_IN_EXPM1):
5839
    CASE_FLT_FN (BUILT_IN_LOGB):
5840
    CASE_FLT_FN (BUILT_IN_LOG):
5841
    CASE_FLT_FN (BUILT_IN_LOG10):
5842
    CASE_FLT_FN (BUILT_IN_LOG2):
5843
    CASE_FLT_FN (BUILT_IN_LOG1P):
5844
    CASE_FLT_FN (BUILT_IN_TAN):
5845
    CASE_FLT_FN (BUILT_IN_ASIN):
5846
    CASE_FLT_FN (BUILT_IN_ACOS):
5847
    CASE_FLT_FN (BUILT_IN_ATAN):
5848
    CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
5849
      /* Treat these like sqrt only if unsafe math optimizations are allowed,
5850
         because of possible accuracy problems.  */
5851
      if (! flag_unsafe_math_optimizations)
5852
        break;
5853
    CASE_FLT_FN (BUILT_IN_SQRT):
5854
    CASE_FLT_FN (BUILT_IN_FLOOR):
5855
    CASE_FLT_FN (BUILT_IN_CEIL):
5856
    CASE_FLT_FN (BUILT_IN_TRUNC):
5857
    CASE_FLT_FN (BUILT_IN_ROUND):
5858
    CASE_FLT_FN (BUILT_IN_NEARBYINT):
5859
    CASE_FLT_FN (BUILT_IN_RINT):
5860
      target = expand_builtin_mathfn (exp, target, subtarget);
5861
      if (target)
5862
        return target;
5863
      break;
5864
 
5865
    CASE_FLT_FN (BUILT_IN_FMA):
5866
      target = expand_builtin_mathfn_ternary (exp, target, subtarget);
5867
      if (target)
5868
        return target;
5869
      break;
5870
 
5871
    CASE_FLT_FN (BUILT_IN_ILOGB):
5872
      if (! flag_unsafe_math_optimizations)
5873
        break;
5874
    CASE_FLT_FN (BUILT_IN_ISINF):
5875
    CASE_FLT_FN (BUILT_IN_FINITE):
5876
    case BUILT_IN_ISFINITE:
5877
    case BUILT_IN_ISNORMAL:
5878
      target = expand_builtin_interclass_mathfn (exp, target);
5879
      if (target)
5880
        return target;
5881
      break;
5882
 
5883
    CASE_FLT_FN (BUILT_IN_ICEIL):
5884
    CASE_FLT_FN (BUILT_IN_LCEIL):
5885
    CASE_FLT_FN (BUILT_IN_LLCEIL):
5886
    CASE_FLT_FN (BUILT_IN_LFLOOR):
5887
    CASE_FLT_FN (BUILT_IN_IFLOOR):
5888
    CASE_FLT_FN (BUILT_IN_LLFLOOR):
5889
      target = expand_builtin_int_roundingfn (exp, target);
5890
      if (target)
5891
        return target;
5892
      break;
5893
 
5894
    CASE_FLT_FN (BUILT_IN_IRINT):
5895
    CASE_FLT_FN (BUILT_IN_LRINT):
5896
    CASE_FLT_FN (BUILT_IN_LLRINT):
5897
    CASE_FLT_FN (BUILT_IN_IROUND):
5898
    CASE_FLT_FN (BUILT_IN_LROUND):
5899
    CASE_FLT_FN (BUILT_IN_LLROUND):
5900
      target = expand_builtin_int_roundingfn_2 (exp, target);
5901
      if (target)
5902
        return target;
5903
      break;
5904
 
5905
    CASE_FLT_FN (BUILT_IN_POWI):
5906
      target = expand_builtin_powi (exp, target);
5907
      if (target)
5908
        return target;
5909
      break;
5910
 
5911
    CASE_FLT_FN (BUILT_IN_ATAN2):
5912
    CASE_FLT_FN (BUILT_IN_LDEXP):
5913
    CASE_FLT_FN (BUILT_IN_SCALB):
5914
    CASE_FLT_FN (BUILT_IN_SCALBN):
5915
    CASE_FLT_FN (BUILT_IN_SCALBLN):
5916
      if (! flag_unsafe_math_optimizations)
5917
        break;
5918
 
5919
    CASE_FLT_FN (BUILT_IN_FMOD):
5920
    CASE_FLT_FN (BUILT_IN_REMAINDER):
5921
    CASE_FLT_FN (BUILT_IN_DREM):
5922
    CASE_FLT_FN (BUILT_IN_POW):
5923
      target = expand_builtin_mathfn_2 (exp, target, subtarget);
5924
      if (target)
5925
        return target;
5926
      break;
5927
 
5928
    CASE_FLT_FN (BUILT_IN_CEXPI):
5929
      target = expand_builtin_cexpi (exp, target);
5930
      gcc_assert (target);
5931
      return target;
5932
 
5933
    CASE_FLT_FN (BUILT_IN_SIN):
5934
    CASE_FLT_FN (BUILT_IN_COS):
5935
      if (! flag_unsafe_math_optimizations)
5936
        break;
5937
      target = expand_builtin_mathfn_3 (exp, target, subtarget);
5938
      if (target)
5939
        return target;
5940
      break;
5941
 
5942
    CASE_FLT_FN (BUILT_IN_SINCOS):
5943
      if (! flag_unsafe_math_optimizations)
5944
        break;
5945
      target = expand_builtin_sincos (exp);
5946
      if (target)
5947
        return target;
5948
      break;
5949
 
5950
    case BUILT_IN_APPLY_ARGS:
5951
      return expand_builtin_apply_args ();
5952
 
5953
      /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5954
         FUNCTION with a copy of the parameters described by
5955
         ARGUMENTS, and ARGSIZE.  It returns a block of memory
5956
         allocated on the stack into which is stored all the registers
5957
         that might possibly be used for returning the result of a
5958
         function.  ARGUMENTS is the value returned by
5959
         __builtin_apply_args.  ARGSIZE is the number of bytes of
5960
         arguments that must be copied.  ??? How should this value be
5961
         computed?  We'll also need a safe worst case value for varargs
5962
         functions.  */
5963
    case BUILT_IN_APPLY:
5964
      if (!validate_arglist (exp, POINTER_TYPE,
5965
                             POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5966
          && !validate_arglist (exp, REFERENCE_TYPE,
5967
                                POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5968
        return const0_rtx;
5969
      else
5970
        {
5971
          rtx ops[3];
5972
 
5973
          ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
5974
          ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
5975
          ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
5976
 
5977
          return expand_builtin_apply (ops[0], ops[1], ops[2]);
5978
        }
5979
 
5980
      /* __builtin_return (RESULT) causes the function to return the
5981
         value described by RESULT.  RESULT is address of the block of
5982
         memory returned by __builtin_apply.  */
5983
    case BUILT_IN_RETURN:
5984
      if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5985
        expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
5986
      return const0_rtx;
5987
 
5988
    case BUILT_IN_SAVEREGS:
5989
      return expand_builtin_saveregs ();
5990
 
5991
    case BUILT_IN_VA_ARG_PACK:
5992
      /* All valid uses of __builtin_va_arg_pack () are removed during
5993
         inlining.  */
5994
      error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
5995
      return const0_rtx;
5996
 
5997
    case BUILT_IN_VA_ARG_PACK_LEN:
5998
      /* All valid uses of __builtin_va_arg_pack_len () are removed during
5999
         inlining.  */
6000
      error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6001
      return const0_rtx;
6002
 
6003
      /* Return the address of the first anonymous stack arg.  */
6004
    case BUILT_IN_NEXT_ARG:
6005
      if (fold_builtin_next_arg (exp, false))
6006
        return const0_rtx;
6007
      return expand_builtin_next_arg ();
6008
 
6009
    case BUILT_IN_CLEAR_CACHE:
6010
      target = expand_builtin___clear_cache (exp);
6011
      if (target)
6012
        return target;
6013
      break;
6014
 
6015
    case BUILT_IN_CLASSIFY_TYPE:
6016
      return expand_builtin_classify_type (exp);
6017
 
6018
    case BUILT_IN_CONSTANT_P:
6019
      return const0_rtx;
6020
 
6021
    case BUILT_IN_FRAME_ADDRESS:
6022
    case BUILT_IN_RETURN_ADDRESS:
6023
      return expand_builtin_frame_address (fndecl, exp);
6024
 
6025
    /* Returns the address of the area where the structure is returned.
6026
 
6027
    case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6028
      if (call_expr_nargs (exp) != 0
6029
          || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6030
          || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6031
        return const0_rtx;
6032
      else
6033
        return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6034
 
6035
    case BUILT_IN_ALLOCA:
6036
    case BUILT_IN_ALLOCA_WITH_ALIGN:
6037
      /* If the allocation stems from the declaration of a variable-sized
6038
         object, it cannot accumulate.  */
6039
      target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp));
6040
      if (target)
6041
        return target;
6042
      break;
6043
 
6044
    case BUILT_IN_STACK_SAVE:
6045
      return expand_stack_save ();
6046
 
6047
    case BUILT_IN_STACK_RESTORE:
6048
      expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6049
      return const0_rtx;
6050
 
6051
    case BUILT_IN_BSWAP32:
6052
    case BUILT_IN_BSWAP64:
6053
      target = expand_builtin_bswap (exp, target, subtarget);
6054
 
6055
      if (target)
6056
        return target;
6057
      break;
6058
 
6059
    CASE_INT_FN (BUILT_IN_FFS):
6060
    case BUILT_IN_FFSIMAX:
6061
      target = expand_builtin_unop (target_mode, exp, target,
6062
                                    subtarget, ffs_optab);
6063
      if (target)
6064
        return target;
6065
      break;
6066
 
6067
    CASE_INT_FN (BUILT_IN_CLZ):
6068
    case BUILT_IN_CLZIMAX:
6069
      target = expand_builtin_unop (target_mode, exp, target,
6070
                                    subtarget, clz_optab);
6071
      if (target)
6072
        return target;
6073
      break;
6074
 
6075
    CASE_INT_FN (BUILT_IN_CTZ):
6076
    case BUILT_IN_CTZIMAX:
6077
      target = expand_builtin_unop (target_mode, exp, target,
6078
                                    subtarget, ctz_optab);
6079
      if (target)
6080
        return target;
6081
      break;
6082
 
6083
    CASE_INT_FN (BUILT_IN_CLRSB):
6084
    case BUILT_IN_CLRSBIMAX:
6085
      target = expand_builtin_unop (target_mode, exp, target,
6086
                                    subtarget, clrsb_optab);
6087
      if (target)
6088
        return target;
6089
      break;
6090
 
6091
    CASE_INT_FN (BUILT_IN_POPCOUNT):
6092
    case BUILT_IN_POPCOUNTIMAX:
6093
      target = expand_builtin_unop (target_mode, exp, target,
6094
                                    subtarget, popcount_optab);
6095
      if (target)
6096
        return target;
6097
      break;
6098
 
6099
    CASE_INT_FN (BUILT_IN_PARITY):
6100
    case BUILT_IN_PARITYIMAX:
6101
      target = expand_builtin_unop (target_mode, exp, target,
6102
                                    subtarget, parity_optab);
6103
      if (target)
6104
        return target;
6105
      break;
6106
 
6107
    case BUILT_IN_STRLEN:
6108
      target = expand_builtin_strlen (exp, target, target_mode);
6109
      if (target)
6110
        return target;
6111
      break;
6112
 
6113
    case BUILT_IN_STRCPY:
6114
      target = expand_builtin_strcpy (exp, target);
6115
      if (target)
6116
        return target;
6117
      break;
6118
 
6119
    case BUILT_IN_STRNCPY:
6120
      target = expand_builtin_strncpy (exp, target);
6121
      if (target)
6122
        return target;
6123
      break;
6124
 
6125
    case BUILT_IN_STPCPY:
6126
      target = expand_builtin_stpcpy (exp, target, mode);
6127
      if (target)
6128
        return target;
6129
      break;
6130
 
6131
    case BUILT_IN_MEMCPY:
6132
      target = expand_builtin_memcpy (exp, target);
6133
      if (target)
6134
        return target;
6135
      break;
6136
 
6137
    case BUILT_IN_MEMPCPY:
6138
      target = expand_builtin_mempcpy (exp, target, mode);
6139
      if (target)
6140
        return target;
6141
      break;
6142
 
6143
    case BUILT_IN_MEMSET:
6144
      target = expand_builtin_memset (exp, target, mode);
6145
      if (target)
6146
        return target;
6147
      break;
6148
 
6149
    case BUILT_IN_BZERO:
6150
      target = expand_builtin_bzero (exp);
6151
      if (target)
6152
        return target;
6153
      break;
6154
 
6155
    case BUILT_IN_STRCMP:
6156
      target = expand_builtin_strcmp (exp, target);
6157
      if (target)
6158
        return target;
6159
      break;
6160
 
6161
    case BUILT_IN_STRNCMP:
6162
      target = expand_builtin_strncmp (exp, target, mode);
6163
      if (target)
6164
        return target;
6165
      break;
6166
 
6167
    case BUILT_IN_BCMP:
6168
    case BUILT_IN_MEMCMP:
6169
      target = expand_builtin_memcmp (exp, target, mode);
6170
      if (target)
6171
        return target;
6172
      break;
6173
 
6174
    case BUILT_IN_SETJMP:
6175
      /* This should have been lowered to the builtins below.  */
6176
      gcc_unreachable ();
6177
 
6178
    case BUILT_IN_SETJMP_SETUP:
6179
      /* __builtin_setjmp_setup is passed a pointer to an array of five words
6180
          and the receiver label.  */
6181
      if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6182
        {
6183
          rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6184
                                      VOIDmode, EXPAND_NORMAL);
6185
          tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6186
          rtx label_r = label_rtx (label);
6187
 
6188
          /* This is copied from the handling of non-local gotos.  */
6189
          expand_builtin_setjmp_setup (buf_addr, label_r);
6190
          nonlocal_goto_handler_labels
6191
            = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6192
                                 nonlocal_goto_handler_labels);
6193
          /* ??? Do not let expand_label treat us as such since we would
6194
             not want to be both on the list of non-local labels and on
6195
             the list of forced labels.  */
6196
          FORCED_LABEL (label) = 0;
6197
          return const0_rtx;
6198
        }
6199
      break;
6200
 
6201
    case BUILT_IN_SETJMP_DISPATCHER:
6202
       /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6203
      if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6204
        {
6205
          tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6206
          rtx label_r = label_rtx (label);
6207
 
6208
          /* Remove the dispatcher label from the list of non-local labels
6209
             since the receiver labels have been added to it above.  */
6210
          remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6211
          return const0_rtx;
6212
        }
6213
      break;
6214
 
6215
    case BUILT_IN_SETJMP_RECEIVER:
6216
       /* __builtin_setjmp_receiver is passed the receiver label.  */
6217
      if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6218
        {
6219
          tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6220
          rtx label_r = label_rtx (label);
6221
 
6222
          expand_builtin_setjmp_receiver (label_r);
6223
          return const0_rtx;
6224
        }
6225
      break;
6226
 
6227
      /* __builtin_longjmp is passed a pointer to an array of five words.
6228
         It's similar to the C library longjmp function but works with
6229
         __builtin_setjmp above.  */
6230
    case BUILT_IN_LONGJMP:
6231
      if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6232
        {
6233
          rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6234
                                      VOIDmode, EXPAND_NORMAL);
6235
          rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6236
 
6237
          if (value != const1_rtx)
6238
            {
6239
              error ("%<__builtin_longjmp%> second argument must be 1");
6240
              return const0_rtx;
6241
            }
6242
 
6243
          expand_builtin_longjmp (buf_addr, value);
6244
          return const0_rtx;
6245
        }
6246
      break;
6247
 
6248
    case BUILT_IN_NONLOCAL_GOTO:
6249
      target = expand_builtin_nonlocal_goto (exp);
6250
      if (target)
6251
        return target;
6252
      break;
6253
 
6254
      /* This updates the setjmp buffer that is its argument with the value
6255
         of the current stack pointer.  */
6256
    case BUILT_IN_UPDATE_SETJMP_BUF:
6257
      if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6258
        {
6259
          rtx buf_addr
6260
            = expand_normal (CALL_EXPR_ARG (exp, 0));
6261
 
6262
          expand_builtin_update_setjmp_buf (buf_addr);
6263
          return const0_rtx;
6264
        }
6265
      break;
6266
 
6267
    case BUILT_IN_TRAP:
6268
      expand_builtin_trap ();
6269
      return const0_rtx;
6270
 
6271
    case BUILT_IN_UNREACHABLE:
6272
      expand_builtin_unreachable ();
6273
      return const0_rtx;
6274
 
6275
    CASE_FLT_FN (BUILT_IN_SIGNBIT):
6276
    case BUILT_IN_SIGNBITD32:
6277
    case BUILT_IN_SIGNBITD64:
6278
    case BUILT_IN_SIGNBITD128:
6279
      target = expand_builtin_signbit (exp, target);
6280
      if (target)
6281
        return target;
6282
      break;
6283
 
6284
      /* Various hooks for the DWARF 2 __throw routine.  */
6285
    case BUILT_IN_UNWIND_INIT:
6286
      expand_builtin_unwind_init ();
6287
      return const0_rtx;
6288
    case BUILT_IN_DWARF_CFA:
6289
      return virtual_cfa_rtx;
6290
#ifdef DWARF2_UNWIND_INFO
6291
    case BUILT_IN_DWARF_SP_COLUMN:
6292
      return expand_builtin_dwarf_sp_column ();
6293
    case BUILT_IN_INIT_DWARF_REG_SIZES:
6294
      expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6295
      return const0_rtx;
6296
#endif
6297
    case BUILT_IN_FROB_RETURN_ADDR:
6298
      return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6299
    case BUILT_IN_EXTRACT_RETURN_ADDR:
6300
      return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6301
    case BUILT_IN_EH_RETURN:
6302
      expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6303
                                CALL_EXPR_ARG (exp, 1));
6304
      return const0_rtx;
6305
#ifdef EH_RETURN_DATA_REGNO
6306
    case BUILT_IN_EH_RETURN_DATA_REGNO:
6307
      return expand_builtin_eh_return_data_regno (exp);
6308
#endif
6309
    case BUILT_IN_EXTEND_POINTER:
6310
      return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6311
    case BUILT_IN_EH_POINTER:
6312
      return expand_builtin_eh_pointer (exp);
6313
    case BUILT_IN_EH_FILTER:
6314
      return expand_builtin_eh_filter (exp);
6315
    case BUILT_IN_EH_COPY_VALUES:
6316
      return expand_builtin_eh_copy_values (exp);
6317
 
6318
    case BUILT_IN_VA_START:
6319
      return expand_builtin_va_start (exp);
6320
    case BUILT_IN_VA_END:
6321
      return expand_builtin_va_end (exp);
6322
    case BUILT_IN_VA_COPY:
6323
      return expand_builtin_va_copy (exp);
6324
    case BUILT_IN_EXPECT:
6325
      return expand_builtin_expect (exp, target);
6326
    case BUILT_IN_ASSUME_ALIGNED:
6327
      return expand_builtin_assume_aligned (exp, target);
6328
    case BUILT_IN_PREFETCH:
6329
      expand_builtin_prefetch (exp);
6330
      return const0_rtx;
6331
 
6332
    case BUILT_IN_INIT_TRAMPOLINE:
6333
      return expand_builtin_init_trampoline (exp, true);
6334
    case BUILT_IN_INIT_HEAP_TRAMPOLINE:
6335
      return expand_builtin_init_trampoline (exp, false);
6336
    case BUILT_IN_ADJUST_TRAMPOLINE:
6337
      return expand_builtin_adjust_trampoline (exp);
6338
 
6339
    case BUILT_IN_FORK:
6340
    case BUILT_IN_EXECL:
6341
    case BUILT_IN_EXECV:
6342
    case BUILT_IN_EXECLP:
6343
    case BUILT_IN_EXECLE:
6344
    case BUILT_IN_EXECVP:
6345
    case BUILT_IN_EXECVE:
6346
      target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6347
      if (target)
6348
        return target;
6349
      break;
6350
 
6351
    case BUILT_IN_SYNC_FETCH_AND_ADD_1:
6352
    case BUILT_IN_SYNC_FETCH_AND_ADD_2:
6353
    case BUILT_IN_SYNC_FETCH_AND_ADD_4:
6354
    case BUILT_IN_SYNC_FETCH_AND_ADD_8:
6355
    case BUILT_IN_SYNC_FETCH_AND_ADD_16:
6356
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_ADD_1);
6357
      target = expand_builtin_sync_operation (mode, exp, PLUS, false, target);
6358
      if (target)
6359
        return target;
6360
      break;
6361
 
6362
    case BUILT_IN_SYNC_FETCH_AND_SUB_1:
6363
    case BUILT_IN_SYNC_FETCH_AND_SUB_2:
6364
    case BUILT_IN_SYNC_FETCH_AND_SUB_4:
6365
    case BUILT_IN_SYNC_FETCH_AND_SUB_8:
6366
    case BUILT_IN_SYNC_FETCH_AND_SUB_16:
6367
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_SUB_1);
6368
      target = expand_builtin_sync_operation (mode, exp, MINUS, false, target);
6369
      if (target)
6370
        return target;
6371
      break;
6372
 
6373
    case BUILT_IN_SYNC_FETCH_AND_OR_1:
6374
    case BUILT_IN_SYNC_FETCH_AND_OR_2:
6375
    case BUILT_IN_SYNC_FETCH_AND_OR_4:
6376
    case BUILT_IN_SYNC_FETCH_AND_OR_8:
6377
    case BUILT_IN_SYNC_FETCH_AND_OR_16:
6378
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_OR_1);
6379
      target = expand_builtin_sync_operation (mode, exp, IOR, false, target);
6380
      if (target)
6381
        return target;
6382
      break;
6383
 
6384
    case BUILT_IN_SYNC_FETCH_AND_AND_1:
6385
    case BUILT_IN_SYNC_FETCH_AND_AND_2:
6386
    case BUILT_IN_SYNC_FETCH_AND_AND_4:
6387
    case BUILT_IN_SYNC_FETCH_AND_AND_8:
6388
    case BUILT_IN_SYNC_FETCH_AND_AND_16:
6389
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_AND_1);
6390
      target = expand_builtin_sync_operation (mode, exp, AND, false, target);
6391
      if (target)
6392
        return target;
6393
      break;
6394
 
6395
    case BUILT_IN_SYNC_FETCH_AND_XOR_1:
6396
    case BUILT_IN_SYNC_FETCH_AND_XOR_2:
6397
    case BUILT_IN_SYNC_FETCH_AND_XOR_4:
6398
    case BUILT_IN_SYNC_FETCH_AND_XOR_8:
6399
    case BUILT_IN_SYNC_FETCH_AND_XOR_16:
6400
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_XOR_1);
6401
      target = expand_builtin_sync_operation (mode, exp, XOR, false, target);
6402
      if (target)
6403
        return target;
6404
      break;
6405
 
6406
    case BUILT_IN_SYNC_FETCH_AND_NAND_1:
6407
    case BUILT_IN_SYNC_FETCH_AND_NAND_2:
6408
    case BUILT_IN_SYNC_FETCH_AND_NAND_4:
6409
    case BUILT_IN_SYNC_FETCH_AND_NAND_8:
6410
    case BUILT_IN_SYNC_FETCH_AND_NAND_16:
6411
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_NAND_1);
6412
      target = expand_builtin_sync_operation (mode, exp, NOT, false, target);
6413
      if (target)
6414
        return target;
6415
      break;
6416
 
6417
    case BUILT_IN_SYNC_ADD_AND_FETCH_1:
6418
    case BUILT_IN_SYNC_ADD_AND_FETCH_2:
6419
    case BUILT_IN_SYNC_ADD_AND_FETCH_4:
6420
    case BUILT_IN_SYNC_ADD_AND_FETCH_8:
6421
    case BUILT_IN_SYNC_ADD_AND_FETCH_16:
6422
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_ADD_AND_FETCH_1);
6423
      target = expand_builtin_sync_operation (mode, exp, PLUS, true, target);
6424
      if (target)
6425
        return target;
6426
      break;
6427
 
6428
    case BUILT_IN_SYNC_SUB_AND_FETCH_1:
6429
    case BUILT_IN_SYNC_SUB_AND_FETCH_2:
6430
    case BUILT_IN_SYNC_SUB_AND_FETCH_4:
6431
    case BUILT_IN_SYNC_SUB_AND_FETCH_8:
6432
    case BUILT_IN_SYNC_SUB_AND_FETCH_16:
6433
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_SUB_AND_FETCH_1);
6434
      target = expand_builtin_sync_operation (mode, exp, MINUS, true, target);
6435
      if (target)
6436
        return target;
6437
      break;
6438
 
6439
    case BUILT_IN_SYNC_OR_AND_FETCH_1:
6440
    case BUILT_IN_SYNC_OR_AND_FETCH_2:
6441
    case BUILT_IN_SYNC_OR_AND_FETCH_4:
6442
    case BUILT_IN_SYNC_OR_AND_FETCH_8:
6443
    case BUILT_IN_SYNC_OR_AND_FETCH_16:
6444
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_OR_AND_FETCH_1);
6445
      target = expand_builtin_sync_operation (mode, exp, IOR, true, target);
6446
      if (target)
6447
        return target;
6448
      break;
6449
 
6450
    case BUILT_IN_SYNC_AND_AND_FETCH_1:
6451
    case BUILT_IN_SYNC_AND_AND_FETCH_2:
6452
    case BUILT_IN_SYNC_AND_AND_FETCH_4:
6453
    case BUILT_IN_SYNC_AND_AND_FETCH_8:
6454
    case BUILT_IN_SYNC_AND_AND_FETCH_16:
6455
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_AND_AND_FETCH_1);
6456
      target = expand_builtin_sync_operation (mode, exp, AND, true, target);
6457
      if (target)
6458
        return target;
6459
      break;
6460
 
6461
    case BUILT_IN_SYNC_XOR_AND_FETCH_1:
6462
    case BUILT_IN_SYNC_XOR_AND_FETCH_2:
6463
    case BUILT_IN_SYNC_XOR_AND_FETCH_4:
6464
    case BUILT_IN_SYNC_XOR_AND_FETCH_8:
6465
    case BUILT_IN_SYNC_XOR_AND_FETCH_16:
6466
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_XOR_AND_FETCH_1);
6467
      target = expand_builtin_sync_operation (mode, exp, XOR, true, target);
6468
      if (target)
6469
        return target;
6470
      break;
6471
 
6472
    case BUILT_IN_SYNC_NAND_AND_FETCH_1:
6473
    case BUILT_IN_SYNC_NAND_AND_FETCH_2:
6474
    case BUILT_IN_SYNC_NAND_AND_FETCH_4:
6475
    case BUILT_IN_SYNC_NAND_AND_FETCH_8:
6476
    case BUILT_IN_SYNC_NAND_AND_FETCH_16:
6477
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_NAND_AND_FETCH_1);
6478
      target = expand_builtin_sync_operation (mode, exp, NOT, true, target);
6479
      if (target)
6480
        return target;
6481
      break;
6482
 
6483
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
6484
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
6485
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
6486
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
6487
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
6488
      if (mode == VOIDmode)
6489
        mode = TYPE_MODE (boolean_type_node);
6490
      if (!target || !register_operand (target, mode))
6491
        target = gen_reg_rtx (mode);
6492
 
6493
      mode = get_builtin_sync_mode
6494
                                (fcode - BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1);
6495
      target = expand_builtin_compare_and_swap (mode, exp, true, target);
6496
      if (target)
6497
        return target;
6498
      break;
6499
 
6500
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
6501
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
6502
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
6503
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
6504
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
6505
      mode = get_builtin_sync_mode
6506
                                (fcode - BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1);
6507
      target = expand_builtin_compare_and_swap (mode, exp, false, target);
6508
      if (target)
6509
        return target;
6510
      break;
6511
 
6512
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
6513
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
6514
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
6515
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
6516
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
6517
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_TEST_AND_SET_1);
6518
      target = expand_builtin_sync_lock_test_and_set (mode, exp, target);
6519
      if (target)
6520
        return target;
6521
      break;
6522
 
6523
    case BUILT_IN_SYNC_LOCK_RELEASE_1:
6524
    case BUILT_IN_SYNC_LOCK_RELEASE_2:
6525
    case BUILT_IN_SYNC_LOCK_RELEASE_4:
6526
    case BUILT_IN_SYNC_LOCK_RELEASE_8:
6527
    case BUILT_IN_SYNC_LOCK_RELEASE_16:
6528
      mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_RELEASE_1);
6529
      expand_builtin_sync_lock_release (mode, exp);
6530
      return const0_rtx;
6531
 
6532
    case BUILT_IN_SYNC_SYNCHRONIZE:
6533
      expand_builtin_sync_synchronize ();
6534
      return const0_rtx;
6535
 
6536
    case BUILT_IN_ATOMIC_EXCHANGE_1:
6537
    case BUILT_IN_ATOMIC_EXCHANGE_2:
6538
    case BUILT_IN_ATOMIC_EXCHANGE_4:
6539
    case BUILT_IN_ATOMIC_EXCHANGE_8:
6540
    case BUILT_IN_ATOMIC_EXCHANGE_16:
6541
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_EXCHANGE_1);
6542
      target = expand_builtin_atomic_exchange (mode, exp, target);
6543
      if (target)
6544
        return target;
6545
      break;
6546
 
6547
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
6548
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
6549
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
6550
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
6551
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
6552
      {
6553
        unsigned int nargs, z;
6554
        VEC(tree,gc) *vec;
6555
 
6556
        mode =
6557
            get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
6558
        target = expand_builtin_atomic_compare_exchange (mode, exp, target);
6559
        if (target)
6560
          return target;
6561
 
6562
        /* If this is turned into an external library call, the weak parameter
6563
           must be dropped to match the expected parameter list.  */
6564
        nargs = call_expr_nargs (exp);
6565
        vec = VEC_alloc (tree, gc, nargs - 1);
6566
        for (z = 0; z < 3; z++)
6567
          VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
6568
        /* Skip the boolean weak parameter.  */
6569
        for (z = 4; z < 6; z++)
6570
          VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
6571
        exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
6572
        break;
6573
      }
6574
 
6575
    case BUILT_IN_ATOMIC_LOAD_1:
6576
    case BUILT_IN_ATOMIC_LOAD_2:
6577
    case BUILT_IN_ATOMIC_LOAD_4:
6578
    case BUILT_IN_ATOMIC_LOAD_8:
6579
    case BUILT_IN_ATOMIC_LOAD_16:
6580
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_LOAD_1);
6581
      target = expand_builtin_atomic_load (mode, exp, target);
6582
      if (target)
6583
        return target;
6584
      break;
6585
 
6586
    case BUILT_IN_ATOMIC_STORE_1:
6587
    case BUILT_IN_ATOMIC_STORE_2:
6588
    case BUILT_IN_ATOMIC_STORE_4:
6589
    case BUILT_IN_ATOMIC_STORE_8:
6590
    case BUILT_IN_ATOMIC_STORE_16:
6591
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_STORE_1);
6592
      target = expand_builtin_atomic_store (mode, exp);
6593
      if (target)
6594
        return const0_rtx;
6595
      break;
6596
 
6597
    case BUILT_IN_ATOMIC_ADD_FETCH_1:
6598
    case BUILT_IN_ATOMIC_ADD_FETCH_2:
6599
    case BUILT_IN_ATOMIC_ADD_FETCH_4:
6600
    case BUILT_IN_ATOMIC_ADD_FETCH_8:
6601
    case BUILT_IN_ATOMIC_ADD_FETCH_16:
6602
      {
6603
        enum built_in_function lib;
6604
        mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1);
6605
        lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_ADD_1 +
6606
                                       (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1));
6607
        target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, true,
6608
                                                 ignore, lib);
6609
        if (target)
6610
          return target;
6611
        break;
6612
      }
6613
    case BUILT_IN_ATOMIC_SUB_FETCH_1:
6614
    case BUILT_IN_ATOMIC_SUB_FETCH_2:
6615
    case BUILT_IN_ATOMIC_SUB_FETCH_4:
6616
    case BUILT_IN_ATOMIC_SUB_FETCH_8:
6617
    case BUILT_IN_ATOMIC_SUB_FETCH_16:
6618
      {
6619
        enum built_in_function lib;
6620
        mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1);
6621
        lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_SUB_1 +
6622
                                       (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1));
6623
        target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, true,
6624
                                                 ignore, lib);
6625
        if (target)
6626
          return target;
6627
        break;
6628
      }
6629
    case BUILT_IN_ATOMIC_AND_FETCH_1:
6630
    case BUILT_IN_ATOMIC_AND_FETCH_2:
6631
    case BUILT_IN_ATOMIC_AND_FETCH_4:
6632
    case BUILT_IN_ATOMIC_AND_FETCH_8:
6633
    case BUILT_IN_ATOMIC_AND_FETCH_16:
6634
      {
6635
        enum built_in_function lib;
6636
        mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_AND_FETCH_1);
6637
        lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_AND_1 +
6638
                                       (fcode - BUILT_IN_ATOMIC_AND_FETCH_1));
6639
        target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, true,
6640
                                                 ignore, lib);
6641
        if (target)
6642
          return target;
6643
        break;
6644
      }
6645
    case BUILT_IN_ATOMIC_NAND_FETCH_1:
6646
    case BUILT_IN_ATOMIC_NAND_FETCH_2:
6647
    case BUILT_IN_ATOMIC_NAND_FETCH_4:
6648
    case BUILT_IN_ATOMIC_NAND_FETCH_8:
6649
    case BUILT_IN_ATOMIC_NAND_FETCH_16:
6650
      {
6651
        enum built_in_function lib;
6652
        mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1);
6653
        lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_NAND_1 +
6654
                                       (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1));
6655
        target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, true,
6656
                                                 ignore, lib);
6657
        if (target)
6658
          return target;
6659
        break;
6660
      }
6661
    case BUILT_IN_ATOMIC_XOR_FETCH_1:
6662
    case BUILT_IN_ATOMIC_XOR_FETCH_2:
6663
    case BUILT_IN_ATOMIC_XOR_FETCH_4:
6664
    case BUILT_IN_ATOMIC_XOR_FETCH_8:
6665
    case BUILT_IN_ATOMIC_XOR_FETCH_16:
6666
      {
6667
        enum built_in_function lib;
6668
        mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1);
6669
        lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_XOR_1 +
6670
                                       (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1));
6671
        target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, true,
6672
                                                 ignore, lib);
6673
        if (target)
6674
          return target;
6675
        break;
6676
      }
6677
    case BUILT_IN_ATOMIC_OR_FETCH_1:
6678
    case BUILT_IN_ATOMIC_OR_FETCH_2:
6679
    case BUILT_IN_ATOMIC_OR_FETCH_4:
6680
    case BUILT_IN_ATOMIC_OR_FETCH_8:
6681
    case BUILT_IN_ATOMIC_OR_FETCH_16:
6682
      {
6683
        enum built_in_function lib;
6684
        mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_OR_FETCH_1);
6685
        lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_OR_1 +
6686
                                       (fcode - BUILT_IN_ATOMIC_OR_FETCH_1));
6687
        target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, true,
6688
                                                 ignore, lib);
6689
        if (target)
6690
          return target;
6691
        break;
6692
      }
6693
    case BUILT_IN_ATOMIC_FETCH_ADD_1:
6694
    case BUILT_IN_ATOMIC_FETCH_ADD_2:
6695
    case BUILT_IN_ATOMIC_FETCH_ADD_4:
6696
    case BUILT_IN_ATOMIC_FETCH_ADD_8:
6697
    case BUILT_IN_ATOMIC_FETCH_ADD_16:
6698
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_ADD_1);
6699
      target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, false,
6700
                                               ignore, BUILT_IN_NONE);
6701
      if (target)
6702
        return target;
6703
      break;
6704
 
6705
    case BUILT_IN_ATOMIC_FETCH_SUB_1:
6706
    case BUILT_IN_ATOMIC_FETCH_SUB_2:
6707
    case BUILT_IN_ATOMIC_FETCH_SUB_4:
6708
    case BUILT_IN_ATOMIC_FETCH_SUB_8:
6709
    case BUILT_IN_ATOMIC_FETCH_SUB_16:
6710
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_SUB_1);
6711
      target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, false,
6712
                                               ignore, BUILT_IN_NONE);
6713
      if (target)
6714
        return target;
6715
      break;
6716
 
6717
    case BUILT_IN_ATOMIC_FETCH_AND_1:
6718
    case BUILT_IN_ATOMIC_FETCH_AND_2:
6719
    case BUILT_IN_ATOMIC_FETCH_AND_4:
6720
    case BUILT_IN_ATOMIC_FETCH_AND_8:
6721
    case BUILT_IN_ATOMIC_FETCH_AND_16:
6722
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_AND_1);
6723
      target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, false,
6724
                                               ignore, BUILT_IN_NONE);
6725
      if (target)
6726
        return target;
6727
      break;
6728
 
6729
    case BUILT_IN_ATOMIC_FETCH_NAND_1:
6730
    case BUILT_IN_ATOMIC_FETCH_NAND_2:
6731
    case BUILT_IN_ATOMIC_FETCH_NAND_4:
6732
    case BUILT_IN_ATOMIC_FETCH_NAND_8:
6733
    case BUILT_IN_ATOMIC_FETCH_NAND_16:
6734
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_NAND_1);
6735
      target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, false,
6736
                                               ignore, BUILT_IN_NONE);
6737
      if (target)
6738
        return target;
6739
      break;
6740
 
6741
    case BUILT_IN_ATOMIC_FETCH_XOR_1:
6742
    case BUILT_IN_ATOMIC_FETCH_XOR_2:
6743
    case BUILT_IN_ATOMIC_FETCH_XOR_4:
6744
    case BUILT_IN_ATOMIC_FETCH_XOR_8:
6745
    case BUILT_IN_ATOMIC_FETCH_XOR_16:
6746
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_XOR_1);
6747
      target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, false,
6748
                                               ignore, BUILT_IN_NONE);
6749
      if (target)
6750
        return target;
6751
      break;
6752
 
6753
    case BUILT_IN_ATOMIC_FETCH_OR_1:
6754
    case BUILT_IN_ATOMIC_FETCH_OR_2:
6755
    case BUILT_IN_ATOMIC_FETCH_OR_4:
6756
    case BUILT_IN_ATOMIC_FETCH_OR_8:
6757
    case BUILT_IN_ATOMIC_FETCH_OR_16:
6758
      mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_OR_1);
6759
      target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, false,
6760
                                               ignore, BUILT_IN_NONE);
6761
      if (target)
6762
        return target;
6763
      break;
6764
 
6765
    case BUILT_IN_ATOMIC_TEST_AND_SET:
6766
      return expand_builtin_atomic_test_and_set (exp, target);
6767
 
6768
    case BUILT_IN_ATOMIC_CLEAR:
6769
      return expand_builtin_atomic_clear (exp);
6770
 
6771
    case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
6772
      return expand_builtin_atomic_always_lock_free (exp);
6773
 
6774
    case BUILT_IN_ATOMIC_IS_LOCK_FREE:
6775
      target = expand_builtin_atomic_is_lock_free (exp);
6776
      if (target)
6777
        return target;
6778
      break;
6779
 
6780
    case BUILT_IN_ATOMIC_THREAD_FENCE:
6781
      expand_builtin_atomic_thread_fence (exp);
6782
      return const0_rtx;
6783
 
6784
    case BUILT_IN_ATOMIC_SIGNAL_FENCE:
6785
      expand_builtin_atomic_signal_fence (exp);
6786
      return const0_rtx;
6787
 
6788
    case BUILT_IN_OBJECT_SIZE:
6789
      return expand_builtin_object_size (exp);
6790
 
6791
    case BUILT_IN_MEMCPY_CHK:
6792
    case BUILT_IN_MEMPCPY_CHK:
6793
    case BUILT_IN_MEMMOVE_CHK:
6794
    case BUILT_IN_MEMSET_CHK:
6795
      target = expand_builtin_memory_chk (exp, target, mode, fcode);
6796
      if (target)
6797
        return target;
6798
      break;
6799
 
6800
    case BUILT_IN_STRCPY_CHK:
6801
    case BUILT_IN_STPCPY_CHK:
6802
    case BUILT_IN_STRNCPY_CHK:
6803
    case BUILT_IN_STPNCPY_CHK:
6804
    case BUILT_IN_STRCAT_CHK:
6805
    case BUILT_IN_STRNCAT_CHK:
6806
    case BUILT_IN_SNPRINTF_CHK:
6807
    case BUILT_IN_VSNPRINTF_CHK:
6808
      maybe_emit_chk_warning (exp, fcode);
6809
      break;
6810
 
6811
    case BUILT_IN_SPRINTF_CHK:
6812
    case BUILT_IN_VSPRINTF_CHK:
6813
      maybe_emit_sprintf_chk_warning (exp, fcode);
6814
      break;
6815
 
6816
    case BUILT_IN_FREE:
6817
      if (warn_free_nonheap_object)
6818
        maybe_emit_free_warning (exp);
6819
      break;
6820
 
6821
    default:    /* just do library call, if unknown builtin */
6822
      break;
6823
    }
6824
 
6825
  /* The switch statement above can drop through to cause the function
6826
     to be called normally.  */
6827
  return expand_call (exp, target, ignore);
6828
}
6829
 
6830
/* Determine whether a tree node represents a call to a built-in
6831
   function.  If the tree T is a call to a built-in function with
6832
   the right number of arguments of the appropriate types, return
6833
   the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6834
   Otherwise the return value is END_BUILTINS.  */
6835
 
6836
enum built_in_function
6837
builtin_mathfn_code (const_tree t)
6838
{
6839
  const_tree fndecl, arg, parmlist;
6840
  const_tree argtype, parmtype;
6841
  const_call_expr_arg_iterator iter;
6842
 
6843
  if (TREE_CODE (t) != CALL_EXPR
6844
      || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6845
    return END_BUILTINS;
6846
 
6847
  fndecl = get_callee_fndecl (t);
6848
  if (fndecl == NULL_TREE
6849
      || TREE_CODE (fndecl) != FUNCTION_DECL
6850
      || ! DECL_BUILT_IN (fndecl)
6851
      || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6852
    return END_BUILTINS;
6853
 
6854
  parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6855
  init_const_call_expr_arg_iterator (t, &iter);
6856
  for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6857
    {
6858
      /* If a function doesn't take a variable number of arguments,
6859
         the last element in the list will have type `void'.  */
6860
      parmtype = TREE_VALUE (parmlist);
6861
      if (VOID_TYPE_P (parmtype))
6862
        {
6863
          if (more_const_call_expr_args_p (&iter))
6864
            return END_BUILTINS;
6865
          return DECL_FUNCTION_CODE (fndecl);
6866
        }
6867
 
6868
      if (! more_const_call_expr_args_p (&iter))
6869
        return END_BUILTINS;
6870
 
6871
      arg = next_const_call_expr_arg (&iter);
6872
      argtype = TREE_TYPE (arg);
6873
 
6874
      if (SCALAR_FLOAT_TYPE_P (parmtype))
6875
        {
6876
          if (! SCALAR_FLOAT_TYPE_P (argtype))
6877
            return END_BUILTINS;
6878
        }
6879
      else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6880
        {
6881
          if (! COMPLEX_FLOAT_TYPE_P (argtype))
6882
            return END_BUILTINS;
6883
        }
6884
      else if (POINTER_TYPE_P (parmtype))
6885
        {
6886
          if (! POINTER_TYPE_P (argtype))
6887
            return END_BUILTINS;
6888
        }
6889
      else if (INTEGRAL_TYPE_P (parmtype))
6890
        {
6891
          if (! INTEGRAL_TYPE_P (argtype))
6892
            return END_BUILTINS;
6893
        }
6894
      else
6895
        return END_BUILTINS;
6896
    }
6897
 
6898
  /* Variable-length argument list.  */
6899
  return DECL_FUNCTION_CODE (fndecl);
6900
}
6901
 
6902
/* Fold a call to __builtin_constant_p, if we know its argument ARG will
6903
   evaluate to a constant.  */
6904
 
6905
static tree
6906
fold_builtin_constant_p (tree arg)
6907
{
6908
  /* We return 1 for a numeric type that's known to be a constant
6909
     value at compile-time or for an aggregate type that's a
6910
     literal constant.  */
6911
  STRIP_NOPS (arg);
6912
 
6913
  /* If we know this is a constant, emit the constant of one.  */
6914
  if (CONSTANT_CLASS_P (arg)
6915
      || (TREE_CODE (arg) == CONSTRUCTOR
6916
          && TREE_CONSTANT (arg)))
6917
    return integer_one_node;
6918
  if (TREE_CODE (arg) == ADDR_EXPR)
6919
    {
6920
       tree op = TREE_OPERAND (arg, 0);
6921
       if (TREE_CODE (op) == STRING_CST
6922
           || (TREE_CODE (op) == ARRAY_REF
6923
               && integer_zerop (TREE_OPERAND (op, 1))
6924
               && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6925
         return integer_one_node;
6926
    }
6927
 
6928
  /* If this expression has side effects, show we don't know it to be a
6929
     constant.  Likewise if it's a pointer or aggregate type since in
6930
     those case we only want literals, since those are only optimized
6931
     when generating RTL, not later.
6932
     And finally, if we are compiling an initializer, not code, we
6933
     need to return a definite result now; there's not going to be any
6934
     more optimization done.  */
6935
  if (TREE_SIDE_EFFECTS (arg)
6936
      || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6937
      || POINTER_TYPE_P (TREE_TYPE (arg))
6938
      || cfun == 0
6939
      || folding_initializer)
6940
    return integer_zero_node;
6941
 
6942
  return NULL_TREE;
6943
}
6944
 
6945
/* Create builtin_expect with PRED and EXPECTED as its arguments and
6946
   return it as a truthvalue.  */
6947
 
6948
static tree
6949
build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
6950
{
6951
  tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
6952
 
6953
  fn = builtin_decl_explicit (BUILT_IN_EXPECT);
6954
  arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6955
  ret_type = TREE_TYPE (TREE_TYPE (fn));
6956
  pred_type = TREE_VALUE (arg_types);
6957
  expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6958
 
6959
  pred = fold_convert_loc (loc, pred_type, pred);
6960
  expected = fold_convert_loc (loc, expected_type, expected);
6961
  call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
6962
 
6963
  return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
6964
                 build_int_cst (ret_type, 0));
6965
}
6966
 
6967
/* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
6968
   NULL_TREE if no simplification is possible.  */
6969
 
6970
static tree
6971
fold_builtin_expect (location_t loc, tree arg0, tree arg1)
6972
{
6973
  tree inner, fndecl, inner_arg0;
6974
  enum tree_code code;
6975
 
6976
  /* Distribute the expected value over short-circuiting operators.
6977
     See through the cast from truthvalue_type_node to long.  */
6978
  inner_arg0 = arg0;
6979
  while (TREE_CODE (inner_arg0) == NOP_EXPR
6980
         && INTEGRAL_TYPE_P (TREE_TYPE (inner_arg0))
6981
         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner_arg0, 0))))
6982
    inner_arg0 = TREE_OPERAND (inner_arg0, 0);
6983
 
6984
  /* If this is a builtin_expect within a builtin_expect keep the
6985
     inner one.  See through a comparison against a constant.  It
6986
     might have been added to create a thruthvalue.  */
6987
  inner = inner_arg0;
6988
 
6989
  if (COMPARISON_CLASS_P (inner)
6990
      && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6991
    inner = TREE_OPERAND (inner, 0);
6992
 
6993
  if (TREE_CODE (inner) == CALL_EXPR
6994
      && (fndecl = get_callee_fndecl (inner))
6995
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
6996
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
6997
    return arg0;
6998
 
6999
  inner = inner_arg0;
7000
  code = TREE_CODE (inner);
7001
  if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7002
    {
7003
      tree op0 = TREE_OPERAND (inner, 0);
7004
      tree op1 = TREE_OPERAND (inner, 1);
7005
 
7006
      op0 = build_builtin_expect_predicate (loc, op0, arg1);
7007
      op1 = build_builtin_expect_predicate (loc, op1, arg1);
7008
      inner = build2 (code, TREE_TYPE (inner), op0, op1);
7009
 
7010
      return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
7011
    }
7012
 
7013
  /* If the argument isn't invariant then there's nothing else we can do.  */
7014
  if (!TREE_CONSTANT (inner_arg0))
7015
    return NULL_TREE;
7016
 
7017
  /* If we expect that a comparison against the argument will fold to
7018
     a constant return the constant.  In practice, this means a true
7019
     constant or the address of a non-weak symbol.  */
7020
  inner = inner_arg0;
7021
  STRIP_NOPS (inner);
7022
  if (TREE_CODE (inner) == ADDR_EXPR)
7023
    {
7024
      do
7025
        {
7026
          inner = TREE_OPERAND (inner, 0);
7027
        }
7028
      while (TREE_CODE (inner) == COMPONENT_REF
7029
             || TREE_CODE (inner) == ARRAY_REF);
7030
      if ((TREE_CODE (inner) == VAR_DECL
7031
           || TREE_CODE (inner) == FUNCTION_DECL)
7032
          && DECL_WEAK (inner))
7033
        return NULL_TREE;
7034
    }
7035
 
7036
  /* Otherwise, ARG0 already has the proper type for the return value.  */
7037
  return arg0;
7038
}
7039
 
7040
/* Fold a call to __builtin_classify_type with argument ARG.  */
7041
 
7042
static tree
7043
fold_builtin_classify_type (tree arg)
7044
{
7045
  if (arg == 0)
7046
    return build_int_cst (integer_type_node, no_type_class);
7047
 
7048
  return build_int_cst (integer_type_node, type_to_class (TREE_TYPE (arg)));
7049
}
7050
 
7051
/* Fold a call to __builtin_strlen with argument ARG.  */
7052
 
7053
static tree
7054
fold_builtin_strlen (location_t loc, tree type, tree arg)
7055
{
7056
  if (!validate_arg (arg, POINTER_TYPE))
7057
    return NULL_TREE;
7058
  else
7059
    {
7060
      tree len = c_strlen (arg, 0);
7061
 
7062
      if (len)
7063
        return fold_convert_loc (loc, type, len);
7064
 
7065
      return NULL_TREE;
7066
    }
7067
}
7068
 
7069
/* Fold a call to __builtin_inf or __builtin_huge_val.  */
7070
 
7071
static tree
7072
fold_builtin_inf (location_t loc, tree type, int warn)
7073
{
7074
  REAL_VALUE_TYPE real;
7075
 
7076
  /* __builtin_inff is intended to be usable to define INFINITY on all
7077
     targets.  If an infinity is not available, INFINITY expands "to a
7078
     positive constant of type float that overflows at translation
7079
     time", footnote "In this case, using INFINITY will violate the
7080
     constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7081
     Thus we pedwarn to ensure this constraint violation is
7082
     diagnosed.  */
7083
  if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7084
    pedwarn (loc, 0, "target format does not support infinity");
7085
 
7086
  real_inf (&real);
7087
  return build_real (type, real);
7088
}
7089
 
7090
/* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
7091
 
7092
static tree
7093
fold_builtin_nan (tree arg, tree type, int quiet)
7094
{
7095
  REAL_VALUE_TYPE real;
7096
  const char *str;
7097
 
7098
  if (!validate_arg (arg, POINTER_TYPE))
7099
    return NULL_TREE;
7100
  str = c_getstr (arg);
7101
  if (!str)
7102
    return NULL_TREE;
7103
 
7104
  if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7105
    return NULL_TREE;
7106
 
7107
  return build_real (type, real);
7108
}
7109
 
7110
/* Return true if the floating point expression T has an integer value.
7111
   We also allow +Inf, -Inf and NaN to be considered integer values.  */
7112
 
7113
static bool
7114
integer_valued_real_p (tree t)
7115
{
7116
  switch (TREE_CODE (t))
7117
    {
7118
    case FLOAT_EXPR:
7119
      return true;
7120
 
7121
    case ABS_EXPR:
7122
    case SAVE_EXPR:
7123
      return integer_valued_real_p (TREE_OPERAND (t, 0));
7124
 
7125
    case COMPOUND_EXPR:
7126
    case MODIFY_EXPR:
7127
    case BIND_EXPR:
7128
      return integer_valued_real_p (TREE_OPERAND (t, 1));
7129
 
7130
    case PLUS_EXPR:
7131
    case MINUS_EXPR:
7132
    case MULT_EXPR:
7133
    case MIN_EXPR:
7134
    case MAX_EXPR:
7135
      return integer_valued_real_p (TREE_OPERAND (t, 0))
7136
             && integer_valued_real_p (TREE_OPERAND (t, 1));
7137
 
7138
    case COND_EXPR:
7139
      return integer_valued_real_p (TREE_OPERAND (t, 1))
7140
             && integer_valued_real_p (TREE_OPERAND (t, 2));
7141
 
7142
    case REAL_CST:
7143
      return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7144
 
7145
    case NOP_EXPR:
7146
      {
7147
        tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7148
        if (TREE_CODE (type) == INTEGER_TYPE)
7149
          return true;
7150
        if (TREE_CODE (type) == REAL_TYPE)
7151
          return integer_valued_real_p (TREE_OPERAND (t, 0));
7152
        break;
7153
      }
7154
 
7155
    case CALL_EXPR:
7156
      switch (builtin_mathfn_code (t))
7157
        {
7158
        CASE_FLT_FN (BUILT_IN_CEIL):
7159
        CASE_FLT_FN (BUILT_IN_FLOOR):
7160
        CASE_FLT_FN (BUILT_IN_NEARBYINT):
7161
        CASE_FLT_FN (BUILT_IN_RINT):
7162
        CASE_FLT_FN (BUILT_IN_ROUND):
7163
        CASE_FLT_FN (BUILT_IN_TRUNC):
7164
          return true;
7165
 
7166
        CASE_FLT_FN (BUILT_IN_FMIN):
7167
        CASE_FLT_FN (BUILT_IN_FMAX):
7168
          return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7169
            && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7170
 
7171
        default:
7172
          break;
7173
        }
7174
      break;
7175
 
7176
    default:
7177
      break;
7178
    }
7179
  return false;
7180
}
7181
 
7182
/* FNDECL is assumed to be a builtin where truncation can be propagated
7183
   across (for instance floor((double)f) == (double)floorf (f).
7184
   Do the transformation for a call with argument ARG.  */
7185
 
7186
static tree
7187
fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
7188
{
7189
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7190
 
7191
  if (!validate_arg (arg, REAL_TYPE))
7192
    return NULL_TREE;
7193
 
7194
  /* Integer rounding functions are idempotent.  */
7195
  if (fcode == builtin_mathfn_code (arg))
7196
    return arg;
7197
 
7198
  /* If argument is already integer valued, and we don't need to worry
7199
     about setting errno, there's no need to perform rounding.  */
7200
  if (! flag_errno_math && integer_valued_real_p (arg))
7201
    return arg;
7202
 
7203
  if (optimize)
7204
    {
7205
      tree arg0 = strip_float_extensions (arg);
7206
      tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7207
      tree newtype = TREE_TYPE (arg0);
7208
      tree decl;
7209
 
7210
      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7211
          && (decl = mathfn_built_in (newtype, fcode)))
7212
        return fold_convert_loc (loc, ftype,
7213
                                 build_call_expr_loc (loc, decl, 1,
7214
                                                  fold_convert_loc (loc,
7215
                                                                    newtype,
7216
                                                                    arg0)));
7217
    }
7218
  return NULL_TREE;
7219
}
7220
 
7221
/* FNDECL is assumed to be builtin which can narrow the FP type of
7222
   the argument, for instance lround((double)f) -> lroundf (f).
7223
   Do the transformation for a call with argument ARG.  */
7224
 
7225
static tree
7226
fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
7227
{
7228
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7229
 
7230
  if (!validate_arg (arg, REAL_TYPE))
7231
    return NULL_TREE;
7232
 
7233
  /* If argument is already integer valued, and we don't need to worry
7234
     about setting errno, there's no need to perform rounding.  */
7235
  if (! flag_errno_math && integer_valued_real_p (arg))
7236
    return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7237
                        TREE_TYPE (TREE_TYPE (fndecl)), arg);
7238
 
7239
  if (optimize)
7240
    {
7241
      tree ftype = TREE_TYPE (arg);
7242
      tree arg0 = strip_float_extensions (arg);
7243
      tree newtype = TREE_TYPE (arg0);
7244
      tree decl;
7245
 
7246
      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7247
          && (decl = mathfn_built_in (newtype, fcode)))
7248
        return build_call_expr_loc (loc, decl, 1,
7249
                                fold_convert_loc (loc, newtype, arg0));
7250
    }
7251
 
7252
  /* Canonicalize iround (x) to lround (x) on ILP32 targets where
7253
     sizeof (int) == sizeof (long).  */
7254
  if (TYPE_PRECISION (integer_type_node)
7255
      == TYPE_PRECISION (long_integer_type_node))
7256
    {
7257
      tree newfn = NULL_TREE;
7258
      switch (fcode)
7259
        {
7260
        CASE_FLT_FN (BUILT_IN_ICEIL):
7261
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7262
          break;
7263
 
7264
        CASE_FLT_FN (BUILT_IN_IFLOOR):
7265
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7266
          break;
7267
 
7268
        CASE_FLT_FN (BUILT_IN_IROUND):
7269
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7270
          break;
7271
 
7272
        CASE_FLT_FN (BUILT_IN_IRINT):
7273
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7274
          break;
7275
 
7276
        default:
7277
          break;
7278
        }
7279
 
7280
      if (newfn)
7281
        {
7282
          tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7283
          return fold_convert_loc (loc,
7284
                                   TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7285
        }
7286
    }
7287
 
7288
  /* Canonicalize llround (x) to lround (x) on LP64 targets where
7289
     sizeof (long long) == sizeof (long).  */
7290
  if (TYPE_PRECISION (long_long_integer_type_node)
7291
      == TYPE_PRECISION (long_integer_type_node))
7292
    {
7293
      tree newfn = NULL_TREE;
7294
      switch (fcode)
7295
        {
7296
        CASE_FLT_FN (BUILT_IN_LLCEIL):
7297
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7298
          break;
7299
 
7300
        CASE_FLT_FN (BUILT_IN_LLFLOOR):
7301
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7302
          break;
7303
 
7304
        CASE_FLT_FN (BUILT_IN_LLROUND):
7305
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7306
          break;
7307
 
7308
        CASE_FLT_FN (BUILT_IN_LLRINT):
7309
          newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7310
          break;
7311
 
7312
        default:
7313
          break;
7314
        }
7315
 
7316
      if (newfn)
7317
        {
7318
          tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7319
          return fold_convert_loc (loc,
7320
                                   TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7321
        }
7322
    }
7323
 
7324
  return NULL_TREE;
7325
}
7326
 
7327
/* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7328
   return type.  Return NULL_TREE if no simplification can be made.  */
7329
 
7330
static tree
7331
fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
7332
{
7333
  tree res;
7334
 
7335
  if (!validate_arg (arg, COMPLEX_TYPE)
7336
      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7337
    return NULL_TREE;
7338
 
7339
  /* Calculate the result when the argument is a constant.  */
7340
  if (TREE_CODE (arg) == COMPLEX_CST
7341
      && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7342
                              type, mpfr_hypot)))
7343
    return res;
7344
 
7345
  if (TREE_CODE (arg) == COMPLEX_EXPR)
7346
    {
7347
      tree real = TREE_OPERAND (arg, 0);
7348
      tree imag = TREE_OPERAND (arg, 1);
7349
 
7350
      /* If either part is zero, cabs is fabs of the other.  */
7351
      if (real_zerop (real))
7352
        return fold_build1_loc (loc, ABS_EXPR, type, imag);
7353
      if (real_zerop (imag))
7354
        return fold_build1_loc (loc, ABS_EXPR, type, real);
7355
 
7356
      /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7357
      if (flag_unsafe_math_optimizations
7358
          && operand_equal_p (real, imag, OEP_PURE_SAME))
7359
        {
7360
          const REAL_VALUE_TYPE sqrt2_trunc
7361
            = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7362
          STRIP_NOPS (real);
7363
          return fold_build2_loc (loc, MULT_EXPR, type,
7364
                              fold_build1_loc (loc, ABS_EXPR, type, real),
7365
                              build_real (type, sqrt2_trunc));
7366
        }
7367
    }
7368
 
7369
  /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7370
  if (TREE_CODE (arg) == NEGATE_EXPR
7371
      || TREE_CODE (arg) == CONJ_EXPR)
7372
    return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
7373
 
7374
  /* Don't do this when optimizing for size.  */
7375
  if (flag_unsafe_math_optimizations
7376
      && optimize && optimize_function_for_speed_p (cfun))
7377
    {
7378
      tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7379
 
7380
      if (sqrtfn != NULL_TREE)
7381
        {
7382
          tree rpart, ipart, result;
7383
 
7384
          arg = builtin_save_expr (arg);
7385
 
7386
          rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7387
          ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
7388
 
7389
          rpart = builtin_save_expr (rpart);
7390
          ipart = builtin_save_expr (ipart);
7391
 
7392
          result = fold_build2_loc (loc, PLUS_EXPR, type,
7393
                                fold_build2_loc (loc, MULT_EXPR, type,
7394
                                             rpart, rpart),
7395
                                fold_build2_loc (loc, MULT_EXPR, type,
7396
                                             ipart, ipart));
7397
 
7398
          return build_call_expr_loc (loc, sqrtfn, 1, result);
7399
        }
7400
    }
7401
 
7402
  return NULL_TREE;
7403
}
7404
 
7405
/* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
7406
   complex tree type of the result.  If NEG is true, the imaginary
7407
   zero is negative.  */
7408
 
7409
static tree
7410
build_complex_cproj (tree type, bool neg)
7411
{
7412
  REAL_VALUE_TYPE rinf, rzero = dconst0;
7413
 
7414
  real_inf (&rinf);
7415
  rzero.sign = neg;
7416
  return build_complex (type, build_real (TREE_TYPE (type), rinf),
7417
                        build_real (TREE_TYPE (type), rzero));
7418
}
7419
 
7420
/* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is the
7421
   return type.  Return NULL_TREE if no simplification can be made.  */
7422
 
7423
static tree
7424
fold_builtin_cproj (location_t loc, tree arg, tree type)
7425
{
7426
  if (!validate_arg (arg, COMPLEX_TYPE)
7427
      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7428
    return NULL_TREE;
7429
 
7430
  /* If there are no infinities, return arg.  */
7431
  if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
7432
    return non_lvalue_loc (loc, arg);
7433
 
7434
  /* Calculate the result when the argument is a constant.  */
7435
  if (TREE_CODE (arg) == COMPLEX_CST)
7436
    {
7437
      const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
7438
      const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
7439
 
7440
      if (real_isinf (real) || real_isinf (imag))
7441
        return build_complex_cproj (type, imag->sign);
7442
      else
7443
        return arg;
7444
    }
7445
  else if (TREE_CODE (arg) == COMPLEX_EXPR)
7446
    {
7447
      tree real = TREE_OPERAND (arg, 0);
7448
      tree imag = TREE_OPERAND (arg, 1);
7449
 
7450
      STRIP_NOPS (real);
7451
      STRIP_NOPS (imag);
7452
 
7453
      /* If the real part is inf and the imag part is known to be
7454
         nonnegative, return (inf + 0i).  Remember side-effects are
7455
         possible in the imag part.  */
7456
      if (TREE_CODE (real) == REAL_CST
7457
          && real_isinf (TREE_REAL_CST_PTR (real))
7458
          && tree_expr_nonnegative_p (imag))
7459
        return omit_one_operand_loc (loc, type,
7460
                                     build_complex_cproj (type, false),
7461
                                     arg);
7462
 
7463
      /* If the imag part is inf, return (inf+I*copysign(0,imag)).
7464
         Remember side-effects are possible in the real part.  */
7465
      if (TREE_CODE (imag) == REAL_CST
7466
          && real_isinf (TREE_REAL_CST_PTR (imag)))
7467
        return
7468
          omit_one_operand_loc (loc, type,
7469
                                build_complex_cproj (type, TREE_REAL_CST_PTR
7470
                                                     (imag)->sign), arg);
7471
    }
7472
 
7473
  return NULL_TREE;
7474
}
7475
 
7476
/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7477
   Return NULL_TREE if no simplification can be made.  */
7478
 
7479
static tree
7480
fold_builtin_sqrt (location_t loc, tree arg, tree type)
7481
{
7482
 
7483
  enum built_in_function fcode;
7484
  tree res;
7485
 
7486
  if (!validate_arg (arg, REAL_TYPE))
7487
    return NULL_TREE;
7488
 
7489
  /* Calculate the result when the argument is a constant.  */
7490
  if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7491
    return res;
7492
 
7493
  /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7494
  fcode = builtin_mathfn_code (arg);
7495
  if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7496
    {
7497
      tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7498
      arg = fold_build2_loc (loc, MULT_EXPR, type,
7499
                         CALL_EXPR_ARG (arg, 0),
7500
                         build_real (type, dconsthalf));
7501
      return build_call_expr_loc (loc, expfn, 1, arg);
7502
    }
7503
 
7504
  /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7505
  if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7506
    {
7507
      tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7508
 
7509
      if (powfn)
7510
        {
7511
          tree arg0 = CALL_EXPR_ARG (arg, 0);
7512
          tree tree_root;
7513
          /* The inner root was either sqrt or cbrt.  */
7514
          /* This was a conditional expression but it triggered a bug
7515
             in Sun C 5.5.  */
7516
          REAL_VALUE_TYPE dconstroot;
7517
          if (BUILTIN_SQRT_P (fcode))
7518
            dconstroot = dconsthalf;
7519
          else
7520
            dconstroot = dconst_third ();
7521
 
7522
          /* Adjust for the outer root.  */
7523
          SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7524
          dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7525
          tree_root = build_real (type, dconstroot);
7526
          return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7527
        }
7528
    }
7529
 
7530
  /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7531
  if (flag_unsafe_math_optimizations
7532
      && (fcode == BUILT_IN_POW
7533
          || fcode == BUILT_IN_POWF
7534
          || fcode == BUILT_IN_POWL))
7535
    {
7536
      tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7537
      tree arg0 = CALL_EXPR_ARG (arg, 0);
7538
      tree arg1 = CALL_EXPR_ARG (arg, 1);
7539
      tree narg1;
7540
      if (!tree_expr_nonnegative_p (arg0))
7541
        arg0 = build1 (ABS_EXPR, type, arg0);
7542
      narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
7543
                           build_real (type, dconsthalf));
7544
      return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
7545
    }
7546
 
7547
  return NULL_TREE;
7548
}
7549
 
7550
/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7551
   Return NULL_TREE if no simplification can be made.  */
7552
 
7553
static tree
7554
fold_builtin_cbrt (location_t loc, tree arg, tree type)
7555
{
7556
  const enum built_in_function fcode = builtin_mathfn_code (arg);
7557
  tree res;
7558
 
7559
  if (!validate_arg (arg, REAL_TYPE))
7560
    return NULL_TREE;
7561
 
7562
  /* Calculate the result when the argument is a constant.  */
7563
  if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7564
    return res;
7565
 
7566
  if (flag_unsafe_math_optimizations)
7567
    {
7568
      /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7569
      if (BUILTIN_EXPONENT_P (fcode))
7570
        {
7571
          tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7572
          const REAL_VALUE_TYPE third_trunc =
7573
            real_value_truncate (TYPE_MODE (type), dconst_third ());
7574
          arg = fold_build2_loc (loc, MULT_EXPR, type,
7575
                             CALL_EXPR_ARG (arg, 0),
7576
                             build_real (type, third_trunc));
7577
          return build_call_expr_loc (loc, expfn, 1, arg);
7578
        }
7579
 
7580
      /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7581
      if (BUILTIN_SQRT_P (fcode))
7582
        {
7583
          tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7584
 
7585
          if (powfn)
7586
            {
7587
              tree arg0 = CALL_EXPR_ARG (arg, 0);
7588
              tree tree_root;
7589
              REAL_VALUE_TYPE dconstroot = dconst_third ();
7590
 
7591
              SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7592
              dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7593
              tree_root = build_real (type, dconstroot);
7594
              return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7595
            }
7596
        }
7597
 
7598
      /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7599
      if (BUILTIN_CBRT_P (fcode))
7600
        {
7601
          tree arg0 = CALL_EXPR_ARG (arg, 0);
7602
          if (tree_expr_nonnegative_p (arg0))
7603
            {
7604
              tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7605
 
7606
              if (powfn)
7607
                {
7608
                  tree tree_root;
7609
                  REAL_VALUE_TYPE dconstroot;
7610
 
7611
                  real_arithmetic (&dconstroot, MULT_EXPR,
7612
                                   dconst_third_ptr (), dconst_third_ptr ());
7613
                  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7614
                  tree_root = build_real (type, dconstroot);
7615
                  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7616
                }
7617
            }
7618
        }
7619
 
7620
      /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7621
      if (fcode == BUILT_IN_POW
7622
          || fcode == BUILT_IN_POWF
7623
          || fcode == BUILT_IN_POWL)
7624
        {
7625
          tree arg00 = CALL_EXPR_ARG (arg, 0);
7626
          tree arg01 = CALL_EXPR_ARG (arg, 1);
7627
          if (tree_expr_nonnegative_p (arg00))
7628
            {
7629
              tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7630
              const REAL_VALUE_TYPE dconstroot
7631
                = real_value_truncate (TYPE_MODE (type), dconst_third ());
7632
              tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
7633
                                         build_real (type, dconstroot));
7634
              return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
7635
            }
7636
        }
7637
    }
7638
  return NULL_TREE;
7639
}
7640
 
7641
/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7642
   TYPE is the type of the return value.  Return NULL_TREE if no
7643
   simplification can be made.  */
7644
 
7645
static tree
7646
fold_builtin_cos (location_t loc,
7647
                  tree arg, tree type, tree fndecl)
7648
{
7649
  tree res, narg;
7650
 
7651
  if (!validate_arg (arg, REAL_TYPE))
7652
    return NULL_TREE;
7653
 
7654
  /* Calculate the result when the argument is a constant.  */
7655
  if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7656
    return res;
7657
 
7658
  /* Optimize cos(-x) into cos (x).  */
7659
  if ((narg = fold_strip_sign_ops (arg)))
7660
    return build_call_expr_loc (loc, fndecl, 1, narg);
7661
 
7662
  return NULL_TREE;
7663
}
7664
 
7665
/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7666
   Return NULL_TREE if no simplification can be made.  */
7667
 
7668
static tree
7669
fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
7670
{
7671
  if (validate_arg (arg, REAL_TYPE))
7672
    {
7673
      tree res, narg;
7674
 
7675
      /* Calculate the result when the argument is a constant.  */
7676
      if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7677
        return res;
7678
 
7679
      /* Optimize cosh(-x) into cosh (x).  */
7680
      if ((narg = fold_strip_sign_ops (arg)))
7681
        return build_call_expr_loc (loc, fndecl, 1, narg);
7682
    }
7683
 
7684
  return NULL_TREE;
7685
}
7686
 
7687
/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7688
   argument ARG.  TYPE is the type of the return value.  Return
7689
   NULL_TREE if no simplification can be made.  */
7690
 
7691
static tree
7692
fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl,
7693
                   bool hyper)
7694
{
7695
  if (validate_arg (arg, COMPLEX_TYPE)
7696
      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7697
    {
7698
      tree tmp;
7699
 
7700
      /* Calculate the result when the argument is a constant.  */
7701
      if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7702
        return tmp;
7703
 
7704
      /* Optimize fn(-x) into fn(x).  */
7705
      if ((tmp = fold_strip_sign_ops (arg)))
7706
        return build_call_expr_loc (loc, fndecl, 1, tmp);
7707
    }
7708
 
7709
  return NULL_TREE;
7710
}
7711
 
7712
/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7713
   Return NULL_TREE if no simplification can be made.  */
7714
 
7715
static tree
7716
fold_builtin_tan (tree arg, tree type)
7717
{
7718
  enum built_in_function fcode;
7719
  tree res;
7720
 
7721
  if (!validate_arg (arg, REAL_TYPE))
7722
    return NULL_TREE;
7723
 
7724
  /* Calculate the result when the argument is a constant.  */
7725
  if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7726
    return res;
7727
 
7728
  /* Optimize tan(atan(x)) = x.  */
7729
  fcode = builtin_mathfn_code (arg);
7730
  if (flag_unsafe_math_optimizations
7731
      && (fcode == BUILT_IN_ATAN
7732
          || fcode == BUILT_IN_ATANF
7733
          || fcode == BUILT_IN_ATANL))
7734
    return CALL_EXPR_ARG (arg, 0);
7735
 
7736
  return NULL_TREE;
7737
}
7738
 
7739
/* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7740
   NULL_TREE if no simplification can be made.  */
7741
 
7742
static tree
7743
fold_builtin_sincos (location_t loc,
7744
                     tree arg0, tree arg1, tree arg2)
7745
{
7746
  tree type;
7747
  tree res, fn, call;
7748
 
7749
  if (!validate_arg (arg0, REAL_TYPE)
7750
      || !validate_arg (arg1, POINTER_TYPE)
7751
      || !validate_arg (arg2, POINTER_TYPE))
7752
    return NULL_TREE;
7753
 
7754
  type = TREE_TYPE (arg0);
7755
 
7756
  /* Calculate the result when the argument is a constant.  */
7757
  if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7758
    return res;
7759
 
7760
  /* Canonicalize sincos to cexpi.  */
7761
  if (!TARGET_C99_FUNCTIONS)
7762
    return NULL_TREE;
7763
  fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7764
  if (!fn)
7765
    return NULL_TREE;
7766
 
7767
  call = build_call_expr_loc (loc, fn, 1, arg0);
7768
  call = builtin_save_expr (call);
7769
 
7770
  return build2 (COMPOUND_EXPR, void_type_node,
7771
                 build2 (MODIFY_EXPR, void_type_node,
7772
                         build_fold_indirect_ref_loc (loc, arg1),
7773
                         build1 (IMAGPART_EXPR, type, call)),
7774
                 build2 (MODIFY_EXPR, void_type_node,
7775
                         build_fold_indirect_ref_loc (loc, arg2),
7776
                         build1 (REALPART_EXPR, type, call)));
7777
}
7778
 
7779
/* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7780
   NULL_TREE if no simplification can be made.  */
7781
 
7782
static tree
7783
fold_builtin_cexp (location_t loc, tree arg0, tree type)
7784
{
7785
  tree rtype;
7786
  tree realp, imagp, ifn;
7787
  tree res;
7788
 
7789
  if (!validate_arg (arg0, COMPLEX_TYPE)
7790
      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
7791
    return NULL_TREE;
7792
 
7793
  /* Calculate the result when the argument is a constant.  */
7794
  if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7795
    return res;
7796
 
7797
  rtype = TREE_TYPE (TREE_TYPE (arg0));
7798
 
7799
  /* In case we can figure out the real part of arg0 and it is constant zero
7800
     fold to cexpi.  */
7801
  if (!TARGET_C99_FUNCTIONS)
7802
    return NULL_TREE;
7803
  ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7804
  if (!ifn)
7805
    return NULL_TREE;
7806
 
7807
  if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
7808
      && real_zerop (realp))
7809
    {
7810
      tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7811
      return build_call_expr_loc (loc, ifn, 1, narg);
7812
    }
7813
 
7814
  /* In case we can easily decompose real and imaginary parts split cexp
7815
     to exp (r) * cexpi (i).  */
7816
  if (flag_unsafe_math_optimizations
7817
      && realp)
7818
    {
7819
      tree rfn, rcall, icall;
7820
 
7821
      rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7822
      if (!rfn)
7823
        return NULL_TREE;
7824
 
7825
      imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
7826
      if (!imagp)
7827
        return NULL_TREE;
7828
 
7829
      icall = build_call_expr_loc (loc, ifn, 1, imagp);
7830
      icall = builtin_save_expr (icall);
7831
      rcall = build_call_expr_loc (loc, rfn, 1, realp);
7832
      rcall = builtin_save_expr (rcall);
7833
      return fold_build2_loc (loc, COMPLEX_EXPR, type,
7834
                          fold_build2_loc (loc, MULT_EXPR, rtype,
7835
                                       rcall,
7836
                                       fold_build1_loc (loc, REALPART_EXPR,
7837
                                                    rtype, icall)),
7838
                          fold_build2_loc (loc, MULT_EXPR, rtype,
7839
                                       rcall,
7840
                                       fold_build1_loc (loc, IMAGPART_EXPR,
7841
                                                    rtype, icall)));
7842
    }
7843
 
7844
  return NULL_TREE;
7845
}
7846
 
7847
/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7848
   Return NULL_TREE if no simplification can be made.  */
7849
 
7850
static tree
7851
fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
7852
{
7853
  if (!validate_arg (arg, REAL_TYPE))
7854
    return NULL_TREE;
7855
 
7856
  /* Optimize trunc of constant value.  */
7857
  if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7858
    {
7859
      REAL_VALUE_TYPE r, x;
7860
      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7861
 
7862
      x = TREE_REAL_CST (arg);
7863
      real_trunc (&r, TYPE_MODE (type), &x);
7864
      return build_real (type, r);
7865
    }
7866
 
7867
  return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7868
}
7869
 
7870
/* Fold function call to builtin floor, floorf or floorl with argument ARG.
7871
   Return NULL_TREE if no simplification can be made.  */
7872
 
7873
static tree
7874
fold_builtin_floor (location_t loc, tree fndecl, tree arg)
7875
{
7876
  if (!validate_arg (arg, REAL_TYPE))
7877
    return NULL_TREE;
7878
 
7879
  /* Optimize floor of constant value.  */
7880
  if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7881
    {
7882
      REAL_VALUE_TYPE x;
7883
 
7884
      x = TREE_REAL_CST (arg);
7885
      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7886
        {
7887
          tree type = TREE_TYPE (TREE_TYPE (fndecl));
7888
          REAL_VALUE_TYPE r;
7889
 
7890
          real_floor (&r, TYPE_MODE (type), &x);
7891
          return build_real (type, r);
7892
        }
7893
    }
7894
 
7895
  /* Fold floor (x) where x is nonnegative to trunc (x).  */
7896
  if (tree_expr_nonnegative_p (arg))
7897
    {
7898
      tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7899
      if (truncfn)
7900
        return build_call_expr_loc (loc, truncfn, 1, arg);
7901
    }
7902
 
7903
  return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7904
}
7905
 
7906
/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7907
   Return NULL_TREE if no simplification can be made.  */
7908
 
7909
static tree
7910
fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
7911
{
7912
  if (!validate_arg (arg, REAL_TYPE))
7913
    return NULL_TREE;
7914
 
7915
  /* Optimize ceil of constant value.  */
7916
  if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7917
    {
7918
      REAL_VALUE_TYPE x;
7919
 
7920
      x = TREE_REAL_CST (arg);
7921
      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7922
        {
7923
          tree type = TREE_TYPE (TREE_TYPE (fndecl));
7924
          REAL_VALUE_TYPE r;
7925
 
7926
          real_ceil (&r, TYPE_MODE (type), &x);
7927
          return build_real (type, r);
7928
        }
7929
    }
7930
 
7931
  return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7932
}
7933
 
7934
/* Fold function call to builtin round, roundf or roundl with argument ARG.
7935
   Return NULL_TREE if no simplification can be made.  */
7936
 
7937
static tree
7938
fold_builtin_round (location_t loc, tree fndecl, tree arg)
7939
{
7940
  if (!validate_arg (arg, REAL_TYPE))
7941
    return NULL_TREE;
7942
 
7943
  /* Optimize round of constant value.  */
7944
  if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7945
    {
7946
      REAL_VALUE_TYPE x;
7947
 
7948
      x = TREE_REAL_CST (arg);
7949
      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7950
        {
7951
          tree type = TREE_TYPE (TREE_TYPE (fndecl));
7952
          REAL_VALUE_TYPE r;
7953
 
7954
          real_round (&r, TYPE_MODE (type), &x);
7955
          return build_real (type, r);
7956
        }
7957
    }
7958
 
7959
  return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7960
}
7961
 
7962
/* Fold function call to builtin lround, lroundf or lroundl (or the
7963
   corresponding long long versions) and other rounding functions.  ARG
7964
   is the argument to the call.  Return NULL_TREE if no simplification
7965
   can be made.  */
7966
 
7967
static tree
7968
fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
7969
{
7970
  if (!validate_arg (arg, REAL_TYPE))
7971
    return NULL_TREE;
7972
 
7973
  /* Optimize lround of constant value.  */
7974
  if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7975
    {
7976
      const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7977
 
7978
      if (real_isfinite (&x))
7979
        {
7980
          tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7981
          tree ftype = TREE_TYPE (arg);
7982
          double_int val;
7983
          REAL_VALUE_TYPE r;
7984
 
7985
          switch (DECL_FUNCTION_CODE (fndecl))
7986
            {
7987
            CASE_FLT_FN (BUILT_IN_IFLOOR):
7988
            CASE_FLT_FN (BUILT_IN_LFLOOR):
7989
            CASE_FLT_FN (BUILT_IN_LLFLOOR):
7990
              real_floor (&r, TYPE_MODE (ftype), &x);
7991
              break;
7992
 
7993
            CASE_FLT_FN (BUILT_IN_ICEIL):
7994
            CASE_FLT_FN (BUILT_IN_LCEIL):
7995
            CASE_FLT_FN (BUILT_IN_LLCEIL):
7996
              real_ceil (&r, TYPE_MODE (ftype), &x);
7997
              break;
7998
 
7999
            CASE_FLT_FN (BUILT_IN_IROUND):
8000
            CASE_FLT_FN (BUILT_IN_LROUND):
8001
            CASE_FLT_FN (BUILT_IN_LLROUND):
8002
              real_round (&r, TYPE_MODE (ftype), &x);
8003
              break;
8004
 
8005
            default:
8006
              gcc_unreachable ();
8007
            }
8008
 
8009
          real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
8010
          if (double_int_fits_to_tree_p (itype, val))
8011
            return double_int_to_tree (itype, val);
8012
        }
8013
    }
8014
 
8015
  switch (DECL_FUNCTION_CODE (fndecl))
8016
    {
8017
    CASE_FLT_FN (BUILT_IN_LFLOOR):
8018
    CASE_FLT_FN (BUILT_IN_LLFLOOR):
8019
      /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
8020
      if (tree_expr_nonnegative_p (arg))
8021
        return fold_build1_loc (loc, FIX_TRUNC_EXPR,
8022
                            TREE_TYPE (TREE_TYPE (fndecl)), arg);
8023
      break;
8024
    default:;
8025
    }
8026
 
8027
  return fold_fixed_mathfn (loc, fndecl, arg);
8028
}
8029
 
8030
/* Fold function call to builtin ffs, clz, ctz, popcount and parity
8031
   and their long and long long variants (i.e. ffsl and ffsll).  ARG is
8032
   the argument to the call.  Return NULL_TREE if no simplification can
8033
   be made.  */
8034
 
8035
static tree
8036
fold_builtin_bitop (tree fndecl, tree arg)
8037
{
8038
  if (!validate_arg (arg, INTEGER_TYPE))
8039
    return NULL_TREE;
8040
 
8041
  /* Optimize for constant argument.  */
8042
  if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8043
    {
8044
      HOST_WIDE_INT hi, width, result;
8045
      unsigned HOST_WIDE_INT lo;
8046
      tree type;
8047
 
8048
      type = TREE_TYPE (arg);
8049
      width = TYPE_PRECISION (type);
8050
      lo = TREE_INT_CST_LOW (arg);
8051
 
8052
      /* Clear all the bits that are beyond the type's precision.  */
8053
      if (width > HOST_BITS_PER_WIDE_INT)
8054
        {
8055
          hi = TREE_INT_CST_HIGH (arg);
8056
          if (width < 2 * HOST_BITS_PER_WIDE_INT)
8057
            hi &= ~((unsigned HOST_WIDE_INT) (-1)
8058
                    << (width - HOST_BITS_PER_WIDE_INT));
8059
        }
8060
      else
8061
        {
8062
          hi = 0;
8063
          if (width < HOST_BITS_PER_WIDE_INT)
8064
            lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8065
        }
8066
 
8067
      switch (DECL_FUNCTION_CODE (fndecl))
8068
        {
8069
        CASE_INT_FN (BUILT_IN_FFS):
8070
          if (lo != 0)
8071
            result = ffs_hwi (lo);
8072
          else if (hi != 0)
8073
            result = HOST_BITS_PER_WIDE_INT + ffs_hwi (hi);
8074
          else
8075
            result = 0;
8076
          break;
8077
 
8078
        CASE_INT_FN (BUILT_IN_CLZ):
8079
          if (hi != 0)
8080
            result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8081
          else if (lo != 0)
8082
            result = width - floor_log2 (lo) - 1;
8083
          else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8084
            result = width;
8085
          break;
8086
 
8087
        CASE_INT_FN (BUILT_IN_CTZ):
8088
          if (lo != 0)
8089
            result = ctz_hwi (lo);
8090
          else if (hi != 0)
8091
            result = HOST_BITS_PER_WIDE_INT + ctz_hwi (hi);
8092
          else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8093
            result = width;
8094
          break;
8095
 
8096
        CASE_INT_FN (BUILT_IN_CLRSB):
8097
          if (width > HOST_BITS_PER_WIDE_INT
8098
              && (hi & ((unsigned HOST_WIDE_INT) 1
8099
                        << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
8100
            {
8101
              hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
8102
                           << (width - HOST_BITS_PER_WIDE_INT - 1));
8103
              lo = ~lo;
8104
            }
8105
          else if (width <= HOST_BITS_PER_WIDE_INT
8106
                   && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
8107
            lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
8108
          if (hi != 0)
8109
            result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
8110
          else if (lo != 0)
8111
            result = width - floor_log2 (lo) - 2;
8112
          else
8113
            result = width - 1;
8114
          break;
8115
 
8116
        CASE_INT_FN (BUILT_IN_POPCOUNT):
8117
          result = 0;
8118
          while (lo)
8119
            result++, lo &= lo - 1;
8120
          while (hi)
8121
            result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8122
          break;
8123
 
8124
        CASE_INT_FN (BUILT_IN_PARITY):
8125
          result = 0;
8126
          while (lo)
8127
            result++, lo &= lo - 1;
8128
          while (hi)
8129
            result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8130
          result &= 1;
8131
          break;
8132
 
8133
        default:
8134
          gcc_unreachable ();
8135
        }
8136
 
8137
      return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8138
    }
8139
 
8140
  return NULL_TREE;
8141
}
8142
 
8143
/* Fold function call to builtin_bswap and the long and long long
8144
   variants.  Return NULL_TREE if no simplification can be made.  */
8145
static tree
8146
fold_builtin_bswap (tree fndecl, tree arg)
8147
{
8148
  if (! validate_arg (arg, INTEGER_TYPE))
8149
    return NULL_TREE;
8150
 
8151
  /* Optimize constant value.  */
8152
  if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8153
    {
8154
      HOST_WIDE_INT hi, width, r_hi = 0;
8155
      unsigned HOST_WIDE_INT lo, r_lo = 0;
8156
      tree type;
8157
 
8158
      type = TREE_TYPE (arg);
8159
      width = TYPE_PRECISION (type);
8160
      lo = TREE_INT_CST_LOW (arg);
8161
      hi = TREE_INT_CST_HIGH (arg);
8162
 
8163
      switch (DECL_FUNCTION_CODE (fndecl))
8164
        {
8165
          case BUILT_IN_BSWAP32:
8166
          case BUILT_IN_BSWAP64:
8167
            {
8168
              int s;
8169
 
8170
              for (s = 0; s < width; s += 8)
8171
                {
8172
                  int d = width - s - 8;
8173
                  unsigned HOST_WIDE_INT byte;
8174
 
8175
                  if (s < HOST_BITS_PER_WIDE_INT)
8176
                    byte = (lo >> s) & 0xff;
8177
                  else
8178
                    byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8179
 
8180
                  if (d < HOST_BITS_PER_WIDE_INT)
8181
                    r_lo |= byte << d;
8182
                  else
8183
                    r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8184
                }
8185
            }
8186
 
8187
            break;
8188
 
8189
        default:
8190
          gcc_unreachable ();
8191
        }
8192
 
8193
      if (width < HOST_BITS_PER_WIDE_INT)
8194
        return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8195
      else
8196
        return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8197
    }
8198
 
8199
  return NULL_TREE;
8200
}
8201
 
8202
/* A subroutine of fold_builtin to fold the various logarithmic
8203
   functions.  Return NULL_TREE if no simplification can me made.
8204
   FUNC is the corresponding MPFR logarithm function.  */
8205
 
8206
static tree
8207
fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
8208
                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8209
{
8210
  if (validate_arg (arg, REAL_TYPE))
8211
    {
8212
      tree type = TREE_TYPE (TREE_TYPE (fndecl));
8213
      tree res;
8214
      const enum built_in_function fcode = builtin_mathfn_code (arg);
8215
 
8216
      /* Calculate the result when the argument is a constant.  */
8217
      if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8218
        return res;
8219
 
8220
      /* Special case, optimize logN(expN(x)) = x.  */
8221
      if (flag_unsafe_math_optimizations
8222
          && ((func == mpfr_log
8223
               && (fcode == BUILT_IN_EXP
8224
                   || fcode == BUILT_IN_EXPF
8225
                   || fcode == BUILT_IN_EXPL))
8226
              || (func == mpfr_log2
8227
                  && (fcode == BUILT_IN_EXP2
8228
                      || fcode == BUILT_IN_EXP2F
8229
                      || fcode == BUILT_IN_EXP2L))
8230
              || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8231
        return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8232
 
8233
      /* Optimize logN(func()) for various exponential functions.  We
8234
         want to determine the value "x" and the power "exponent" in
8235
         order to transform logN(x**exponent) into exponent*logN(x).  */
8236
      if (flag_unsafe_math_optimizations)
8237
        {
8238
          tree exponent = 0, x = 0;
8239
 
8240
          switch (fcode)
8241
          {
8242
          CASE_FLT_FN (BUILT_IN_EXP):
8243
            /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8244
            x = build_real (type, real_value_truncate (TYPE_MODE (type),
8245
                                                       dconst_e ()));
8246
            exponent = CALL_EXPR_ARG (arg, 0);
8247
            break;
8248
          CASE_FLT_FN (BUILT_IN_EXP2):
8249
            /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8250
            x = build_real (type, dconst2);
8251
            exponent = CALL_EXPR_ARG (arg, 0);
8252
            break;
8253
          CASE_FLT_FN (BUILT_IN_EXP10):
8254
          CASE_FLT_FN (BUILT_IN_POW10):
8255
            /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8256
            {
8257
              REAL_VALUE_TYPE dconst10;
8258
              real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8259
              x = build_real (type, dconst10);
8260
            }
8261
            exponent = CALL_EXPR_ARG (arg, 0);
8262
            break;
8263
          CASE_FLT_FN (BUILT_IN_SQRT):
8264
            /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8265
            x = CALL_EXPR_ARG (arg, 0);
8266
            exponent = build_real (type, dconsthalf);
8267
            break;
8268
          CASE_FLT_FN (BUILT_IN_CBRT):
8269
            /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8270
            x = CALL_EXPR_ARG (arg, 0);
8271
            exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8272
                                                              dconst_third ()));
8273
            break;
8274
          CASE_FLT_FN (BUILT_IN_POW):
8275
            /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8276
            x = CALL_EXPR_ARG (arg, 0);
8277
            exponent = CALL_EXPR_ARG (arg, 1);
8278
            break;
8279
          default:
8280
            break;
8281
          }
8282
 
8283
          /* Now perform the optimization.  */
8284
          if (x && exponent)
8285
            {
8286
              tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8287
              return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8288
            }
8289
        }
8290
    }
8291
 
8292
  return NULL_TREE;
8293
}
8294
 
8295
/* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8296
   NULL_TREE if no simplification can be made.  */
8297
 
8298
static tree
8299
fold_builtin_hypot (location_t loc, tree fndecl,
8300
                    tree arg0, tree arg1, tree type)
8301
{
8302
  tree res, narg0, narg1;
8303
 
8304
  if (!validate_arg (arg0, REAL_TYPE)
8305
      || !validate_arg (arg1, REAL_TYPE))
8306
    return NULL_TREE;
8307
 
8308
  /* Calculate the result when the argument is a constant.  */
8309
  if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8310
    return res;
8311
 
8312
  /* If either argument to hypot has a negate or abs, strip that off.
8313
     E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8314
  narg0 = fold_strip_sign_ops (arg0);
8315
  narg1 = fold_strip_sign_ops (arg1);
8316
  if (narg0 || narg1)
8317
    {
8318
      return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
8319
                              narg1 ? narg1 : arg1);
8320
    }
8321
 
8322
  /* If either argument is zero, hypot is fabs of the other.  */
8323
  if (real_zerop (arg0))
8324
    return fold_build1_loc (loc, ABS_EXPR, type, arg1);
8325
  else if (real_zerop (arg1))
8326
    return fold_build1_loc (loc, ABS_EXPR, type, arg0);
8327
 
8328
  /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8329
  if (flag_unsafe_math_optimizations
8330
      && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8331
    {
8332
      const REAL_VALUE_TYPE sqrt2_trunc
8333
        = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8334
      return fold_build2_loc (loc, MULT_EXPR, type,
8335
                          fold_build1_loc (loc, ABS_EXPR, type, arg0),
8336
                          build_real (type, sqrt2_trunc));
8337
    }
8338
 
8339
  return NULL_TREE;
8340
}
8341
 
8342
 
8343
/* Fold a builtin function call to pow, powf, or powl.  Return
8344
   NULL_TREE if no simplification can be made.  */
8345
static tree
8346
fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
8347
{
8348
  tree res;
8349
 
8350
  if (!validate_arg (arg0, REAL_TYPE)
8351
       || !validate_arg (arg1, REAL_TYPE))
8352
    return NULL_TREE;
8353
 
8354
  /* Calculate the result when the argument is a constant.  */
8355
  if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8356
    return res;
8357
 
8358
  /* Optimize pow(1.0,y) = 1.0.  */
8359
  if (real_onep (arg0))
8360
    return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8361
 
8362
  if (TREE_CODE (arg1) == REAL_CST
8363
      && !TREE_OVERFLOW (arg1))
8364
    {
8365
      REAL_VALUE_TYPE cint;
8366
      REAL_VALUE_TYPE c;
8367
      HOST_WIDE_INT n;
8368
 
8369
      c = TREE_REAL_CST (arg1);
8370
 
8371
      /* Optimize pow(x,0.0) = 1.0.  */
8372
      if (REAL_VALUES_EQUAL (c, dconst0))
8373
        return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8374
                                 arg0);
8375
 
8376
      /* Optimize pow(x,1.0) = x.  */
8377
      if (REAL_VALUES_EQUAL (c, dconst1))
8378
        return arg0;
8379
 
8380
      /* Optimize pow(x,-1.0) = 1.0/x.  */
8381
      if (REAL_VALUES_EQUAL (c, dconstm1))
8382
        return fold_build2_loc (loc, RDIV_EXPR, type,
8383
                            build_real (type, dconst1), arg0);
8384
 
8385
      /* Optimize pow(x,0.5) = sqrt(x).  */
8386
      if (flag_unsafe_math_optimizations
8387
          && REAL_VALUES_EQUAL (c, dconsthalf))
8388
        {
8389
          tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8390
 
8391
          if (sqrtfn != NULL_TREE)
8392
            return build_call_expr_loc (loc, sqrtfn, 1, arg0);
8393
        }
8394
 
8395
      /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8396
      if (flag_unsafe_math_optimizations)
8397
        {
8398
          const REAL_VALUE_TYPE dconstroot
8399
            = real_value_truncate (TYPE_MODE (type), dconst_third ());
8400
 
8401
          if (REAL_VALUES_EQUAL (c, dconstroot))
8402
            {
8403
              tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8404
              if (cbrtfn != NULL_TREE)
8405
                return build_call_expr_loc (loc, cbrtfn, 1, arg0);
8406
            }
8407
        }
8408
 
8409
      /* Check for an integer exponent.  */
8410
      n = real_to_integer (&c);
8411
      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8412
      if (real_identical (&c, &cint))
8413
        {
8414
          /* Attempt to evaluate pow at compile-time, unless this should
8415
             raise an exception.  */
8416
          if (TREE_CODE (arg0) == REAL_CST
8417
              && !TREE_OVERFLOW (arg0)
8418
              && (n > 0
8419
                  || (!flag_trapping_math && !flag_errno_math)
8420
                  || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8421
            {
8422
              REAL_VALUE_TYPE x;
8423
              bool inexact;
8424
 
8425
              x = TREE_REAL_CST (arg0);
8426
              inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8427
              if (flag_unsafe_math_optimizations || !inexact)
8428
                return build_real (type, x);
8429
            }
8430
 
8431
          /* Strip sign ops from even integer powers.  */
8432
          if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8433
            {
8434
              tree narg0 = fold_strip_sign_ops (arg0);
8435
              if (narg0)
8436
                return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
8437
            }
8438
        }
8439
    }
8440
 
8441
  if (flag_unsafe_math_optimizations)
8442
    {
8443
      const enum built_in_function fcode = builtin_mathfn_code (arg0);
8444
 
8445
      /* Optimize pow(expN(x),y) = expN(x*y).  */
8446
      if (BUILTIN_EXPONENT_P (fcode))
8447
        {
8448
          tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8449
          tree arg = CALL_EXPR_ARG (arg0, 0);
8450
          arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8451
          return build_call_expr_loc (loc, expfn, 1, arg);
8452
        }
8453
 
8454
      /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8455
      if (BUILTIN_SQRT_P (fcode))
8456
        {
8457
          tree narg0 = CALL_EXPR_ARG (arg0, 0);
8458
          tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8459
                                    build_real (type, dconsthalf));
8460
          return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
8461
        }
8462
 
8463
      /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8464
      if (BUILTIN_CBRT_P (fcode))
8465
        {
8466
          tree arg = CALL_EXPR_ARG (arg0, 0);
8467
          if (tree_expr_nonnegative_p (arg))
8468
            {
8469
              const REAL_VALUE_TYPE dconstroot
8470
                = real_value_truncate (TYPE_MODE (type), dconst_third ());
8471
              tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8472
                                        build_real (type, dconstroot));
8473
              return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
8474
            }
8475
        }
8476
 
8477
      /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative.  */
8478
      if (fcode == BUILT_IN_POW
8479
          || fcode == BUILT_IN_POWF
8480
          || fcode == BUILT_IN_POWL)
8481
        {
8482
          tree arg00 = CALL_EXPR_ARG (arg0, 0);
8483
          if (tree_expr_nonnegative_p (arg00))
8484
            {
8485
              tree arg01 = CALL_EXPR_ARG (arg0, 1);
8486
              tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8487
              return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8488
            }
8489
        }
8490
    }
8491
 
8492
  return NULL_TREE;
8493
}
8494
 
8495
/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8496
   Return NULL_TREE if no simplification can be made.  */
8497
static tree
8498
fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
8499
                   tree arg0, tree arg1, tree type)
8500
{
8501
  if (!validate_arg (arg0, REAL_TYPE)
8502
      || !validate_arg (arg1, INTEGER_TYPE))
8503
    return NULL_TREE;
8504
 
8505
  /* Optimize pow(1.0,y) = 1.0.  */
8506
  if (real_onep (arg0))
8507
    return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8508
 
8509
  if (host_integerp (arg1, 0))
8510
    {
8511
      HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8512
 
8513
      /* Evaluate powi at compile-time.  */
8514
      if (TREE_CODE (arg0) == REAL_CST
8515
          && !TREE_OVERFLOW (arg0))
8516
        {
8517
          REAL_VALUE_TYPE x;
8518
          x = TREE_REAL_CST (arg0);
8519
          real_powi (&x, TYPE_MODE (type), &x, c);
8520
          return build_real (type, x);
8521
        }
8522
 
8523
      /* Optimize pow(x,0) = 1.0.  */
8524
      if (c == 0)
8525
        return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8526
                                 arg0);
8527
 
8528
      /* Optimize pow(x,1) = x.  */
8529
      if (c == 1)
8530
        return arg0;
8531
 
8532
      /* Optimize pow(x,-1) = 1.0/x.  */
8533
      if (c == -1)
8534
        return fold_build2_loc (loc, RDIV_EXPR, type,
8535
                           build_real (type, dconst1), arg0);
8536
    }
8537
 
8538
  return NULL_TREE;
8539
}
8540
 
8541
/* A subroutine of fold_builtin to fold the various exponent
8542
   functions.  Return NULL_TREE if no simplification can be made.
8543
   FUNC is the corresponding MPFR exponent function.  */
8544
 
8545
static tree
8546
fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
8547
                       int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8548
{
8549
  if (validate_arg (arg, REAL_TYPE))
8550
    {
8551
      tree type = TREE_TYPE (TREE_TYPE (fndecl));
8552
      tree res;
8553
 
8554
      /* Calculate the result when the argument is a constant.  */
8555
      if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8556
        return res;
8557
 
8558
      /* Optimize expN(logN(x)) = x.  */
8559
      if (flag_unsafe_math_optimizations)
8560
        {
8561
          const enum built_in_function fcode = builtin_mathfn_code (arg);
8562
 
8563
          if ((func == mpfr_exp
8564
               && (fcode == BUILT_IN_LOG
8565
                   || fcode == BUILT_IN_LOGF
8566
                   || fcode == BUILT_IN_LOGL))
8567
              || (func == mpfr_exp2
8568
                  && (fcode == BUILT_IN_LOG2
8569
                      || fcode == BUILT_IN_LOG2F
8570
                      || fcode == BUILT_IN_LOG2L))
8571
              || (func == mpfr_exp10
8572
                  && (fcode == BUILT_IN_LOG10
8573
                      || fcode == BUILT_IN_LOG10F
8574
                      || fcode == BUILT_IN_LOG10L)))
8575
            return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8576
        }
8577
    }
8578
 
8579
  return NULL_TREE;
8580
}
8581
 
8582
/* Return true if VAR is a VAR_DECL or a component thereof.  */
8583
 
8584
static bool
8585
var_decl_component_p (tree var)
8586
{
8587
  tree inner = var;
8588
  while (handled_component_p (inner))
8589
    inner = TREE_OPERAND (inner, 0);
8590
  return SSA_VAR_P (inner);
8591
}
8592
 
8593
/* Fold function call to builtin memset.  Return
8594
   NULL_TREE if no simplification can be made.  */
8595
 
8596
static tree
8597
fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8598
                     tree type, bool ignore)
8599
{
8600
  tree var, ret, etype;
8601
  unsigned HOST_WIDE_INT length, cval;
8602
 
8603
  if (! validate_arg (dest, POINTER_TYPE)
8604
      || ! validate_arg (c, INTEGER_TYPE)
8605
      || ! validate_arg (len, INTEGER_TYPE))
8606
    return NULL_TREE;
8607
 
8608
  if (! host_integerp (len, 1))
8609
    return NULL_TREE;
8610
 
8611
  /* If the LEN parameter is zero, return DEST.  */
8612
  if (integer_zerop (len))
8613
    return omit_one_operand_loc (loc, type, dest, c);
8614
 
8615
  if (TREE_CODE (c) != INTEGER_CST || TREE_SIDE_EFFECTS (dest))
8616
    return NULL_TREE;
8617
 
8618
  var = dest;
8619
  STRIP_NOPS (var);
8620
  if (TREE_CODE (var) != ADDR_EXPR)
8621
    return NULL_TREE;
8622
 
8623
  var = TREE_OPERAND (var, 0);
8624
  if (TREE_THIS_VOLATILE (var))
8625
    return NULL_TREE;
8626
 
8627
  etype = TREE_TYPE (var);
8628
  if (TREE_CODE (etype) == ARRAY_TYPE)
8629
    etype = TREE_TYPE (etype);
8630
 
8631
  if (!INTEGRAL_TYPE_P (etype)
8632
      && !POINTER_TYPE_P (etype))
8633
    return NULL_TREE;
8634
 
8635
  if (! var_decl_component_p (var))
8636
    return NULL_TREE;
8637
 
8638
  length = tree_low_cst (len, 1);
8639
  if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
8640
      || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
8641
    return NULL_TREE;
8642
 
8643
  if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8644
    return NULL_TREE;
8645
 
8646
  if (integer_zerop (c))
8647
    cval = 0;
8648
  else
8649
    {
8650
      if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8651
        return NULL_TREE;
8652
 
8653
      cval = TREE_INT_CST_LOW (c);
8654
      cval &= 0xff;
8655
      cval |= cval << 8;
8656
      cval |= cval << 16;
8657
      cval |= (cval << 31) << 1;
8658
    }
8659
 
8660
  ret = build_int_cst_type (etype, cval);
8661
  var = build_fold_indirect_ref_loc (loc,
8662
                                 fold_convert_loc (loc,
8663
                                                   build_pointer_type (etype),
8664
                                                   dest));
8665
  ret = build2 (MODIFY_EXPR, etype, var, ret);
8666
  if (ignore)
8667
    return ret;
8668
 
8669
  return omit_one_operand_loc (loc, type, dest, ret);
8670
}
8671
 
8672
/* Fold function call to builtin memset.  Return
8673
   NULL_TREE if no simplification can be made.  */
8674
 
8675
static tree
8676
fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
8677
{
8678
  if (! validate_arg (dest, POINTER_TYPE)
8679
      || ! validate_arg (size, INTEGER_TYPE))
8680
    return NULL_TREE;
8681
 
8682
  if (!ignore)
8683
    return NULL_TREE;
8684
 
8685
  /* New argument list transforming bzero(ptr x, int y) to
8686
     memset(ptr x, int 0, size_t y).   This is done this way
8687
     so that if it isn't expanded inline, we fallback to
8688
     calling bzero instead of memset.  */
8689
 
8690
  return fold_builtin_memset (loc, dest, integer_zero_node,
8691
                              fold_convert_loc (loc, size_type_node, size),
8692
                              void_type_node, ignore);
8693
}
8694
 
8695
/* Fold function call to builtin mem{{,p}cpy,move}.  Return
8696
   NULL_TREE if no simplification can be made.
8697
   If ENDP is 0, return DEST (like memcpy).
8698
   If ENDP is 1, return DEST+LEN (like mempcpy).
8699
   If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8700
   If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8701
   (memmove).   */
8702
 
8703
static tree
8704
fold_builtin_memory_op (location_t loc, tree dest, tree src,
8705
                        tree len, tree type, bool ignore, int endp)
8706
{
8707
  tree destvar, srcvar, expr;
8708
 
8709
  if (! validate_arg (dest, POINTER_TYPE)
8710
      || ! validate_arg (src, POINTER_TYPE)
8711
      || ! validate_arg (len, INTEGER_TYPE))
8712
    return NULL_TREE;
8713
 
8714
  /* If the LEN parameter is zero, return DEST.  */
8715
  if (integer_zerop (len))
8716
    return omit_one_operand_loc (loc, type, dest, src);
8717
 
8718
  /* If SRC and DEST are the same (and not volatile), return
8719
     DEST{,+LEN,+LEN-1}.  */
8720
  if (operand_equal_p (src, dest, 0))
8721
    expr = len;
8722
  else
8723
    {
8724
      tree srctype, desttype;
8725
      unsigned int src_align, dest_align;
8726
      tree off0;
8727
 
8728
      if (endp == 3)
8729
        {
8730
          src_align = get_pointer_alignment (src);
8731
          dest_align = get_pointer_alignment (dest);
8732
 
8733
          /* Both DEST and SRC must be pointer types.
8734
             ??? This is what old code did.  Is the testing for pointer types
8735
             really mandatory?
8736
 
8737
             If either SRC is readonly or length is 1, we can use memcpy.  */
8738
          if (!dest_align || !src_align)
8739
            return NULL_TREE;
8740
          if (readonly_data_expr (src)
8741
              || (host_integerp (len, 1)
8742
                  && (MIN (src_align, dest_align) / BITS_PER_UNIT
8743
                      >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
8744
            {
8745
              tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8746
              if (!fn)
8747
                return NULL_TREE;
8748
              return build_call_expr_loc (loc, fn, 3, dest, src, len);
8749
            }
8750
 
8751
          /* If *src and *dest can't overlap, optimize into memcpy as well.  */
8752
          if (TREE_CODE (src) == ADDR_EXPR
8753
              && TREE_CODE (dest) == ADDR_EXPR)
8754
            {
8755
              tree src_base, dest_base, fn;
8756
              HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8757
              HOST_WIDE_INT size = -1;
8758
              HOST_WIDE_INT maxsize = -1;
8759
 
8760
              srcvar = TREE_OPERAND (src, 0);
8761
              src_base = get_ref_base_and_extent (srcvar, &src_offset,
8762
                                                  &size, &maxsize);
8763
              destvar = TREE_OPERAND (dest, 0);
8764
              dest_base = get_ref_base_and_extent (destvar, &dest_offset,
8765
                                                   &size, &maxsize);
8766
              if (host_integerp (len, 1))
8767
                maxsize = tree_low_cst (len, 1);
8768
              else
8769
                maxsize = -1;
8770
              src_offset /= BITS_PER_UNIT;
8771
              dest_offset /= BITS_PER_UNIT;
8772
              if (SSA_VAR_P (src_base)
8773
                  && SSA_VAR_P (dest_base))
8774
                {
8775
                  if (operand_equal_p (src_base, dest_base, 0)
8776
                      && ranges_overlap_p (src_offset, maxsize,
8777
                                           dest_offset, maxsize))
8778
                    return NULL_TREE;
8779
                }
8780
              else if (TREE_CODE (src_base) == MEM_REF
8781
                       && TREE_CODE (dest_base) == MEM_REF)
8782
                {
8783
                  double_int off;
8784
                  if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8785
                                         TREE_OPERAND (dest_base, 0), 0))
8786
                    return NULL_TREE;
8787
                  off = double_int_add (mem_ref_offset (src_base),
8788
                                        shwi_to_double_int (src_offset));
8789
                  if (!double_int_fits_in_shwi_p (off))
8790
                    return NULL_TREE;
8791
                  src_offset = off.low;
8792
                  off = double_int_add (mem_ref_offset (dest_base),
8793
                                        shwi_to_double_int (dest_offset));
8794
                  if (!double_int_fits_in_shwi_p (off))
8795
                    return NULL_TREE;
8796
                  dest_offset = off.low;
8797
                  if (ranges_overlap_p (src_offset, maxsize,
8798
                                        dest_offset, maxsize))
8799
                    return NULL_TREE;
8800
                }
8801
              else
8802
                return NULL_TREE;
8803
 
8804
              fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8805
              if (!fn)
8806
                return NULL_TREE;
8807
              return build_call_expr_loc (loc, fn, 3, dest, src, len);
8808
            }
8809
 
8810
          /* If the destination and source do not alias optimize into
8811
             memcpy as well.  */
8812
          if ((is_gimple_min_invariant (dest)
8813
               || TREE_CODE (dest) == SSA_NAME)
8814
              && (is_gimple_min_invariant (src)
8815
                  || TREE_CODE (src) == SSA_NAME))
8816
            {
8817
              ao_ref destr, srcr;
8818
              ao_ref_init_from_ptr_and_size (&destr, dest, len);
8819
              ao_ref_init_from_ptr_and_size (&srcr, src, len);
8820
              if (!refs_may_alias_p_1 (&destr, &srcr, false))
8821
                {
8822
                  tree fn;
8823
                  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8824
                  if (!fn)
8825
                    return NULL_TREE;
8826
                  return build_call_expr_loc (loc, fn, 3, dest, src, len);
8827
                }
8828
            }
8829
 
8830
          return NULL_TREE;
8831
        }
8832
 
8833
      if (!host_integerp (len, 0))
8834
        return NULL_TREE;
8835
      /* FIXME:
8836
         This logic lose for arguments like (type *)malloc (sizeof (type)),
8837
         since we strip the casts of up to VOID return value from malloc.
8838
         Perhaps we ought to inherit type from non-VOID argument here?  */
8839
      STRIP_NOPS (src);
8840
      STRIP_NOPS (dest);
8841
      if (!POINTER_TYPE_P (TREE_TYPE (src))
8842
          || !POINTER_TYPE_P (TREE_TYPE (dest)))
8843
        return NULL_TREE;
8844
      /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
8845
      if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8846
        {
8847
          tree tem = TREE_OPERAND (src, 0);
8848
          STRIP_NOPS (tem);
8849
          if (tem != TREE_OPERAND (src, 0))
8850
            src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8851
        }
8852
      if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8853
        {
8854
          tree tem = TREE_OPERAND (dest, 0);
8855
          STRIP_NOPS (tem);
8856
          if (tem != TREE_OPERAND (dest, 0))
8857
            dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8858
        }
8859
      srctype = TREE_TYPE (TREE_TYPE (src));
8860
      if (TREE_CODE (srctype) == ARRAY_TYPE
8861
          && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8862
        {
8863
          srctype = TREE_TYPE (srctype);
8864
          STRIP_NOPS (src);
8865
          src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8866
        }
8867
      desttype = TREE_TYPE (TREE_TYPE (dest));
8868
      if (TREE_CODE (desttype) == ARRAY_TYPE
8869
          && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8870
        {
8871
          desttype = TREE_TYPE (desttype);
8872
          STRIP_NOPS (dest);
8873
          dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8874
        }
8875
      if (TREE_ADDRESSABLE (srctype)
8876
          || TREE_ADDRESSABLE (desttype))
8877
        return NULL_TREE;
8878
 
8879
      src_align = get_pointer_alignment (src);
8880
      dest_align = get_pointer_alignment (dest);
8881
      if (dest_align < TYPE_ALIGN (desttype)
8882
          || src_align < TYPE_ALIGN (srctype))
8883
        return NULL_TREE;
8884
 
8885
      if (!ignore)
8886
        dest = builtin_save_expr (dest);
8887
 
8888
      /* Build accesses at offset zero with a ref-all character type.  */
8889
      off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
8890
                                                         ptr_mode, true), 0);
8891
 
8892
      destvar = dest;
8893
      STRIP_NOPS (destvar);
8894
      if (TREE_CODE (destvar) == ADDR_EXPR
8895
          && var_decl_component_p (TREE_OPERAND (destvar, 0))
8896
          && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8897
        destvar = fold_build2 (MEM_REF, desttype, destvar, off0);
8898
      else
8899
        destvar = NULL_TREE;
8900
 
8901
      srcvar = src;
8902
      STRIP_NOPS (srcvar);
8903
      if (TREE_CODE (srcvar) == ADDR_EXPR
8904
          && var_decl_component_p (TREE_OPERAND (srcvar, 0))
8905
          && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8906
        {
8907
          if (!destvar
8908
              || src_align >= TYPE_ALIGN (desttype))
8909
            srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
8910
                                  srcvar, off0);
8911
          else if (!STRICT_ALIGNMENT)
8912
            {
8913
              srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8914
                                            src_align);
8915
              srcvar = fold_build2 (MEM_REF, srctype, srcvar, off0);
8916
            }
8917
          else
8918
            srcvar = NULL_TREE;
8919
        }
8920
      else
8921
        srcvar = NULL_TREE;
8922
 
8923
      if (srcvar == NULL_TREE && destvar == NULL_TREE)
8924
        return NULL_TREE;
8925
 
8926
      if (srcvar == NULL_TREE)
8927
        {
8928
          STRIP_NOPS (src);
8929
          if (src_align >= TYPE_ALIGN (desttype))
8930
            srcvar = fold_build2 (MEM_REF, desttype, src, off0);
8931
          else
8932
            {
8933
              if (STRICT_ALIGNMENT)
8934
                return NULL_TREE;
8935
              srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8936
                                            src_align);
8937
              srcvar = fold_build2 (MEM_REF, srctype, src, off0);
8938
            }
8939
        }
8940
      else if (destvar == NULL_TREE)
8941
        {
8942
          STRIP_NOPS (dest);
8943
          if (dest_align >= TYPE_ALIGN (srctype))
8944
            destvar = fold_build2 (MEM_REF, srctype, dest, off0);
8945
          else
8946
            {
8947
              if (STRICT_ALIGNMENT)
8948
                return NULL_TREE;
8949
              desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
8950
                                             dest_align);
8951
              destvar = fold_build2 (MEM_REF, desttype, dest, off0);
8952
            }
8953
        }
8954
 
8955
      expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, srcvar);
8956
    }
8957
 
8958
  if (ignore)
8959
    return expr;
8960
 
8961
  if (endp == 0 || endp == 3)
8962
    return omit_one_operand_loc (loc, type, dest, expr);
8963
 
8964
  if (expr == len)
8965
    expr = NULL_TREE;
8966
 
8967
  if (endp == 2)
8968
    len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
8969
                       ssize_int (1));
8970
 
8971
  dest = fold_build_pointer_plus_loc (loc, dest, len);
8972
  dest = fold_convert_loc (loc, type, dest);
8973
  if (expr)
8974
    dest = omit_one_operand_loc (loc, type, dest, expr);
8975
  return dest;
8976
}
8977
 
8978
/* Fold function call to builtin strcpy with arguments DEST and SRC.
8979
   If LEN is not NULL, it represents the length of the string to be
8980
   copied.  Return NULL_TREE if no simplification can be made.  */
8981
 
8982
tree
8983
fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
8984
{
8985
  tree fn;
8986
 
8987
  if (!validate_arg (dest, POINTER_TYPE)
8988
      || !validate_arg (src, POINTER_TYPE))
8989
    return NULL_TREE;
8990
 
8991
  /* If SRC and DEST are the same (and not volatile), return DEST.  */
8992
  if (operand_equal_p (src, dest, 0))
8993
    return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
8994
 
8995
  if (optimize_function_for_size_p (cfun))
8996
    return NULL_TREE;
8997
 
8998
  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8999
  if (!fn)
9000
    return NULL_TREE;
9001
 
9002
  if (!len)
9003
    {
9004
      len = c_strlen (src, 1);
9005
      if (! len || TREE_SIDE_EFFECTS (len))
9006
        return NULL_TREE;
9007
    }
9008
 
9009
  len = fold_convert_loc (loc, size_type_node, len);
9010
  len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
9011
  return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9012
                           build_call_expr_loc (loc, fn, 3, dest, src, len));
9013
}
9014
 
9015
/* Fold function call to builtin stpcpy with arguments DEST and SRC.
9016
   Return NULL_TREE if no simplification can be made.  */
9017
 
9018
static tree
9019
fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
9020
{
9021
  tree fn, len, lenp1, call, type;
9022
 
9023
  if (!validate_arg (dest, POINTER_TYPE)
9024
      || !validate_arg (src, POINTER_TYPE))
9025
    return NULL_TREE;
9026
 
9027
  len = c_strlen (src, 1);
9028
  if (!len
9029
      || TREE_CODE (len) != INTEGER_CST)
9030
    return NULL_TREE;
9031
 
9032
  if (optimize_function_for_size_p (cfun)
9033
      /* If length is zero it's small enough.  */
9034
      && !integer_zerop (len))
9035
    return NULL_TREE;
9036
 
9037
  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9038
  if (!fn)
9039
    return NULL_TREE;
9040
 
9041
  lenp1 = size_binop_loc (loc, PLUS_EXPR,
9042
                          fold_convert_loc (loc, size_type_node, len),
9043
                          build_int_cst (size_type_node, 1));
9044
  /* We use dest twice in building our expression.  Save it from
9045
     multiple expansions.  */
9046
  dest = builtin_save_expr (dest);
9047
  call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
9048
 
9049
  type = TREE_TYPE (TREE_TYPE (fndecl));
9050
  dest = fold_build_pointer_plus_loc (loc, dest, len);
9051
  dest = fold_convert_loc (loc, type, dest);
9052
  dest = omit_one_operand_loc (loc, type, dest, call);
9053
  return dest;
9054
}
9055
 
9056
/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9057
   If SLEN is not NULL, it represents the length of the source string.
9058
   Return NULL_TREE if no simplification can be made.  */
9059
 
9060
tree
9061
fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
9062
                      tree src, tree len, tree slen)
9063
{
9064
  tree fn;
9065
 
9066
  if (!validate_arg (dest, POINTER_TYPE)
9067
      || !validate_arg (src, POINTER_TYPE)
9068
      || !validate_arg (len, INTEGER_TYPE))
9069
    return NULL_TREE;
9070
 
9071
  /* If the LEN parameter is zero, return DEST.  */
9072
  if (integer_zerop (len))
9073
    return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9074
 
9075
  /* We can't compare slen with len as constants below if len is not a
9076
     constant.  */
9077
  if (len == 0 || TREE_CODE (len) != INTEGER_CST)
9078
    return NULL_TREE;
9079
 
9080
  if (!slen)
9081
    slen = c_strlen (src, 1);
9082
 
9083
  /* Now, we must be passed a constant src ptr parameter.  */
9084
  if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
9085
    return NULL_TREE;
9086
 
9087
  slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
9088
 
9089
  /* We do not support simplification of this case, though we do
9090
     support it when expanding trees into RTL.  */
9091
  /* FIXME: generate a call to __builtin_memset.  */
9092
  if (tree_int_cst_lt (slen, len))
9093
    return NULL_TREE;
9094
 
9095
  /* OK transform into builtin memcpy.  */
9096
  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9097
  if (!fn)
9098
    return NULL_TREE;
9099
 
9100
  len = fold_convert_loc (loc, size_type_node, len);
9101
  return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9102
                           build_call_expr_loc (loc, fn, 3, dest, src, len));
9103
}
9104
 
9105
/* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
9106
   arguments to the call, and TYPE is its return type.
9107
   Return NULL_TREE if no simplification can be made.  */
9108
 
9109
static tree
9110
fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
9111
{
9112
  if (!validate_arg (arg1, POINTER_TYPE)
9113
      || !validate_arg (arg2, INTEGER_TYPE)
9114
      || !validate_arg (len, INTEGER_TYPE))
9115
    return NULL_TREE;
9116
  else
9117
    {
9118
      const char *p1;
9119
 
9120
      if (TREE_CODE (arg2) != INTEGER_CST
9121
          || !host_integerp (len, 1))
9122
        return NULL_TREE;
9123
 
9124
      p1 = c_getstr (arg1);
9125
      if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9126
        {
9127
          char c;
9128
          const char *r;
9129
          tree tem;
9130
 
9131
          if (target_char_cast (arg2, &c))
9132
            return NULL_TREE;
9133
 
9134
          r = (const char *) memchr (p1, c, tree_low_cst (len, 1));
9135
 
9136
          if (r == NULL)
9137
            return build_int_cst (TREE_TYPE (arg1), 0);
9138
 
9139
          tem = fold_build_pointer_plus_hwi_loc (loc, arg1, r - p1);
9140
          return fold_convert_loc (loc, type, tem);
9141
        }
9142
      return NULL_TREE;
9143
    }
9144
}
9145
 
9146
/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9147
   Return NULL_TREE if no simplification can be made.  */
9148
 
9149
static tree
9150
fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9151
{
9152
  const char *p1, *p2;
9153
 
9154
  if (!validate_arg (arg1, POINTER_TYPE)
9155
      || !validate_arg (arg2, POINTER_TYPE)
9156
      || !validate_arg (len, INTEGER_TYPE))
9157
    return NULL_TREE;
9158
 
9159
  /* If the LEN parameter is zero, return zero.  */
9160
  if (integer_zerop (len))
9161
    return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9162
                              arg1, arg2);
9163
 
9164
  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9165
  if (operand_equal_p (arg1, arg2, 0))
9166
    return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9167
 
9168
  p1 = c_getstr (arg1);
9169
  p2 = c_getstr (arg2);
9170
 
9171
  /* If all arguments are constant, and the value of len is not greater
9172
     than the lengths of arg1 and arg2, evaluate at compile-time.  */
9173
  if (host_integerp (len, 1) && p1 && p2
9174
      && compare_tree_int (len, strlen (p1) + 1) <= 0
9175
      && compare_tree_int (len, strlen (p2) + 1) <= 0)
9176
    {
9177
      const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9178
 
9179
      if (r > 0)
9180
        return integer_one_node;
9181
      else if (r < 0)
9182
        return integer_minus_one_node;
9183
      else
9184
        return integer_zero_node;
9185
    }
9186
 
9187
  /* If len parameter is one, return an expression corresponding to
9188
     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9189
  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9190
    {
9191
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9192
      tree cst_uchar_ptr_node
9193
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9194
 
9195
      tree ind1
9196
        = fold_convert_loc (loc, integer_type_node,
9197
                            build1 (INDIRECT_REF, cst_uchar_node,
9198
                                    fold_convert_loc (loc,
9199
                                                      cst_uchar_ptr_node,
9200
                                                      arg1)));
9201
      tree ind2
9202
        = fold_convert_loc (loc, integer_type_node,
9203
                            build1 (INDIRECT_REF, cst_uchar_node,
9204
                                    fold_convert_loc (loc,
9205
                                                      cst_uchar_ptr_node,
9206
                                                      arg2)));
9207
      return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9208
    }
9209
 
9210
  return NULL_TREE;
9211
}
9212
 
9213
/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9214
   Return NULL_TREE if no simplification can be made.  */
9215
 
9216
static tree
9217
fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9218
{
9219
  const char *p1, *p2;
9220
 
9221
  if (!validate_arg (arg1, POINTER_TYPE)
9222
      || !validate_arg (arg2, POINTER_TYPE))
9223
    return NULL_TREE;
9224
 
9225
  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9226
  if (operand_equal_p (arg1, arg2, 0))
9227
    return integer_zero_node;
9228
 
9229
  p1 = c_getstr (arg1);
9230
  p2 = c_getstr (arg2);
9231
 
9232
  if (p1 && p2)
9233
    {
9234
      const int i = strcmp (p1, p2);
9235
      if (i < 0)
9236
        return integer_minus_one_node;
9237
      else if (i > 0)
9238
        return integer_one_node;
9239
      else
9240
        return integer_zero_node;
9241
    }
9242
 
9243
  /* If the second arg is "", return *(const unsigned char*)arg1.  */
9244
  if (p2 && *p2 == '\0')
9245
    {
9246
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9247
      tree cst_uchar_ptr_node
9248
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9249
 
9250
      return fold_convert_loc (loc, integer_type_node,
9251
                               build1 (INDIRECT_REF, cst_uchar_node,
9252
                                       fold_convert_loc (loc,
9253
                                                         cst_uchar_ptr_node,
9254
                                                         arg1)));
9255
    }
9256
 
9257
  /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9258
  if (p1 && *p1 == '\0')
9259
    {
9260
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9261
      tree cst_uchar_ptr_node
9262
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9263
 
9264
      tree temp
9265
        = fold_convert_loc (loc, integer_type_node,
9266
                            build1 (INDIRECT_REF, cst_uchar_node,
9267
                                    fold_convert_loc (loc,
9268
                                                      cst_uchar_ptr_node,
9269
                                                      arg2)));
9270
      return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9271
    }
9272
 
9273
  return NULL_TREE;
9274
}
9275
 
9276
/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9277
   Return NULL_TREE if no simplification can be made.  */
9278
 
9279
static tree
9280
fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9281
{
9282
  const char *p1, *p2;
9283
 
9284
  if (!validate_arg (arg1, POINTER_TYPE)
9285
      || !validate_arg (arg2, POINTER_TYPE)
9286
      || !validate_arg (len, INTEGER_TYPE))
9287
    return NULL_TREE;
9288
 
9289
  /* If the LEN parameter is zero, return zero.  */
9290
  if (integer_zerop (len))
9291
    return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9292
                              arg1, arg2);
9293
 
9294
  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9295
  if (operand_equal_p (arg1, arg2, 0))
9296
    return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9297
 
9298
  p1 = c_getstr (arg1);
9299
  p2 = c_getstr (arg2);
9300
 
9301
  if (host_integerp (len, 1) && p1 && p2)
9302
    {
9303
      const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9304
      if (i > 0)
9305
        return integer_one_node;
9306
      else if (i < 0)
9307
        return integer_minus_one_node;
9308
      else
9309
        return integer_zero_node;
9310
    }
9311
 
9312
  /* If the second arg is "", and the length is greater than zero,
9313
     return *(const unsigned char*)arg1.  */
9314
  if (p2 && *p2 == '\0'
9315
      && TREE_CODE (len) == INTEGER_CST
9316
      && tree_int_cst_sgn (len) == 1)
9317
    {
9318
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9319
      tree cst_uchar_ptr_node
9320
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9321
 
9322
      return fold_convert_loc (loc, integer_type_node,
9323
                               build1 (INDIRECT_REF, cst_uchar_node,
9324
                                       fold_convert_loc (loc,
9325
                                                         cst_uchar_ptr_node,
9326
                                                         arg1)));
9327
    }
9328
 
9329
  /* If the first arg is "", and the length is greater than zero,
9330
     return -*(const unsigned char*)arg2.  */
9331
  if (p1 && *p1 == '\0'
9332
      && TREE_CODE (len) == INTEGER_CST
9333
      && tree_int_cst_sgn (len) == 1)
9334
    {
9335
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9336
      tree cst_uchar_ptr_node
9337
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9338
 
9339
      tree temp = fold_convert_loc (loc, integer_type_node,
9340
                                    build1 (INDIRECT_REF, cst_uchar_node,
9341
                                            fold_convert_loc (loc,
9342
                                                              cst_uchar_ptr_node,
9343
                                                              arg2)));
9344
      return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9345
    }
9346
 
9347
  /* If len parameter is one, return an expression corresponding to
9348
     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9349
  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9350
    {
9351
      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9352
      tree cst_uchar_ptr_node
9353
        = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9354
 
9355
      tree ind1 = fold_convert_loc (loc, integer_type_node,
9356
                                    build1 (INDIRECT_REF, cst_uchar_node,
9357
                                            fold_convert_loc (loc,
9358
                                                              cst_uchar_ptr_node,
9359
                                                              arg1)));
9360
      tree ind2 = fold_convert_loc (loc, integer_type_node,
9361
                                    build1 (INDIRECT_REF, cst_uchar_node,
9362
                                            fold_convert_loc (loc,
9363
                                                              cst_uchar_ptr_node,
9364
                                                              arg2)));
9365
      return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9366
    }
9367
 
9368
  return NULL_TREE;
9369
}
9370
 
9371
/* Fold function call to builtin signbit, signbitf or signbitl with argument
9372
   ARG.  Return NULL_TREE if no simplification can be made.  */
9373
 
9374
static tree
9375
fold_builtin_signbit (location_t loc, tree arg, tree type)
9376
{
9377
  if (!validate_arg (arg, REAL_TYPE))
9378
    return NULL_TREE;
9379
 
9380
  /* If ARG is a compile-time constant, determine the result.  */
9381
  if (TREE_CODE (arg) == REAL_CST
9382
      && !TREE_OVERFLOW (arg))
9383
    {
9384
      REAL_VALUE_TYPE c;
9385
 
9386
      c = TREE_REAL_CST (arg);
9387
      return (REAL_VALUE_NEGATIVE (c)
9388
              ? build_one_cst (type)
9389
              : build_zero_cst (type));
9390
    }
9391
 
9392
  /* If ARG is non-negative, the result is always zero.  */
9393
  if (tree_expr_nonnegative_p (arg))
9394
    return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9395
 
9396
  /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9397
  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9398
    return fold_convert (type,
9399
                         fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
9400
                        build_real (TREE_TYPE (arg), dconst0)));
9401
 
9402
  return NULL_TREE;
9403
}
9404
 
9405
/* Fold function call to builtin copysign, copysignf or copysignl with
9406
   arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9407
   be made.  */
9408
 
9409
static tree
9410
fold_builtin_copysign (location_t loc, tree fndecl,
9411
                       tree arg1, tree arg2, tree type)
9412
{
9413
  tree tem;
9414
 
9415
  if (!validate_arg (arg1, REAL_TYPE)
9416
      || !validate_arg (arg2, REAL_TYPE))
9417
    return NULL_TREE;
9418
 
9419
  /* copysign(X,X) is X.  */
9420
  if (operand_equal_p (arg1, arg2, 0))
9421
    return fold_convert_loc (loc, type, arg1);
9422
 
9423
  /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9424
  if (TREE_CODE (arg1) == REAL_CST
9425
      && TREE_CODE (arg2) == REAL_CST
9426
      && !TREE_OVERFLOW (arg1)
9427
      && !TREE_OVERFLOW (arg2))
9428
    {
9429
      REAL_VALUE_TYPE c1, c2;
9430
 
9431
      c1 = TREE_REAL_CST (arg1);
9432
      c2 = TREE_REAL_CST (arg2);
9433
      /* c1.sign := c2.sign.  */
9434
      real_copysign (&c1, &c2);
9435
      return build_real (type, c1);
9436
    }
9437
 
9438
  /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9439
     Remember to evaluate Y for side-effects.  */
9440
  if (tree_expr_nonnegative_p (arg2))
9441
    return omit_one_operand_loc (loc, type,
9442
                             fold_build1_loc (loc, ABS_EXPR, type, arg1),
9443
                             arg2);
9444
 
9445
  /* Strip sign changing operations for the first argument.  */
9446
  tem = fold_strip_sign_ops (arg1);
9447
  if (tem)
9448
    return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
9449
 
9450
  return NULL_TREE;
9451
}
9452
 
9453
/* Fold a call to builtin isascii with argument ARG.  */
9454
 
9455
static tree
9456
fold_builtin_isascii (location_t loc, tree arg)
9457
{
9458
  if (!validate_arg (arg, INTEGER_TYPE))
9459
    return NULL_TREE;
9460
  else
9461
    {
9462
      /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9463
      arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9464
                         build_int_cst (integer_type_node,
9465
                                        ~ (unsigned HOST_WIDE_INT) 0x7f));
9466
      return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
9467
                              arg, integer_zero_node);
9468
    }
9469
}
9470
 
9471
/* Fold a call to builtin toascii with argument ARG.  */
9472
 
9473
static tree
9474
fold_builtin_toascii (location_t loc, tree arg)
9475
{
9476
  if (!validate_arg (arg, INTEGER_TYPE))
9477
    return NULL_TREE;
9478
 
9479
  /* Transform toascii(c) -> (c & 0x7f).  */
9480
  return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
9481
                          build_int_cst (integer_type_node, 0x7f));
9482
}
9483
 
9484
/* Fold a call to builtin isdigit with argument ARG.  */
9485
 
9486
static tree
9487
fold_builtin_isdigit (location_t loc, tree arg)
9488
{
9489
  if (!validate_arg (arg, INTEGER_TYPE))
9490
    return NULL_TREE;
9491
  else
9492
    {
9493
      /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9494
      /* According to the C standard, isdigit is unaffected by locale.
9495
         However, it definitely is affected by the target character set.  */
9496
      unsigned HOST_WIDE_INT target_digit0
9497
        = lang_hooks.to_target_charset ('0');
9498
 
9499
      if (target_digit0 == 0)
9500
        return NULL_TREE;
9501
 
9502
      arg = fold_convert_loc (loc, unsigned_type_node, arg);
9503
      arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9504
                         build_int_cst (unsigned_type_node, target_digit0));
9505
      return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
9506
                          build_int_cst (unsigned_type_node, 9));
9507
    }
9508
}
9509
 
9510
/* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9511
 
9512
static tree
9513
fold_builtin_fabs (location_t loc, tree arg, tree type)
9514
{
9515
  if (!validate_arg (arg, REAL_TYPE))
9516
    return NULL_TREE;
9517
 
9518
  arg = fold_convert_loc (loc, type, arg);
9519
  if (TREE_CODE (arg) == REAL_CST)
9520
    return fold_abs_const (arg, type);
9521
  return fold_build1_loc (loc, ABS_EXPR, type, arg);
9522
}
9523
 
9524
/* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9525
 
9526
static tree
9527
fold_builtin_abs (location_t loc, tree arg, tree type)
9528
{
9529
  if (!validate_arg (arg, INTEGER_TYPE))
9530
    return NULL_TREE;
9531
 
9532
  arg = fold_convert_loc (loc, type, arg);
9533
  if (TREE_CODE (arg) == INTEGER_CST)
9534
    return fold_abs_const (arg, type);
9535
  return fold_build1_loc (loc, ABS_EXPR, type, arg);
9536
}
9537
 
9538
/* Fold a fma operation with arguments ARG[012].  */
9539
 
9540
tree
9541
fold_fma (location_t loc ATTRIBUTE_UNUSED,
9542
          tree type, tree arg0, tree arg1, tree arg2)
9543
{
9544
  if (TREE_CODE (arg0) == REAL_CST
9545
      && TREE_CODE (arg1) == REAL_CST
9546
      && TREE_CODE (arg2) == REAL_CST)
9547
    return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
9548
 
9549
  return NULL_TREE;
9550
}
9551
 
9552
/* Fold a call to fma, fmaf, or fmal with arguments ARG[012].  */
9553
 
9554
static tree
9555
fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
9556
{
9557
  if (validate_arg (arg0, REAL_TYPE)
9558
      && validate_arg(arg1, REAL_TYPE)
9559
      && validate_arg(arg2, REAL_TYPE))
9560
    {
9561
      tree tem = fold_fma (loc, type, arg0, arg1, arg2);
9562
      if (tem)
9563
        return tem;
9564
 
9565
      /* ??? Only expand to FMA_EXPR if it's directly supported.  */
9566
      if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing)
9567
        return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2);
9568
    }
9569
  return NULL_TREE;
9570
}
9571
 
9572
/* Fold a call to builtin fmin or fmax.  */
9573
 
9574
static tree
9575
fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9576
                        tree type, bool max)
9577
{
9578
  if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9579
    {
9580
      /* Calculate the result when the argument is a constant.  */
9581
      tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9582
 
9583
      if (res)
9584
        return res;
9585
 
9586
      /* If either argument is NaN, return the other one.  Avoid the
9587
         transformation if we get (and honor) a signalling NaN.  Using
9588
         omit_one_operand() ensures we create a non-lvalue.  */
9589
      if (TREE_CODE (arg0) == REAL_CST
9590
          && real_isnan (&TREE_REAL_CST (arg0))
9591
          && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9592
              || ! TREE_REAL_CST (arg0).signalling))
9593
        return omit_one_operand_loc (loc, type, arg1, arg0);
9594
      if (TREE_CODE (arg1) == REAL_CST
9595
          && real_isnan (&TREE_REAL_CST (arg1))
9596
          && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9597
              || ! TREE_REAL_CST (arg1).signalling))
9598
        return omit_one_operand_loc (loc, type, arg0, arg1);
9599
 
9600
      /* Transform fmin/fmax(x,x) -> x.  */
9601
      if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9602
        return omit_one_operand_loc (loc, type, arg0, arg1);
9603
 
9604
      /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9605
         functions to return the numeric arg if the other one is NaN.
9606
         These tree codes don't honor that, so only transform if
9607
         -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9608
         handled, so we don't have to worry about it either.  */
9609
      if (flag_finite_math_only)
9610
        return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9611
                            fold_convert_loc (loc, type, arg0),
9612
                            fold_convert_loc (loc, type, arg1));
9613
    }
9614
  return NULL_TREE;
9615
}
9616
 
9617
/* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9618
 
9619
static tree
9620
fold_builtin_carg (location_t loc, tree arg, tree type)
9621
{
9622
  if (validate_arg (arg, COMPLEX_TYPE)
9623
      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
9624
    {
9625
      tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9626
 
9627
      if (atan2_fn)
9628
        {
9629
          tree new_arg = builtin_save_expr (arg);
9630
          tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9631
          tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9632
          return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
9633
        }
9634
    }
9635
 
9636
  return NULL_TREE;
9637
}
9638
 
9639
/* Fold a call to builtin logb/ilogb.  */
9640
 
9641
static tree
9642
fold_builtin_logb (location_t loc, tree arg, tree rettype)
9643
{
9644
  if (! validate_arg (arg, REAL_TYPE))
9645
    return NULL_TREE;
9646
 
9647
  STRIP_NOPS (arg);
9648
 
9649
  if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9650
    {
9651
      const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9652
 
9653
      switch (value->cl)
9654
      {
9655
      case rvc_nan:
9656
      case rvc_inf:
9657
        /* If arg is Inf or NaN and we're logb, return it.  */
9658
        if (TREE_CODE (rettype) == REAL_TYPE)
9659
          return fold_convert_loc (loc, rettype, arg);
9660
        /* Fall through... */
9661
      case rvc_zero:
9662
        /* Zero may set errno and/or raise an exception for logb, also
9663
           for ilogb we don't know FP_ILOGB0.  */
9664
        return NULL_TREE;
9665
      case rvc_normal:
9666
        /* For normal numbers, proceed iff radix == 2.  In GCC,
9667
           normalized significands are in the range [0.5, 1.0).  We
9668
           want the exponent as if they were [1.0, 2.0) so get the
9669
           exponent and subtract 1.  */
9670
        if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9671
          return fold_convert_loc (loc, rettype,
9672
                                   build_int_cst (integer_type_node,
9673
                                                  REAL_EXP (value)-1));
9674
        break;
9675
      }
9676
    }
9677
 
9678
  return NULL_TREE;
9679
}
9680
 
9681
/* Fold a call to builtin significand, if radix == 2.  */
9682
 
9683
static tree
9684
fold_builtin_significand (location_t loc, tree arg, tree rettype)
9685
{
9686
  if (! validate_arg (arg, REAL_TYPE))
9687
    return NULL_TREE;
9688
 
9689
  STRIP_NOPS (arg);
9690
 
9691
  if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9692
    {
9693
      const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9694
 
9695
      switch (value->cl)
9696
      {
9697
      case rvc_zero:
9698
      case rvc_nan:
9699
      case rvc_inf:
9700
        /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9701
        return fold_convert_loc (loc, rettype, arg);
9702
      case rvc_normal:
9703
        /* For normal numbers, proceed iff radix == 2.  */
9704
        if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9705
          {
9706
            REAL_VALUE_TYPE result = *value;
9707
            /* In GCC, normalized significands are in the range [0.5,
9708
               1.0).  We want them to be [1.0, 2.0) so set the
9709
               exponent to 1.  */
9710
            SET_REAL_EXP (&result, 1);
9711
            return build_real (rettype, result);
9712
          }
9713
        break;
9714
      }
9715
    }
9716
 
9717
  return NULL_TREE;
9718
}
9719
 
9720
/* Fold a call to builtin frexp, we can assume the base is 2.  */
9721
 
9722
static tree
9723
fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
9724
{
9725
  if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9726
    return NULL_TREE;
9727
 
9728
  STRIP_NOPS (arg0);
9729
 
9730
  if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9731
    return NULL_TREE;
9732
 
9733
  arg1 = build_fold_indirect_ref_loc (loc, arg1);
9734
 
9735
  /* Proceed if a valid pointer type was passed in.  */
9736
  if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9737
    {
9738
      const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9739
      tree frac, exp;
9740
 
9741
      switch (value->cl)
9742
      {
9743
      case rvc_zero:
9744
        /* For +-0, return (*exp = 0, +-0).  */
9745
        exp = integer_zero_node;
9746
        frac = arg0;
9747
        break;
9748
      case rvc_nan:
9749
      case rvc_inf:
9750
        /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9751
        return omit_one_operand_loc (loc, rettype, arg0, arg1);
9752
      case rvc_normal:
9753
        {
9754
          /* Since the frexp function always expects base 2, and in
9755
             GCC normalized significands are already in the range
9756
             [0.5, 1.0), we have exactly what frexp wants.  */
9757
          REAL_VALUE_TYPE frac_rvt = *value;
9758
          SET_REAL_EXP (&frac_rvt, 0);
9759
          frac = build_real (rettype, frac_rvt);
9760
          exp = build_int_cst (integer_type_node, REAL_EXP (value));
9761
        }
9762
        break;
9763
      default:
9764
        gcc_unreachable ();
9765
      }
9766
 
9767
      /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9768
      arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
9769
      TREE_SIDE_EFFECTS (arg1) = 1;
9770
      return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
9771
    }
9772
 
9773
  return NULL_TREE;
9774
}
9775
 
9776
/* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9777
   then we can assume the base is two.  If it's false, then we have to
9778
   check the mode of the TYPE parameter in certain cases.  */
9779
 
9780
static tree
9781
fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9782
                            tree type, bool ldexp)
9783
{
9784
  if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9785
    {
9786
      STRIP_NOPS (arg0);
9787
      STRIP_NOPS (arg1);
9788
 
9789
      /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9790
      if (real_zerop (arg0) || integer_zerop (arg1)
9791
          || (TREE_CODE (arg0) == REAL_CST
9792
              && !real_isfinite (&TREE_REAL_CST (arg0))))
9793
        return omit_one_operand_loc (loc, type, arg0, arg1);
9794
 
9795
      /* If both arguments are constant, then try to evaluate it.  */
9796
      if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9797
          && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9798
          && host_integerp (arg1, 0))
9799
        {
9800
          /* Bound the maximum adjustment to twice the range of the
9801
             mode's valid exponents.  Use abs to ensure the range is
9802
             positive as a sanity check.  */
9803
          const long max_exp_adj = 2 *
9804
            labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9805
                 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9806
 
9807
          /* Get the user-requested adjustment.  */
9808
          const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9809
 
9810
          /* The requested adjustment must be inside this range.  This
9811
             is a preliminary cap to avoid things like overflow, we
9812
             may still fail to compute the result for other reasons.  */
9813
          if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9814
            {
9815
              REAL_VALUE_TYPE initial_result;
9816
 
9817
              real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9818
 
9819
              /* Ensure we didn't overflow.  */
9820
              if (! real_isinf (&initial_result))
9821
                {
9822
                  const REAL_VALUE_TYPE trunc_result
9823
                    = real_value_truncate (TYPE_MODE (type), initial_result);
9824
 
9825
                  /* Only proceed if the target mode can hold the
9826
                     resulting value.  */
9827
                  if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9828
                    return build_real (type, trunc_result);
9829
                }
9830
            }
9831
        }
9832
    }
9833
 
9834
  return NULL_TREE;
9835
}
9836
 
9837
/* Fold a call to builtin modf.  */
9838
 
9839
static tree
9840
fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
9841
{
9842
  if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9843
    return NULL_TREE;
9844
 
9845
  STRIP_NOPS (arg0);
9846
 
9847
  if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9848
    return NULL_TREE;
9849
 
9850
  arg1 = build_fold_indirect_ref_loc (loc, arg1);
9851
 
9852
  /* Proceed if a valid pointer type was passed in.  */
9853
  if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9854
    {
9855
      const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9856
      REAL_VALUE_TYPE trunc, frac;
9857
 
9858
      switch (value->cl)
9859
      {
9860
      case rvc_nan:
9861
      case rvc_zero:
9862
        /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9863
        trunc = frac = *value;
9864
        break;
9865
      case rvc_inf:
9866
        /* For +-Inf, return (*arg1 = arg0, +-0).  */
9867
        frac = dconst0;
9868
        frac.sign = value->sign;
9869
        trunc = *value;
9870
        break;
9871
      case rvc_normal:
9872
        /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9873
        real_trunc (&trunc, VOIDmode, value);
9874
        real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9875
        /* If the original number was negative and already
9876
           integral, then the fractional part is -0.0.  */
9877
        if (value->sign && frac.cl == rvc_zero)
9878
          frac.sign = value->sign;
9879
        break;
9880
      }
9881
 
9882
      /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9883
      arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
9884
                          build_real (rettype, trunc));
9885
      TREE_SIDE_EFFECTS (arg1) = 1;
9886
      return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
9887
                          build_real (rettype, frac));
9888
    }
9889
 
9890
  return NULL_TREE;
9891
}
9892
 
9893
/* Given a location LOC, an interclass builtin function decl FNDECL
9894
   and its single argument ARG, return an folded expression computing
9895
   the same, or NULL_TREE if we either couldn't or didn't want to fold
9896
   (the latter happen if there's an RTL instruction available).  */
9897
 
9898
static tree
9899
fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9900
{
9901
  enum machine_mode mode;
9902
 
9903
  if (!validate_arg (arg, REAL_TYPE))
9904
    return NULL_TREE;
9905
 
9906
  if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9907
    return NULL_TREE;
9908
 
9909
  mode = TYPE_MODE (TREE_TYPE (arg));
9910
 
9911
  /* If there is no optab, try generic code.  */
9912
  switch (DECL_FUNCTION_CODE (fndecl))
9913
    {
9914
      tree result;
9915
 
9916
    CASE_FLT_FN (BUILT_IN_ISINF):
9917
      {
9918
        /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
9919
        tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER);
9920
        tree const type = TREE_TYPE (arg);
9921
        REAL_VALUE_TYPE r;
9922
        char buf[128];
9923
 
9924
        get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9925
        real_from_string (&r, buf);
9926
        result = build_call_expr (isgr_fn, 2,
9927
                                  fold_build1_loc (loc, ABS_EXPR, type, arg),
9928
                                  build_real (type, r));
9929
        return result;
9930
      }
9931
    CASE_FLT_FN (BUILT_IN_FINITE):
9932
    case BUILT_IN_ISFINITE:
9933
      {
9934
        /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
9935
        tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9936
        tree const type = TREE_TYPE (arg);
9937
        REAL_VALUE_TYPE r;
9938
        char buf[128];
9939
 
9940
        get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9941
        real_from_string (&r, buf);
9942
        result = build_call_expr (isle_fn, 2,
9943
                                  fold_build1_loc (loc, ABS_EXPR, type, arg),
9944
                                  build_real (type, r));
9945
        /*result = fold_build2_loc (loc, UNGT_EXPR,
9946
                                  TREE_TYPE (TREE_TYPE (fndecl)),
9947
                                  fold_build1_loc (loc, ABS_EXPR, type, arg),
9948
                                  build_real (type, r));
9949
        result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9950
                                  TREE_TYPE (TREE_TYPE (fndecl)),
9951
                                  result);*/
9952
        return result;
9953
      }
9954
    case BUILT_IN_ISNORMAL:
9955
      {
9956
        /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9957
           islessequal(fabs(x),DBL_MAX).  */
9958
        tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9959
        tree const isge_fn = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL);
9960
        tree const type = TREE_TYPE (arg);
9961
        REAL_VALUE_TYPE rmax, rmin;
9962
        char buf[128];
9963
 
9964
        get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9965
        real_from_string (&rmax, buf);
9966
        sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9967
        real_from_string (&rmin, buf);
9968
        arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9969
        result = build_call_expr (isle_fn, 2, arg,
9970
                                  build_real (type, rmax));
9971
        result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
9972
                              build_call_expr (isge_fn, 2, arg,
9973
                                               build_real (type, rmin)));
9974
        return result;
9975
      }
9976
    default:
9977
      break;
9978
    }
9979
 
9980
  return NULL_TREE;
9981
}
9982
 
9983
/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9984
   ARG is the argument for the call.  */
9985
 
9986
static tree
9987
fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
9988
{
9989
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
9990
  REAL_VALUE_TYPE r;
9991
 
9992
  if (!validate_arg (arg, REAL_TYPE))
9993
    return NULL_TREE;
9994
 
9995
  switch (builtin_index)
9996
    {
9997
    case BUILT_IN_ISINF:
9998
      if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9999
        return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10000
 
10001
      if (TREE_CODE (arg) == REAL_CST)
10002
        {
10003
          r = TREE_REAL_CST (arg);
10004
          if (real_isinf (&r))
10005
            return real_compare (GT_EXPR, &r, &dconst0)
10006
                   ? integer_one_node : integer_minus_one_node;
10007
          else
10008
            return integer_zero_node;
10009
        }
10010
 
10011
      return NULL_TREE;
10012
 
10013
    case BUILT_IN_ISINF_SIGN:
10014
      {
10015
        /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10016
        /* In a boolean context, GCC will fold the inner COND_EXPR to
10017
           1.  So e.g. "if (isinf_sign(x))" would be folded to just
10018
           "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10019
        tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10020
        tree isinf_fn = builtin_decl_explicit (BUILT_IN_ISINF);
10021
        tree tmp = NULL_TREE;
10022
 
10023
        arg = builtin_save_expr (arg);
10024
 
10025
        if (signbit_fn && isinf_fn)
10026
          {
10027
            tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
10028
            tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
10029
 
10030
            signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10031
                                        signbit_call, integer_zero_node);
10032
            isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10033
                                      isinf_call, integer_zero_node);
10034
 
10035
            tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
10036
                               integer_minus_one_node, integer_one_node);
10037
            tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10038
                               isinf_call, tmp,
10039
                               integer_zero_node);
10040
          }
10041
 
10042
        return tmp;
10043
      }
10044
 
10045
    case BUILT_IN_ISFINITE:
10046
      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10047
          && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10048
        return omit_one_operand_loc (loc, type, integer_one_node, arg);
10049
 
10050
      if (TREE_CODE (arg) == REAL_CST)
10051
        {
10052
          r = TREE_REAL_CST (arg);
10053
          return real_isfinite (&r) ? integer_one_node : integer_zero_node;
10054
        }
10055
 
10056
      return NULL_TREE;
10057
 
10058
    case BUILT_IN_ISNAN:
10059
      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
10060
        return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10061
 
10062
      if (TREE_CODE (arg) == REAL_CST)
10063
        {
10064
          r = TREE_REAL_CST (arg);
10065
          return real_isnan (&r) ? integer_one_node : integer_zero_node;
10066
        }
10067
 
10068
      arg = builtin_save_expr (arg);
10069
      return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
10070
 
10071
    default:
10072
      gcc_unreachable ();
10073
    }
10074
}
10075
 
10076
/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10077
   This builtin will generate code to return the appropriate floating
10078
   point classification depending on the value of the floating point
10079
   number passed in.  The possible return values must be supplied as
10080
   int arguments to the call in the following order: FP_NAN, FP_INFINITE,
10081
   FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
10082
   one floating point argument which is "type generic".  */
10083
 
10084
static tree
10085
fold_builtin_fpclassify (location_t loc, tree exp)
10086
{
10087
  tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10088
    arg, type, res, tmp;
10089
  enum machine_mode mode;
10090
  REAL_VALUE_TYPE r;
10091
  char buf[128];
10092
 
10093
  /* Verify the required arguments in the original call.  */
10094
  if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10095
                         INTEGER_TYPE, INTEGER_TYPE,
10096
                         INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10097
    return NULL_TREE;
10098
 
10099
  fp_nan = CALL_EXPR_ARG (exp, 0);
10100
  fp_infinite = CALL_EXPR_ARG (exp, 1);
10101
  fp_normal = CALL_EXPR_ARG (exp, 2);
10102
  fp_subnormal = CALL_EXPR_ARG (exp, 3);
10103
  fp_zero = CALL_EXPR_ARG (exp, 4);
10104
  arg = CALL_EXPR_ARG (exp, 5);
10105
  type = TREE_TYPE (arg);
10106
  mode = TYPE_MODE (type);
10107
  arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10108
 
10109
  /* fpclassify(x) ->
10110
       isnan(x) ? FP_NAN :
10111
         (fabs(x) == Inf ? FP_INFINITE :
10112
           (fabs(x) >= DBL_MIN ? FP_NORMAL :
10113
             (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
10114
 
10115
  tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10116
                     build_real (type, dconst0));
10117
  res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10118
                     tmp, fp_zero, fp_subnormal);
10119
 
10120
  sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10121
  real_from_string (&r, buf);
10122
  tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
10123
                     arg, build_real (type, r));
10124
  res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
10125
 
10126
  if (HONOR_INFINITIES (mode))
10127
    {
10128
      real_inf (&r);
10129
      tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10130
                         build_real (type, r));
10131
      res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
10132
                         fp_infinite, res);
10133
    }
10134
 
10135
  if (HONOR_NANS (mode))
10136
    {
10137
      tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
10138
      res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
10139
    }
10140
 
10141
  return res;
10142
}
10143
 
10144
/* Fold a call to an unordered comparison function such as
10145
   __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
10146
   being called and ARG0 and ARG1 are the arguments for the call.
10147
   UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10148
   the opposite of the desired result.  UNORDERED_CODE is used
10149
   for modes that can hold NaNs and ORDERED_CODE is used for
10150
   the rest.  */
10151
 
10152
static tree
10153
fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
10154
                            enum tree_code unordered_code,
10155
                            enum tree_code ordered_code)
10156
{
10157
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
10158
  enum tree_code code;
10159
  tree type0, type1;
10160
  enum tree_code code0, code1;
10161
  tree cmp_type = NULL_TREE;
10162
 
10163
  type0 = TREE_TYPE (arg0);
10164
  type1 = TREE_TYPE (arg1);
10165
 
10166
  code0 = TREE_CODE (type0);
10167
  code1 = TREE_CODE (type1);
10168
 
10169
  if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10170
    /* Choose the wider of two real types.  */
10171
    cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10172
      ? type0 : type1;
10173
  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10174
    cmp_type = type0;
10175
  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10176
    cmp_type = type1;
10177
 
10178
  arg0 = fold_convert_loc (loc, cmp_type, arg0);
10179
  arg1 = fold_convert_loc (loc, cmp_type, arg1);
10180
 
10181
  if (unordered_code == UNORDERED_EXPR)
10182
    {
10183
      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
10184
        return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
10185
      return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
10186
    }
10187
 
10188
  code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10189
                                                   : ordered_code;
10190
  return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
10191
                      fold_build2_loc (loc, code, type, arg0, arg1));
10192
}
10193
 
10194
/* Fold a call to built-in function FNDECL with 0 arguments.
10195
   IGNORE is true if the result of the function call is ignored.  This
10196
   function returns NULL_TREE if no simplification was possible.  */
10197
 
10198
static tree
10199
fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
10200
{
10201
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
10202
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10203
  switch (fcode)
10204
    {
10205
    CASE_FLT_FN (BUILT_IN_INF):
10206
    case BUILT_IN_INFD32:
10207
    case BUILT_IN_INFD64:
10208
    case BUILT_IN_INFD128:
10209
      return fold_builtin_inf (loc, type, true);
10210
 
10211
    CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10212
      return fold_builtin_inf (loc, type, false);
10213
 
10214
    case BUILT_IN_CLASSIFY_TYPE:
10215
      return fold_builtin_classify_type (NULL_TREE);
10216
 
10217
    default:
10218
      break;
10219
    }
10220
  return NULL_TREE;
10221
}
10222
 
10223
/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10224
   IGNORE is true if the result of the function call is ignored.  This
10225
   function returns NULL_TREE if no simplification was possible.  */
10226
 
10227
static tree
10228
fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
10229
{
10230
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
10231
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10232
  switch (fcode)
10233
    {
10234
    case BUILT_IN_CONSTANT_P:
10235
      {
10236
        tree val = fold_builtin_constant_p (arg0);
10237
 
10238
        /* Gimplification will pull the CALL_EXPR for the builtin out of
10239
           an if condition.  When not optimizing, we'll not CSE it back.
10240
           To avoid link error types of regressions, return false now.  */
10241
        if (!val && !optimize)
10242
          val = integer_zero_node;
10243
 
10244
        return val;
10245
      }
10246
 
10247
    case BUILT_IN_CLASSIFY_TYPE:
10248
      return fold_builtin_classify_type (arg0);
10249
 
10250
    case BUILT_IN_STRLEN:
10251
      return fold_builtin_strlen (loc, type, arg0);
10252
 
10253
    CASE_FLT_FN (BUILT_IN_FABS):
10254
      return fold_builtin_fabs (loc, arg0, type);
10255
 
10256
    case BUILT_IN_ABS:
10257
    case BUILT_IN_LABS:
10258
    case BUILT_IN_LLABS:
10259
    case BUILT_IN_IMAXABS:
10260
      return fold_builtin_abs (loc, arg0, type);
10261
 
10262
    CASE_FLT_FN (BUILT_IN_CONJ):
10263
      if (validate_arg (arg0, COMPLEX_TYPE)
10264
        && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10265
        return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
10266
    break;
10267
 
10268
    CASE_FLT_FN (BUILT_IN_CREAL):
10269
      if (validate_arg (arg0, COMPLEX_TYPE)
10270
        && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10271
        return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
10272
    break;
10273
 
10274
    CASE_FLT_FN (BUILT_IN_CIMAG):
10275
      if (validate_arg (arg0, COMPLEX_TYPE)
10276
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10277
        return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
10278
    break;
10279
 
10280
    CASE_FLT_FN (BUILT_IN_CCOS):
10281
      return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
10282
 
10283
    CASE_FLT_FN (BUILT_IN_CCOSH):
10284
      return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
10285
 
10286
    CASE_FLT_FN (BUILT_IN_CPROJ):
10287
      return fold_builtin_cproj(loc, arg0, type);
10288
 
10289
    CASE_FLT_FN (BUILT_IN_CSIN):
10290
      if (validate_arg (arg0, COMPLEX_TYPE)
10291
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10292
        return do_mpc_arg1 (arg0, type, mpc_sin);
10293
    break;
10294
 
10295
    CASE_FLT_FN (BUILT_IN_CSINH):
10296
      if (validate_arg (arg0, COMPLEX_TYPE)
10297
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10298
        return do_mpc_arg1 (arg0, type, mpc_sinh);
10299
    break;
10300
 
10301
    CASE_FLT_FN (BUILT_IN_CTAN):
10302
      if (validate_arg (arg0, COMPLEX_TYPE)
10303
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10304
        return do_mpc_arg1 (arg0, type, mpc_tan);
10305
    break;
10306
 
10307
    CASE_FLT_FN (BUILT_IN_CTANH):
10308
      if (validate_arg (arg0, COMPLEX_TYPE)
10309
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10310
        return do_mpc_arg1 (arg0, type, mpc_tanh);
10311
    break;
10312
 
10313
    CASE_FLT_FN (BUILT_IN_CLOG):
10314
      if (validate_arg (arg0, COMPLEX_TYPE)
10315
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10316
        return do_mpc_arg1 (arg0, type, mpc_log);
10317
    break;
10318
 
10319
    CASE_FLT_FN (BUILT_IN_CSQRT):
10320
      if (validate_arg (arg0, COMPLEX_TYPE)
10321
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10322
        return do_mpc_arg1 (arg0, type, mpc_sqrt);
10323
    break;
10324
 
10325
    CASE_FLT_FN (BUILT_IN_CASIN):
10326
      if (validate_arg (arg0, COMPLEX_TYPE)
10327
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10328
        return do_mpc_arg1 (arg0, type, mpc_asin);
10329
    break;
10330
 
10331
    CASE_FLT_FN (BUILT_IN_CACOS):
10332
      if (validate_arg (arg0, COMPLEX_TYPE)
10333
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10334
        return do_mpc_arg1 (arg0, type, mpc_acos);
10335
    break;
10336
 
10337
    CASE_FLT_FN (BUILT_IN_CATAN):
10338
      if (validate_arg (arg0, COMPLEX_TYPE)
10339
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10340
        return do_mpc_arg1 (arg0, type, mpc_atan);
10341
    break;
10342
 
10343
    CASE_FLT_FN (BUILT_IN_CASINH):
10344
      if (validate_arg (arg0, COMPLEX_TYPE)
10345
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10346
        return do_mpc_arg1 (arg0, type, mpc_asinh);
10347
    break;
10348
 
10349
    CASE_FLT_FN (BUILT_IN_CACOSH):
10350
      if (validate_arg (arg0, COMPLEX_TYPE)
10351
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10352
        return do_mpc_arg1 (arg0, type, mpc_acosh);
10353
    break;
10354
 
10355
    CASE_FLT_FN (BUILT_IN_CATANH):
10356
      if (validate_arg (arg0, COMPLEX_TYPE)
10357
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10358
        return do_mpc_arg1 (arg0, type, mpc_atanh);
10359
    break;
10360
 
10361
    CASE_FLT_FN (BUILT_IN_CABS):
10362
      return fold_builtin_cabs (loc, arg0, type, fndecl);
10363
 
10364
    CASE_FLT_FN (BUILT_IN_CARG):
10365
      return fold_builtin_carg (loc, arg0, type);
10366
 
10367
    CASE_FLT_FN (BUILT_IN_SQRT):
10368
      return fold_builtin_sqrt (loc, arg0, type);
10369
 
10370
    CASE_FLT_FN (BUILT_IN_CBRT):
10371
      return fold_builtin_cbrt (loc, arg0, type);
10372
 
10373
    CASE_FLT_FN (BUILT_IN_ASIN):
10374
      if (validate_arg (arg0, REAL_TYPE))
10375
        return do_mpfr_arg1 (arg0, type, mpfr_asin,
10376
                             &dconstm1, &dconst1, true);
10377
    break;
10378
 
10379
    CASE_FLT_FN (BUILT_IN_ACOS):
10380
      if (validate_arg (arg0, REAL_TYPE))
10381
        return do_mpfr_arg1 (arg0, type, mpfr_acos,
10382
                             &dconstm1, &dconst1, true);
10383
    break;
10384
 
10385
    CASE_FLT_FN (BUILT_IN_ATAN):
10386
      if (validate_arg (arg0, REAL_TYPE))
10387
        return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10388
    break;
10389
 
10390
    CASE_FLT_FN (BUILT_IN_ASINH):
10391
      if (validate_arg (arg0, REAL_TYPE))
10392
        return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10393
    break;
10394
 
10395
    CASE_FLT_FN (BUILT_IN_ACOSH):
10396
      if (validate_arg (arg0, REAL_TYPE))
10397
        return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10398
                             &dconst1, NULL, true);
10399
    break;
10400
 
10401
    CASE_FLT_FN (BUILT_IN_ATANH):
10402
      if (validate_arg (arg0, REAL_TYPE))
10403
        return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10404
                             &dconstm1, &dconst1, false);
10405
    break;
10406
 
10407
    CASE_FLT_FN (BUILT_IN_SIN):
10408
      if (validate_arg (arg0, REAL_TYPE))
10409
        return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10410
    break;
10411
 
10412
    CASE_FLT_FN (BUILT_IN_COS):
10413
      return fold_builtin_cos (loc, arg0, type, fndecl);
10414
 
10415
    CASE_FLT_FN (BUILT_IN_TAN):
10416
      return fold_builtin_tan (arg0, type);
10417
 
10418
    CASE_FLT_FN (BUILT_IN_CEXP):
10419
      return fold_builtin_cexp (loc, arg0, type);
10420
 
10421
    CASE_FLT_FN (BUILT_IN_CEXPI):
10422
      if (validate_arg (arg0, REAL_TYPE))
10423
        return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10424
    break;
10425
 
10426
    CASE_FLT_FN (BUILT_IN_SINH):
10427
      if (validate_arg (arg0, REAL_TYPE))
10428
        return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10429
    break;
10430
 
10431
    CASE_FLT_FN (BUILT_IN_COSH):
10432
      return fold_builtin_cosh (loc, arg0, type, fndecl);
10433
 
10434
    CASE_FLT_FN (BUILT_IN_TANH):
10435
      if (validate_arg (arg0, REAL_TYPE))
10436
        return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10437
    break;
10438
 
10439
    CASE_FLT_FN (BUILT_IN_ERF):
10440
      if (validate_arg (arg0, REAL_TYPE))
10441
        return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10442
    break;
10443
 
10444
    CASE_FLT_FN (BUILT_IN_ERFC):
10445
      if (validate_arg (arg0, REAL_TYPE))
10446
        return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10447
    break;
10448
 
10449
    CASE_FLT_FN (BUILT_IN_TGAMMA):
10450
      if (validate_arg (arg0, REAL_TYPE))
10451
        return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10452
    break;
10453
 
10454
    CASE_FLT_FN (BUILT_IN_EXP):
10455
      return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
10456
 
10457
    CASE_FLT_FN (BUILT_IN_EXP2):
10458
      return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
10459
 
10460
    CASE_FLT_FN (BUILT_IN_EXP10):
10461
    CASE_FLT_FN (BUILT_IN_POW10):
10462
      return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
10463
 
10464
    CASE_FLT_FN (BUILT_IN_EXPM1):
10465
      if (validate_arg (arg0, REAL_TYPE))
10466
        return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10467
    break;
10468
 
10469
    CASE_FLT_FN (BUILT_IN_LOG):
10470
    return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
10471
 
10472
    CASE_FLT_FN (BUILT_IN_LOG2):
10473
      return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
10474
 
10475
    CASE_FLT_FN (BUILT_IN_LOG10):
10476
      return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
10477
 
10478
    CASE_FLT_FN (BUILT_IN_LOG1P):
10479
      if (validate_arg (arg0, REAL_TYPE))
10480
        return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10481
                             &dconstm1, NULL, false);
10482
    break;
10483
 
10484
    CASE_FLT_FN (BUILT_IN_J0):
10485
      if (validate_arg (arg0, REAL_TYPE))
10486
        return do_mpfr_arg1 (arg0, type, mpfr_j0,
10487
                             NULL, NULL, 0);
10488
    break;
10489
 
10490
    CASE_FLT_FN (BUILT_IN_J1):
10491
      if (validate_arg (arg0, REAL_TYPE))
10492
        return do_mpfr_arg1 (arg0, type, mpfr_j1,
10493
                             NULL, NULL, 0);
10494
    break;
10495
 
10496
    CASE_FLT_FN (BUILT_IN_Y0):
10497
      if (validate_arg (arg0, REAL_TYPE))
10498
        return do_mpfr_arg1 (arg0, type, mpfr_y0,
10499
                             &dconst0, NULL, false);
10500
    break;
10501
 
10502
    CASE_FLT_FN (BUILT_IN_Y1):
10503
      if (validate_arg (arg0, REAL_TYPE))
10504
        return do_mpfr_arg1 (arg0, type, mpfr_y1,
10505
                             &dconst0, NULL, false);
10506
    break;
10507
 
10508
    CASE_FLT_FN (BUILT_IN_NAN):
10509
    case BUILT_IN_NAND32:
10510
    case BUILT_IN_NAND64:
10511
    case BUILT_IN_NAND128:
10512
      return fold_builtin_nan (arg0, type, true);
10513
 
10514
    CASE_FLT_FN (BUILT_IN_NANS):
10515
      return fold_builtin_nan (arg0, type, false);
10516
 
10517
    CASE_FLT_FN (BUILT_IN_FLOOR):
10518
      return fold_builtin_floor (loc, fndecl, arg0);
10519
 
10520
    CASE_FLT_FN (BUILT_IN_CEIL):
10521
      return fold_builtin_ceil (loc, fndecl, arg0);
10522
 
10523
    CASE_FLT_FN (BUILT_IN_TRUNC):
10524
      return fold_builtin_trunc (loc, fndecl, arg0);
10525
 
10526
    CASE_FLT_FN (BUILT_IN_ROUND):
10527
      return fold_builtin_round (loc, fndecl, arg0);
10528
 
10529
    CASE_FLT_FN (BUILT_IN_NEARBYINT):
10530
    CASE_FLT_FN (BUILT_IN_RINT):
10531
      return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
10532
 
10533
    CASE_FLT_FN (BUILT_IN_ICEIL):
10534
    CASE_FLT_FN (BUILT_IN_LCEIL):
10535
    CASE_FLT_FN (BUILT_IN_LLCEIL):
10536
    CASE_FLT_FN (BUILT_IN_LFLOOR):
10537
    CASE_FLT_FN (BUILT_IN_IFLOOR):
10538
    CASE_FLT_FN (BUILT_IN_LLFLOOR):
10539
    CASE_FLT_FN (BUILT_IN_IROUND):
10540
    CASE_FLT_FN (BUILT_IN_LROUND):
10541
    CASE_FLT_FN (BUILT_IN_LLROUND):
10542
      return fold_builtin_int_roundingfn (loc, fndecl, arg0);
10543
 
10544
    CASE_FLT_FN (BUILT_IN_IRINT):
10545
    CASE_FLT_FN (BUILT_IN_LRINT):
10546
    CASE_FLT_FN (BUILT_IN_LLRINT):
10547
      return fold_fixed_mathfn (loc, fndecl, arg0);
10548
 
10549
    case BUILT_IN_BSWAP32:
10550
    case BUILT_IN_BSWAP64:
10551
      return fold_builtin_bswap (fndecl, arg0);
10552
 
10553
    CASE_INT_FN (BUILT_IN_FFS):
10554
    CASE_INT_FN (BUILT_IN_CLZ):
10555
    CASE_INT_FN (BUILT_IN_CTZ):
10556
    CASE_INT_FN (BUILT_IN_CLRSB):
10557
    CASE_INT_FN (BUILT_IN_POPCOUNT):
10558
    CASE_INT_FN (BUILT_IN_PARITY):
10559
      return fold_builtin_bitop (fndecl, arg0);
10560
 
10561
    CASE_FLT_FN (BUILT_IN_SIGNBIT):
10562
      return fold_builtin_signbit (loc, arg0, type);
10563
 
10564
    CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10565
      return fold_builtin_significand (loc, arg0, type);
10566
 
10567
    CASE_FLT_FN (BUILT_IN_ILOGB):
10568
    CASE_FLT_FN (BUILT_IN_LOGB):
10569
      return fold_builtin_logb (loc, arg0, type);
10570
 
10571
    case BUILT_IN_ISASCII:
10572
      return fold_builtin_isascii (loc, arg0);
10573
 
10574
    case BUILT_IN_TOASCII:
10575
      return fold_builtin_toascii (loc, arg0);
10576
 
10577
    case BUILT_IN_ISDIGIT:
10578
      return fold_builtin_isdigit (loc, arg0);
10579
 
10580
    CASE_FLT_FN (BUILT_IN_FINITE):
10581
    case BUILT_IN_FINITED32:
10582
    case BUILT_IN_FINITED64:
10583
    case BUILT_IN_FINITED128:
10584
    case BUILT_IN_ISFINITE:
10585
      {
10586
        tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10587
        if (ret)
10588
          return ret;
10589
        return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10590
      }
10591
 
10592
    CASE_FLT_FN (BUILT_IN_ISINF):
10593
    case BUILT_IN_ISINFD32:
10594
    case BUILT_IN_ISINFD64:
10595
    case BUILT_IN_ISINFD128:
10596
      {
10597
        tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10598
        if (ret)
10599
          return ret;
10600
        return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10601
      }
10602
 
10603
    case BUILT_IN_ISNORMAL:
10604
      return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10605
 
10606
    case BUILT_IN_ISINF_SIGN:
10607
      return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
10608
 
10609
    CASE_FLT_FN (BUILT_IN_ISNAN):
10610
    case BUILT_IN_ISNAND32:
10611
    case BUILT_IN_ISNAND64:
10612
    case BUILT_IN_ISNAND128:
10613
      return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
10614
 
10615
    case BUILT_IN_PRINTF:
10616
    case BUILT_IN_PRINTF_UNLOCKED:
10617
    case BUILT_IN_VPRINTF:
10618
      return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
10619
 
10620
    case BUILT_IN_FREE:
10621
      if (integer_zerop (arg0))
10622
        return build_empty_stmt (loc);
10623
      break;
10624
 
10625
    default:
10626
      break;
10627
    }
10628
 
10629
  return NULL_TREE;
10630
 
10631
}
10632
 
10633
/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10634
   IGNORE is true if the result of the function call is ignored.  This
10635
   function returns NULL_TREE if no simplification was possible.  */
10636
 
10637
static tree
10638
fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
10639
{
10640
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
10641
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10642
 
10643
  switch (fcode)
10644
    {
10645
    CASE_FLT_FN (BUILT_IN_JN):
10646
      if (validate_arg (arg0, INTEGER_TYPE)
10647
          && validate_arg (arg1, REAL_TYPE))
10648
        return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10649
    break;
10650
 
10651
    CASE_FLT_FN (BUILT_IN_YN):
10652
      if (validate_arg (arg0, INTEGER_TYPE)
10653
          && validate_arg (arg1, REAL_TYPE))
10654
        return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10655
                                 &dconst0, false);
10656
    break;
10657
 
10658
    CASE_FLT_FN (BUILT_IN_DREM):
10659
    CASE_FLT_FN (BUILT_IN_REMAINDER):
10660
      if (validate_arg (arg0, REAL_TYPE)
10661
          && validate_arg(arg1, REAL_TYPE))
10662
        return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10663
    break;
10664
 
10665
    CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10666
    CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10667
      if (validate_arg (arg0, REAL_TYPE)
10668
          && validate_arg(arg1, POINTER_TYPE))
10669
        return do_mpfr_lgamma_r (arg0, arg1, type);
10670
    break;
10671
 
10672
    CASE_FLT_FN (BUILT_IN_ATAN2):
10673
      if (validate_arg (arg0, REAL_TYPE)
10674
          && validate_arg(arg1, REAL_TYPE))
10675
        return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10676
    break;
10677
 
10678
    CASE_FLT_FN (BUILT_IN_FDIM):
10679
      if (validate_arg (arg0, REAL_TYPE)
10680
          && validate_arg(arg1, REAL_TYPE))
10681
        return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10682
    break;
10683
 
10684
    CASE_FLT_FN (BUILT_IN_HYPOT):
10685
      return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
10686
 
10687
    CASE_FLT_FN (BUILT_IN_CPOW):
10688
      if (validate_arg (arg0, COMPLEX_TYPE)
10689
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10690
          && validate_arg (arg1, COMPLEX_TYPE)
10691
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
10692
        return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
10693
    break;
10694
 
10695
    CASE_FLT_FN (BUILT_IN_LDEXP):
10696
      return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
10697
    CASE_FLT_FN (BUILT_IN_SCALBN):
10698
    CASE_FLT_FN (BUILT_IN_SCALBLN):
10699
      return fold_builtin_load_exponent (loc, arg0, arg1,
10700
                                         type, /*ldexp=*/false);
10701
 
10702
    CASE_FLT_FN (BUILT_IN_FREXP):
10703
      return fold_builtin_frexp (loc, arg0, arg1, type);
10704
 
10705
    CASE_FLT_FN (BUILT_IN_MODF):
10706
      return fold_builtin_modf (loc, arg0, arg1, type);
10707
 
10708
    case BUILT_IN_BZERO:
10709
      return fold_builtin_bzero (loc, arg0, arg1, ignore);
10710
 
10711
    case BUILT_IN_FPUTS:
10712
      return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
10713
 
10714
    case BUILT_IN_FPUTS_UNLOCKED:
10715
      return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
10716
 
10717
    case BUILT_IN_STRSTR:
10718
      return fold_builtin_strstr (loc, arg0, arg1, type);
10719
 
10720
    case BUILT_IN_STRCAT:
10721
      return fold_builtin_strcat (loc, arg0, arg1);
10722
 
10723
    case BUILT_IN_STRSPN:
10724
      return fold_builtin_strspn (loc, arg0, arg1);
10725
 
10726
    case BUILT_IN_STRCSPN:
10727
      return fold_builtin_strcspn (loc, arg0, arg1);
10728
 
10729
    case BUILT_IN_STRCHR:
10730
    case BUILT_IN_INDEX:
10731
      return fold_builtin_strchr (loc, arg0, arg1, type);
10732
 
10733
    case BUILT_IN_STRRCHR:
10734
    case BUILT_IN_RINDEX:
10735
      return fold_builtin_strrchr (loc, arg0, arg1, type);
10736
 
10737
    case BUILT_IN_STRCPY:
10738
      return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
10739
 
10740
    case BUILT_IN_STPCPY:
10741
      if (ignore)
10742
        {
10743
          tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
10744
          if (!fn)
10745
            break;
10746
 
10747
          return build_call_expr_loc (loc, fn, 2, arg0, arg1);
10748
        }
10749
      else
10750
        return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
10751
      break;
10752
 
10753
    case BUILT_IN_STRCMP:
10754
      return fold_builtin_strcmp (loc, arg0, arg1);
10755
 
10756
    case BUILT_IN_STRPBRK:
10757
      return fold_builtin_strpbrk (loc, arg0, arg1, type);
10758
 
10759
    case BUILT_IN_EXPECT:
10760
      return fold_builtin_expect (loc, arg0, arg1);
10761
 
10762
    CASE_FLT_FN (BUILT_IN_POW):
10763
      return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
10764
 
10765
    CASE_FLT_FN (BUILT_IN_POWI):
10766
      return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
10767
 
10768
    CASE_FLT_FN (BUILT_IN_COPYSIGN):
10769
      return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
10770
 
10771
    CASE_FLT_FN (BUILT_IN_FMIN):
10772
      return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
10773
 
10774
    CASE_FLT_FN (BUILT_IN_FMAX):
10775
      return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
10776
 
10777
    case BUILT_IN_ISGREATER:
10778
      return fold_builtin_unordered_cmp (loc, fndecl,
10779
                                         arg0, arg1, UNLE_EXPR, LE_EXPR);
10780
    case BUILT_IN_ISGREATEREQUAL:
10781
      return fold_builtin_unordered_cmp (loc, fndecl,
10782
                                         arg0, arg1, UNLT_EXPR, LT_EXPR);
10783
    case BUILT_IN_ISLESS:
10784
      return fold_builtin_unordered_cmp (loc, fndecl,
10785
                                         arg0, arg1, UNGE_EXPR, GE_EXPR);
10786
    case BUILT_IN_ISLESSEQUAL:
10787
      return fold_builtin_unordered_cmp (loc, fndecl,
10788
                                         arg0, arg1, UNGT_EXPR, GT_EXPR);
10789
    case BUILT_IN_ISLESSGREATER:
10790
      return fold_builtin_unordered_cmp (loc, fndecl,
10791
                                         arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10792
    case BUILT_IN_ISUNORDERED:
10793
      return fold_builtin_unordered_cmp (loc, fndecl,
10794
                                         arg0, arg1, UNORDERED_EXPR,
10795
                                         NOP_EXPR);
10796
 
10797
      /* We do the folding for va_start in the expander.  */
10798
    case BUILT_IN_VA_START:
10799
      break;
10800
 
10801
    case BUILT_IN_SPRINTF:
10802
      return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
10803
 
10804
    case BUILT_IN_OBJECT_SIZE:
10805
      return fold_builtin_object_size (arg0, arg1);
10806
 
10807
    case BUILT_IN_PRINTF:
10808
    case BUILT_IN_PRINTF_UNLOCKED:
10809
    case BUILT_IN_VPRINTF:
10810
      return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
10811
 
10812
    case BUILT_IN_PRINTF_CHK:
10813
    case BUILT_IN_VPRINTF_CHK:
10814
      if (!validate_arg (arg0, INTEGER_TYPE)
10815
          || TREE_SIDE_EFFECTS (arg0))
10816
        return NULL_TREE;
10817
      else
10818
        return fold_builtin_printf (loc, fndecl,
10819
                                    arg1, NULL_TREE, ignore, fcode);
10820
    break;
10821
 
10822
    case BUILT_IN_FPRINTF:
10823
    case BUILT_IN_FPRINTF_UNLOCKED:
10824
    case BUILT_IN_VFPRINTF:
10825
      return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
10826
                                   ignore, fcode);
10827
 
10828
    case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
10829
      return fold_builtin_atomic_always_lock_free (arg0, arg1);
10830
 
10831
    case BUILT_IN_ATOMIC_IS_LOCK_FREE:
10832
      return fold_builtin_atomic_is_lock_free (arg0, arg1);
10833
 
10834
    default:
10835
      break;
10836
    }
10837
  return NULL_TREE;
10838
}
10839
 
10840
/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10841
   and ARG2.  IGNORE is true if the result of the function call is ignored.
10842
   This function returns NULL_TREE if no simplification was possible.  */
10843
 
10844
static tree
10845
fold_builtin_3 (location_t loc, tree fndecl,
10846
                tree arg0, tree arg1, tree arg2, bool ignore)
10847
{
10848
  tree type = TREE_TYPE (TREE_TYPE (fndecl));
10849
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10850
  switch (fcode)
10851
    {
10852
 
10853
    CASE_FLT_FN (BUILT_IN_SINCOS):
10854
      return fold_builtin_sincos (loc, arg0, arg1, arg2);
10855
 
10856
    CASE_FLT_FN (BUILT_IN_FMA):
10857
      return fold_builtin_fma (loc, arg0, arg1, arg2, type);
10858
    break;
10859
 
10860
    CASE_FLT_FN (BUILT_IN_REMQUO):
10861
      if (validate_arg (arg0, REAL_TYPE)
10862
          && validate_arg(arg1, REAL_TYPE)
10863
          && validate_arg(arg2, POINTER_TYPE))
10864
        return do_mpfr_remquo (arg0, arg1, arg2);
10865
    break;
10866
 
10867
    case BUILT_IN_MEMSET:
10868
      return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
10869
 
10870
    case BUILT_IN_BCOPY:
10871
      return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10872
                                     void_type_node, true, /*endp=*/3);
10873
 
10874
    case BUILT_IN_MEMCPY:
10875
      return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10876
                                     type, ignore, /*endp=*/0);
10877
 
10878
    case BUILT_IN_MEMPCPY:
10879
      return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10880
                                     type, ignore, /*endp=*/1);
10881
 
10882
    case BUILT_IN_MEMMOVE:
10883
      return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10884
                                     type, ignore, /*endp=*/3);
10885
 
10886
    case BUILT_IN_STRNCAT:
10887
      return fold_builtin_strncat (loc, arg0, arg1, arg2);
10888
 
10889
    case BUILT_IN_STRNCPY:
10890
      return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
10891
 
10892
    case BUILT_IN_STRNCMP:
10893
      return fold_builtin_strncmp (loc, arg0, arg1, arg2);
10894
 
10895
    case BUILT_IN_MEMCHR:
10896
      return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
10897
 
10898
    case BUILT_IN_BCMP:
10899
    case BUILT_IN_MEMCMP:
10900
      return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
10901
 
10902
    case BUILT_IN_SPRINTF:
10903
      return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
10904
 
10905
    case BUILT_IN_SNPRINTF:
10906
      return fold_builtin_snprintf (loc, arg0, arg1, arg2, NULL_TREE, ignore);
10907
 
10908
    case BUILT_IN_STRCPY_CHK:
10909
    case BUILT_IN_STPCPY_CHK:
10910
      return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
10911
                                      ignore, fcode);
10912
 
10913
    case BUILT_IN_STRCAT_CHK:
10914
      return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
10915
 
10916
    case BUILT_IN_PRINTF_CHK:
10917
    case BUILT_IN_VPRINTF_CHK:
10918
      if (!validate_arg (arg0, INTEGER_TYPE)
10919
          || TREE_SIDE_EFFECTS (arg0))
10920
        return NULL_TREE;
10921
      else
10922
        return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
10923
    break;
10924
 
10925
    case BUILT_IN_FPRINTF:
10926
    case BUILT_IN_FPRINTF_UNLOCKED:
10927
    case BUILT_IN_VFPRINTF:
10928
      return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10929
                                   ignore, fcode);
10930
 
10931
    case BUILT_IN_FPRINTF_CHK:
10932
    case BUILT_IN_VFPRINTF_CHK:
10933
      if (!validate_arg (arg1, INTEGER_TYPE)
10934
          || TREE_SIDE_EFFECTS (arg1))
10935
        return NULL_TREE;
10936
      else
10937
        return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
10938
                                     ignore, fcode);
10939
 
10940
    default:
10941
      break;
10942
    }
10943
  return NULL_TREE;
10944
}
10945
 
10946
/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10947
   ARG2, and ARG3.  IGNORE is true if the result of the function call is
10948
   ignored.  This function returns NULL_TREE if no simplification was
10949
   possible.  */
10950
 
10951
static tree
10952
fold_builtin_4 (location_t loc, tree fndecl,
10953
                tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
10954
{
10955
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10956
 
10957
  switch (fcode)
10958
    {
10959
    case BUILT_IN_MEMCPY_CHK:
10960
    case BUILT_IN_MEMPCPY_CHK:
10961
    case BUILT_IN_MEMMOVE_CHK:
10962
    case BUILT_IN_MEMSET_CHK:
10963
      return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
10964
                                      NULL_TREE, ignore,
10965
                                      DECL_FUNCTION_CODE (fndecl));
10966
 
10967
    case BUILT_IN_STRNCPY_CHK:
10968
    case BUILT_IN_STPNCPY_CHK:
10969
      return fold_builtin_stxncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE,
10970
                                       ignore, fcode);
10971
 
10972
    case BUILT_IN_STRNCAT_CHK:
10973
      return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
10974
 
10975
    case BUILT_IN_SNPRINTF:
10976
      return fold_builtin_snprintf (loc, arg0, arg1, arg2, arg3, ignore);
10977
 
10978
    case BUILT_IN_FPRINTF_CHK:
10979
    case BUILT_IN_VFPRINTF_CHK:
10980
      if (!validate_arg (arg1, INTEGER_TYPE)
10981
          || TREE_SIDE_EFFECTS (arg1))
10982
        return NULL_TREE;
10983
      else
10984
        return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
10985
                                     ignore, fcode);
10986
    break;
10987
 
10988
    default:
10989
      break;
10990
    }
10991
  return NULL_TREE;
10992
}
10993
 
10994
/* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
10995
    arguments, where NARGS <= 4.  IGNORE is true if the result of the
10996
    function call is ignored.  This function returns NULL_TREE if no
10997
    simplification was possible.  Note that this only folds builtins with
10998
    fixed argument patterns.  Foldings that do varargs-to-varargs
10999
    transformations, or that match calls with more than 4 arguments,
11000
    need to be handled with fold_builtin_varargs instead.  */
11001
 
11002
#define MAX_ARGS_TO_FOLD_BUILTIN 4
11003
 
11004
static tree
11005
fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
11006
{
11007
  tree ret = NULL_TREE;
11008
 
11009
  switch (nargs)
11010
    {
11011
    case 0:
11012
      ret = fold_builtin_0 (loc, fndecl, ignore);
11013
      break;
11014
    case 1:
11015
      ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
11016
      break;
11017
    case 2:
11018
      ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
11019
      break;
11020
    case 3:
11021
      ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
11022
      break;
11023
    case 4:
11024
      ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
11025
                            ignore);
11026
      break;
11027
    default:
11028
      break;
11029
    }
11030
  if (ret)
11031
    {
11032
      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11033
      SET_EXPR_LOCATION (ret, loc);
11034
      TREE_NO_WARNING (ret) = 1;
11035
      return ret;
11036
    }
11037
  return NULL_TREE;
11038
}
11039
 
11040
/* Builtins with folding operations that operate on "..." arguments
11041
   need special handling; we need to store the arguments in a convenient
11042
   data structure before attempting any folding.  Fortunately there are
11043
   only a few builtins that fall into this category.  FNDECL is the
11044
   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
11045
   result of the function call is ignored.  */
11046
 
11047
static tree
11048
fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
11049
                      bool ignore ATTRIBUTE_UNUSED)
11050
{
11051
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11052
  tree ret = NULL_TREE;
11053
 
11054
  switch (fcode)
11055
    {
11056
    case BUILT_IN_SPRINTF_CHK:
11057
    case BUILT_IN_VSPRINTF_CHK:
11058
      ret = fold_builtin_sprintf_chk (loc, exp, fcode);
11059
      break;
11060
 
11061
    case BUILT_IN_SNPRINTF_CHK:
11062
    case BUILT_IN_VSNPRINTF_CHK:
11063
      ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
11064
      break;
11065
 
11066
    case BUILT_IN_FPCLASSIFY:
11067
      ret = fold_builtin_fpclassify (loc, exp);
11068
      break;
11069
 
11070
    default:
11071
      break;
11072
    }
11073
  if (ret)
11074
    {
11075
      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11076
      SET_EXPR_LOCATION (ret, loc);
11077
      TREE_NO_WARNING (ret) = 1;
11078
      return ret;
11079
    }
11080
  return NULL_TREE;
11081
}
11082
 
11083
/* Return true if FNDECL shouldn't be folded right now.
11084
   If a built-in function has an inline attribute always_inline
11085
   wrapper, defer folding it after always_inline functions have
11086
   been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11087
   might not be performed.  */
11088
 
11089
bool
11090
avoid_folding_inline_builtin (tree fndecl)
11091
{
11092
  return (DECL_DECLARED_INLINE_P (fndecl)
11093
          && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11094
          && cfun
11095
          && !cfun->always_inline_functions_inlined
11096
          && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11097
}
11098
 
11099
/* A wrapper function for builtin folding that prevents warnings for
11100
   "statement without effect" and the like, caused by removing the
11101
   call node earlier than the warning is generated.  */
11102
 
11103
tree
11104
fold_call_expr (location_t loc, tree exp, bool ignore)
11105
{
11106
  tree ret = NULL_TREE;
11107
  tree fndecl = get_callee_fndecl (exp);
11108
  if (fndecl
11109
      && TREE_CODE (fndecl) == FUNCTION_DECL
11110
      && DECL_BUILT_IN (fndecl)
11111
      /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11112
         yet.  Defer folding until we see all the arguments
11113
         (after inlining).  */
11114
      && !CALL_EXPR_VA_ARG_PACK (exp))
11115
    {
11116
      int nargs = call_expr_nargs (exp);
11117
 
11118
      /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11119
         instead last argument is __builtin_va_arg_pack ().  Defer folding
11120
         even in that case, until arguments are finalized.  */
11121
      if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11122
        {
11123
          tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11124
          if (fndecl2
11125
              && TREE_CODE (fndecl2) == FUNCTION_DECL
11126
              && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11127
              && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11128
            return NULL_TREE;
11129
        }
11130
 
11131
      if (avoid_folding_inline_builtin (fndecl))
11132
        return NULL_TREE;
11133
 
11134
      if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11135
        return targetm.fold_builtin (fndecl, call_expr_nargs (exp),
11136
                                     CALL_EXPR_ARGP (exp), ignore);
11137
      else
11138
        {
11139
          if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11140
            {
11141
              tree *args = CALL_EXPR_ARGP (exp);
11142
              ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
11143
            }
11144
          if (!ret)
11145
            ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
11146
          if (ret)
11147
            return ret;
11148
        }
11149
    }
11150
  return NULL_TREE;
11151
}
11152
 
11153
/* Conveniently construct a function call expression.  FNDECL names the
11154
   function to be called and N arguments are passed in the array
11155
   ARGARRAY.  */
11156
 
11157
tree
11158
build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
11159
{
11160
  tree fntype = TREE_TYPE (fndecl);
11161
  tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11162
 
11163
  return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
11164
}
11165
 
11166
/* Conveniently construct a function call expression.  FNDECL names the
11167
   function to be called and the arguments are passed in the vector
11168
   VEC.  */
11169
 
11170
tree
11171
build_call_expr_loc_vec (location_t loc, tree fndecl, VEC(tree,gc) *vec)
11172
{
11173
  return build_call_expr_loc_array (loc, fndecl, VEC_length (tree, vec),
11174
                                    VEC_address (tree, vec));
11175
}
11176
 
11177
 
11178
/* Conveniently construct a function call expression.  FNDECL names the
11179
   function to be called, N is the number of arguments, and the "..."
11180
   parameters are the argument expressions.  */
11181
 
11182
tree
11183
build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
11184
{
11185
  va_list ap;
11186
  tree *argarray = XALLOCAVEC (tree, n);
11187
  int i;
11188
 
11189
  va_start (ap, n);
11190
  for (i = 0; i < n; i++)
11191
    argarray[i] = va_arg (ap, tree);
11192
  va_end (ap);
11193
  return build_call_expr_loc_array (loc, fndecl, n, argarray);
11194
}
11195
 
11196
/* Like build_call_expr_loc (UNKNOWN_LOCATION, ...).  Duplicated because
11197
   varargs macros aren't supported by all bootstrap compilers.  */
11198
 
11199
tree
11200
build_call_expr (tree fndecl, int n, ...)
11201
{
11202
  va_list ap;
11203
  tree *argarray = XALLOCAVEC (tree, n);
11204
  int i;
11205
 
11206
  va_start (ap, n);
11207
  for (i = 0; i < n; i++)
11208
    argarray[i] = va_arg (ap, tree);
11209
  va_end (ap);
11210
  return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
11211
}
11212
 
11213
/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
11214
   N arguments are passed in the array ARGARRAY.  */
11215
 
11216
tree
11217
fold_builtin_call_array (location_t loc, tree type,
11218
                         tree fn,
11219
                         int n,
11220
                         tree *argarray)
11221
{
11222
  tree ret = NULL_TREE;
11223
   tree exp;
11224
 
11225
  if (TREE_CODE (fn) == ADDR_EXPR)
11226
  {
11227
    tree fndecl = TREE_OPERAND (fn, 0);
11228
    if (TREE_CODE (fndecl) == FUNCTION_DECL
11229
        && DECL_BUILT_IN (fndecl))
11230
      {
11231
        /* If last argument is __builtin_va_arg_pack (), arguments to this
11232
           function are not finalized yet.  Defer folding until they are.  */
11233
        if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11234
          {
11235
            tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11236
            if (fndecl2
11237
                && TREE_CODE (fndecl2) == FUNCTION_DECL
11238
                && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11239
                && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11240
              return build_call_array_loc (loc, type, fn, n, argarray);
11241
          }
11242
        if (avoid_folding_inline_builtin (fndecl))
11243
          return build_call_array_loc (loc, type, fn, n, argarray);
11244
        if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11245
          {
11246
            ret = targetm.fold_builtin (fndecl, n, argarray, false);
11247
            if (ret)
11248
              return ret;
11249
 
11250
            return build_call_array_loc (loc, type, fn, n, argarray);
11251
          }
11252
        else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11253
          {
11254
            /* First try the transformations that don't require consing up
11255
               an exp.  */
11256
            ret = fold_builtin_n (loc, fndecl, argarray, n, false);
11257
            if (ret)
11258
              return ret;
11259
          }
11260
 
11261
        /* If we got this far, we need to build an exp.  */
11262
        exp = build_call_array_loc (loc, type, fn, n, argarray);
11263
        ret = fold_builtin_varargs (loc, fndecl, exp, false);
11264
        return ret ? ret : exp;
11265
      }
11266
  }
11267
 
11268
  return build_call_array_loc (loc, type, fn, n, argarray);
11269
}
11270
 
11271
/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11272
   list ARGS along with N new arguments in NEWARGS.  SKIP is the number
11273
   of arguments in ARGS to be omitted.  OLDNARGS is the number of
11274
   elements in ARGS.  */
11275
 
11276
static tree
11277
rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
11278
                          int skip, tree fndecl, int n, va_list newargs)
11279
{
11280
  int nargs = oldnargs - skip + n;
11281
  tree *buffer;
11282
 
11283
  if (n > 0)
11284
    {
11285
      int i, j;
11286
 
11287
      buffer = XALLOCAVEC (tree, nargs);
11288
      for (i = 0; i < n; i++)
11289
        buffer[i] = va_arg (newargs, tree);
11290
      for (j = skip; j < oldnargs; j++, i++)
11291
        buffer[i] = args[j];
11292
    }
11293
  else
11294
    buffer = args + skip;
11295
 
11296
  return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
11297
}
11298
 
11299
/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11300
   list ARGS along with N new arguments specified as the "..."
11301
   parameters.  SKIP is the number of arguments in ARGS to be omitted.
11302
   OLDNARGS is the number of elements in ARGS.  */
11303
 
11304
static tree
11305
rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
11306
                         int skip, tree fndecl, int n, ...)
11307
{
11308
  va_list ap;
11309
  tree t;
11310
 
11311
  va_start (ap, n);
11312
  t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
11313
  va_end (ap);
11314
 
11315
  return t;
11316
}
11317
 
11318
/* Construct a new CALL_EXPR using the tail of the argument list of EXP
11319
   along with N new arguments specified as the "..." parameters.  SKIP
11320
   is the number of arguments in EXP to be omitted.  This function is used
11321
   to do varargs-to-varargs transformations.  */
11322
 
11323
static tree
11324
rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
11325
{
11326
  va_list ap;
11327
  tree t;
11328
 
11329
  va_start (ap, n);
11330
  t = rewrite_call_expr_valist (loc, call_expr_nargs (exp),
11331
                                CALL_EXPR_ARGP (exp), skip, fndecl, n, ap);
11332
  va_end (ap);
11333
 
11334
  return t;
11335
}
11336
 
11337
/* Validate a single argument ARG against a tree code CODE representing
11338
   a type.  */
11339
 
11340
static bool
11341
validate_arg (const_tree arg, enum tree_code code)
11342
{
11343
  if (!arg)
11344
    return false;
11345
  else if (code == POINTER_TYPE)
11346
    return POINTER_TYPE_P (TREE_TYPE (arg));
11347
  else if (code == INTEGER_TYPE)
11348
    return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11349
  return code == TREE_CODE (TREE_TYPE (arg));
11350
}
11351
 
11352
/* This function validates the types of a function call argument list
11353
   against a specified list of tree_codes.  If the last specifier is a 0,
11354
   that represents an ellipses, otherwise the last specifier must be a
11355
   VOID_TYPE.
11356
 
11357
   This is the GIMPLE version of validate_arglist.  Eventually we want to
11358
   completely convert builtins.c to work from GIMPLEs and the tree based
11359
   validate_arglist will then be removed.  */
11360
 
11361
bool
11362
validate_gimple_arglist (const_gimple call, ...)
11363
{
11364
  enum tree_code code;
11365
  bool res = 0;
11366
  va_list ap;
11367
  const_tree arg;
11368
  size_t i;
11369
 
11370
  va_start (ap, call);
11371
  i = 0;
11372
 
11373
  do
11374
    {
11375
      code = (enum tree_code) va_arg (ap, int);
11376
      switch (code)
11377
        {
11378
        case 0:
11379
          /* This signifies an ellipses, any further arguments are all ok.  */
11380
          res = true;
11381
          goto end;
11382
        case VOID_TYPE:
11383
          /* This signifies an endlink, if no arguments remain, return
11384
             true, otherwise return false.  */
11385
          res = (i == gimple_call_num_args (call));
11386
          goto end;
11387
        default:
11388
          /* If no parameters remain or the parameter's code does not
11389
             match the specified code, return false.  Otherwise continue
11390
             checking any remaining arguments.  */
11391
          arg = gimple_call_arg (call, i++);
11392
          if (!validate_arg (arg, code))
11393
            goto end;
11394
          break;
11395
        }
11396
    }
11397
  while (1);
11398
 
11399
  /* We need gotos here since we can only have one VA_CLOSE in a
11400
     function.  */
11401
 end: ;
11402
  va_end (ap);
11403
 
11404
  return res;
11405
}
11406
 
11407
/* This function validates the types of a function call argument list
11408
   against a specified list of tree_codes.  If the last specifier is a 0,
11409
   that represents an ellipses, otherwise the last specifier must be a
11410
   VOID_TYPE.  */
11411
 
11412
bool
11413
validate_arglist (const_tree callexpr, ...)
11414
{
11415
  enum tree_code code;
11416
  bool res = 0;
11417
  va_list ap;
11418
  const_call_expr_arg_iterator iter;
11419
  const_tree arg;
11420
 
11421
  va_start (ap, callexpr);
11422
  init_const_call_expr_arg_iterator (callexpr, &iter);
11423
 
11424
  do
11425
    {
11426
      code = (enum tree_code) va_arg (ap, int);
11427
      switch (code)
11428
        {
11429
        case 0:
11430
          /* This signifies an ellipses, any further arguments are all ok.  */
11431
          res = true;
11432
          goto end;
11433
        case VOID_TYPE:
11434
          /* This signifies an endlink, if no arguments remain, return
11435
             true, otherwise return false.  */
11436
          res = !more_const_call_expr_args_p (&iter);
11437
          goto end;
11438
        default:
11439
          /* If no parameters remain or the parameter's code does not
11440
             match the specified code, return false.  Otherwise continue
11441
             checking any remaining arguments.  */
11442
          arg = next_const_call_expr_arg (&iter);
11443
          if (!validate_arg (arg, code))
11444
            goto end;
11445
          break;
11446
        }
11447
    }
11448
  while (1);
11449
 
11450
  /* We need gotos here since we can only have one VA_CLOSE in a
11451
     function.  */
11452
 end: ;
11453
  va_end (ap);
11454
 
11455
  return res;
11456
}
11457
 
11458
/* Default target-specific builtin expander that does nothing.  */
11459
 
11460
rtx
11461
default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11462
                        rtx target ATTRIBUTE_UNUSED,
11463
                        rtx subtarget ATTRIBUTE_UNUSED,
11464
                        enum machine_mode mode ATTRIBUTE_UNUSED,
11465
                        int ignore ATTRIBUTE_UNUSED)
11466
{
11467
  return NULL_RTX;
11468
}
11469
 
11470
/* Returns true is EXP represents data that would potentially reside
11471
   in a readonly section.  */
11472
 
11473
static bool
11474
readonly_data_expr (tree exp)
11475
{
11476
  STRIP_NOPS (exp);
11477
 
11478
  if (TREE_CODE (exp) != ADDR_EXPR)
11479
    return false;
11480
 
11481
  exp = get_base_address (TREE_OPERAND (exp, 0));
11482
  if (!exp)
11483
    return false;
11484
 
11485
  /* Make sure we call decl_readonly_section only for trees it
11486
     can handle (since it returns true for everything it doesn't
11487
     understand).  */
11488
  if (TREE_CODE (exp) == STRING_CST
11489
      || TREE_CODE (exp) == CONSTRUCTOR
11490
      || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11491
    return decl_readonly_section (exp, 0);
11492
  else
11493
    return false;
11494
}
11495
 
11496
/* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
11497
   to the call, and TYPE is its return type.
11498
 
11499
   Return NULL_TREE if no simplification was possible, otherwise return the
11500
   simplified form of the call as a tree.
11501
 
11502
   The simplified form may be a constant or other expression which
11503
   computes the same value, but in a more efficient manner (including
11504
   calls to other builtin functions).
11505
 
11506
   The call may contain arguments which need to be evaluated, but
11507
   which are not useful to determine the result of the call.  In
11508
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11509
   COMPOUND_EXPR will be an argument which must be evaluated.
11510
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11511
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11512
   form of the builtin function call.  */
11513
 
11514
static tree
11515
fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
11516
{
11517
  if (!validate_arg (s1, POINTER_TYPE)
11518
      || !validate_arg (s2, POINTER_TYPE))
11519
    return NULL_TREE;
11520
  else
11521
    {
11522
      tree fn;
11523
      const char *p1, *p2;
11524
 
11525
      p2 = c_getstr (s2);
11526
      if (p2 == NULL)
11527
        return NULL_TREE;
11528
 
11529
      p1 = c_getstr (s1);
11530
      if (p1 != NULL)
11531
        {
11532
          const char *r = strstr (p1, p2);
11533
          tree tem;
11534
 
11535
          if (r == NULL)
11536
            return build_int_cst (TREE_TYPE (s1), 0);
11537
 
11538
          /* Return an offset into the constant string argument.  */
11539
          tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11540
          return fold_convert_loc (loc, type, tem);
11541
        }
11542
 
11543
      /* The argument is const char *, and the result is char *, so we need
11544
         a type conversion here to avoid a warning.  */
11545
      if (p2[0] == '\0')
11546
        return fold_convert_loc (loc, type, s1);
11547
 
11548
      if (p2[1] != '\0')
11549
        return NULL_TREE;
11550
 
11551
      fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11552
      if (!fn)
11553
        return NULL_TREE;
11554
 
11555
      /* New argument list transforming strstr(s1, s2) to
11556
         strchr(s1, s2[0]).  */
11557
      return build_call_expr_loc (loc, fn, 2, s1,
11558
                                  build_int_cst (integer_type_node, p2[0]));
11559
    }
11560
}
11561
 
11562
/* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
11563
   the call, and TYPE is its return type.
11564
 
11565
   Return NULL_TREE if no simplification was possible, otherwise return the
11566
   simplified form of the call as a tree.
11567
 
11568
   The simplified form may be a constant or other expression which
11569
   computes the same value, but in a more efficient manner (including
11570
   calls to other builtin functions).
11571
 
11572
   The call may contain arguments which need to be evaluated, but
11573
   which are not useful to determine the result of the call.  In
11574
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11575
   COMPOUND_EXPR will be an argument which must be evaluated.
11576
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11577
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11578
   form of the builtin function call.  */
11579
 
11580
static tree
11581
fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
11582
{
11583
  if (!validate_arg (s1, POINTER_TYPE)
11584
      || !validate_arg (s2, INTEGER_TYPE))
11585
    return NULL_TREE;
11586
  else
11587
    {
11588
      const char *p1;
11589
 
11590
      if (TREE_CODE (s2) != INTEGER_CST)
11591
        return NULL_TREE;
11592
 
11593
      p1 = c_getstr (s1);
11594
      if (p1 != NULL)
11595
        {
11596
          char c;
11597
          const char *r;
11598
          tree tem;
11599
 
11600
          if (target_char_cast (s2, &c))
11601
            return NULL_TREE;
11602
 
11603
          r = strchr (p1, c);
11604
 
11605
          if (r == NULL)
11606
            return build_int_cst (TREE_TYPE (s1), 0);
11607
 
11608
          /* Return an offset into the constant string argument.  */
11609
          tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11610
          return fold_convert_loc (loc, type, tem);
11611
        }
11612
      return NULL_TREE;
11613
    }
11614
}
11615
 
11616
/* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11617
   the call, and TYPE is its return type.
11618
 
11619
   Return NULL_TREE if no simplification was possible, otherwise return the
11620
   simplified form of the call as a tree.
11621
 
11622
   The simplified form may be a constant or other expression which
11623
   computes the same value, but in a more efficient manner (including
11624
   calls to other builtin functions).
11625
 
11626
   The call may contain arguments which need to be evaluated, but
11627
   which are not useful to determine the result of the call.  In
11628
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11629
   COMPOUND_EXPR will be an argument which must be evaluated.
11630
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11631
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11632
   form of the builtin function call.  */
11633
 
11634
static tree
11635
fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
11636
{
11637
  if (!validate_arg (s1, POINTER_TYPE)
11638
      || !validate_arg (s2, INTEGER_TYPE))
11639
    return NULL_TREE;
11640
  else
11641
    {
11642
      tree fn;
11643
      const char *p1;
11644
 
11645
      if (TREE_CODE (s2) != INTEGER_CST)
11646
        return NULL_TREE;
11647
 
11648
      p1 = c_getstr (s1);
11649
      if (p1 != NULL)
11650
        {
11651
          char c;
11652
          const char *r;
11653
          tree tem;
11654
 
11655
          if (target_char_cast (s2, &c))
11656
            return NULL_TREE;
11657
 
11658
          r = strrchr (p1, c);
11659
 
11660
          if (r == NULL)
11661
            return build_int_cst (TREE_TYPE (s1), 0);
11662
 
11663
          /* Return an offset into the constant string argument.  */
11664
          tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11665
          return fold_convert_loc (loc, type, tem);
11666
        }
11667
 
11668
      if (! integer_zerop (s2))
11669
        return NULL_TREE;
11670
 
11671
      fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11672
      if (!fn)
11673
        return NULL_TREE;
11674
 
11675
      /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11676
      return build_call_expr_loc (loc, fn, 2, s1, s2);
11677
    }
11678
}
11679
 
11680
/* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11681
   to the call, and TYPE is its return type.
11682
 
11683
   Return NULL_TREE if no simplification was possible, otherwise return the
11684
   simplified form of the call as a tree.
11685
 
11686
   The simplified form may be a constant or other expression which
11687
   computes the same value, but in a more efficient manner (including
11688
   calls to other builtin functions).
11689
 
11690
   The call may contain arguments which need to be evaluated, but
11691
   which are not useful to determine the result of the call.  In
11692
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11693
   COMPOUND_EXPR will be an argument which must be evaluated.
11694
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11695
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11696
   form of the builtin function call.  */
11697
 
11698
static tree
11699
fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
11700
{
11701
  if (!validate_arg (s1, POINTER_TYPE)
11702
      || !validate_arg (s2, POINTER_TYPE))
11703
    return NULL_TREE;
11704
  else
11705
    {
11706
      tree fn;
11707
      const char *p1, *p2;
11708
 
11709
      p2 = c_getstr (s2);
11710
      if (p2 == NULL)
11711
        return NULL_TREE;
11712
 
11713
      p1 = c_getstr (s1);
11714
      if (p1 != NULL)
11715
        {
11716
          const char *r = strpbrk (p1, p2);
11717
          tree tem;
11718
 
11719
          if (r == NULL)
11720
            return build_int_cst (TREE_TYPE (s1), 0);
11721
 
11722
          /* Return an offset into the constant string argument.  */
11723
          tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11724
          return fold_convert_loc (loc, type, tem);
11725
        }
11726
 
11727
      if (p2[0] == '\0')
11728
        /* strpbrk(x, "") == NULL.
11729
           Evaluate and ignore s1 in case it had side-effects.  */
11730
        return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
11731
 
11732
      if (p2[1] != '\0')
11733
        return NULL_TREE;  /* Really call strpbrk.  */
11734
 
11735
      fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11736
      if (!fn)
11737
        return NULL_TREE;
11738
 
11739
      /* New argument list transforming strpbrk(s1, s2) to
11740
         strchr(s1, s2[0]).  */
11741
      return build_call_expr_loc (loc, fn, 2, s1,
11742
                                  build_int_cst (integer_type_node, p2[0]));
11743
    }
11744
}
11745
 
11746
/* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11747
   to the call.
11748
 
11749
   Return NULL_TREE if no simplification was possible, otherwise return the
11750
   simplified form of the call as a tree.
11751
 
11752
   The simplified form may be a constant or other expression which
11753
   computes the same value, but in a more efficient manner (including
11754
   calls to other builtin functions).
11755
 
11756
   The call may contain arguments which need to be evaluated, but
11757
   which are not useful to determine the result of the call.  In
11758
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11759
   COMPOUND_EXPR will be an argument which must be evaluated.
11760
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11761
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11762
   form of the builtin function call.  */
11763
 
11764
static tree
11765
fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
11766
{
11767
  if (!validate_arg (dst, POINTER_TYPE)
11768
      || !validate_arg (src, POINTER_TYPE))
11769
    return NULL_TREE;
11770
  else
11771
    {
11772
      const char *p = c_getstr (src);
11773
 
11774
      /* If the string length is zero, return the dst parameter.  */
11775
      if (p && *p == '\0')
11776
        return dst;
11777
 
11778
      if (optimize_insn_for_speed_p ())
11779
        {
11780
          /* See if we can store by pieces into (dst + strlen(dst)).  */
11781
          tree newdst, call;
11782
          tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11783
          tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY);
11784
 
11785
          if (!strlen_fn || !strcpy_fn)
11786
            return NULL_TREE;
11787
 
11788
          /* If we don't have a movstr we don't want to emit an strcpy
11789
             call.  We have to do that if the length of the source string
11790
             isn't computable (in that case we can use memcpy probably
11791
             later expanding to a sequence of mov instructions).  If we
11792
             have movstr instructions we can emit strcpy calls.  */
11793
          if (!HAVE_movstr)
11794
            {
11795
              tree len = c_strlen (src, 1);
11796
              if (! len || TREE_SIDE_EFFECTS (len))
11797
                return NULL_TREE;
11798
            }
11799
 
11800
          /* Stabilize the argument list.  */
11801
          dst = builtin_save_expr (dst);
11802
 
11803
          /* Create strlen (dst).  */
11804
          newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11805
          /* Create (dst p+ strlen (dst)).  */
11806
 
11807
          newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
11808
          newdst = builtin_save_expr (newdst);
11809
 
11810
          call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11811
          return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11812
        }
11813
      return NULL_TREE;
11814
    }
11815
}
11816
 
11817
/* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11818
   arguments to the call.
11819
 
11820
   Return NULL_TREE if no simplification was possible, otherwise return the
11821
   simplified form of the call as a tree.
11822
 
11823
   The simplified form may be a constant or other expression which
11824
   computes the same value, but in a more efficient manner (including
11825
   calls to other builtin functions).
11826
 
11827
   The call may contain arguments which need to be evaluated, but
11828
   which are not useful to determine the result of the call.  In
11829
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11830
   COMPOUND_EXPR will be an argument which must be evaluated.
11831
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11832
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11833
   form of the builtin function call.  */
11834
 
11835
static tree
11836
fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
11837
{
11838
  if (!validate_arg (dst, POINTER_TYPE)
11839
      || !validate_arg (src, POINTER_TYPE)
11840
      || !validate_arg (len, INTEGER_TYPE))
11841
    return NULL_TREE;
11842
  else
11843
    {
11844
      const char *p = c_getstr (src);
11845
 
11846
      /* If the requested length is zero, or the src parameter string
11847
         length is zero, return the dst parameter.  */
11848
      if (integer_zerop (len) || (p && *p == '\0'))
11849
        return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
11850
 
11851
      /* If the requested len is greater than or equal to the string
11852
         length, call strcat.  */
11853
      if (TREE_CODE (len) == INTEGER_CST && p
11854
          && compare_tree_int (len, strlen (p)) >= 0)
11855
        {
11856
          tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
11857
 
11858
          /* If the replacement _DECL isn't initialized, don't do the
11859
             transformation.  */
11860
          if (!fn)
11861
            return NULL_TREE;
11862
 
11863
          return build_call_expr_loc (loc, fn, 2, dst, src);
11864
        }
11865
      return NULL_TREE;
11866
    }
11867
}
11868
 
11869
/* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11870
   to the call.
11871
 
11872
   Return NULL_TREE if no simplification was possible, otherwise return the
11873
   simplified form of the call as a tree.
11874
 
11875
   The simplified form may be a constant or other expression which
11876
   computes the same value, but in a more efficient manner (including
11877
   calls to other builtin functions).
11878
 
11879
   The call may contain arguments which need to be evaluated, but
11880
   which are not useful to determine the result of the call.  In
11881
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11882
   COMPOUND_EXPR will be an argument which must be evaluated.
11883
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11884
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11885
   form of the builtin function call.  */
11886
 
11887
static tree
11888
fold_builtin_strspn (location_t loc, tree s1, tree s2)
11889
{
11890
  if (!validate_arg (s1, POINTER_TYPE)
11891
      || !validate_arg (s2, POINTER_TYPE))
11892
    return NULL_TREE;
11893
  else
11894
    {
11895
      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11896
 
11897
      /* If both arguments are constants, evaluate at compile-time.  */
11898
      if (p1 && p2)
11899
        {
11900
          const size_t r = strspn (p1, p2);
11901
          return size_int (r);
11902
        }
11903
 
11904
      /* If either argument is "", return NULL_TREE.  */
11905
      if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11906
        /* Evaluate and ignore both arguments in case either one has
11907
           side-effects.  */
11908
        return omit_two_operands_loc (loc, size_type_node, size_zero_node,
11909
                                  s1, s2);
11910
      return NULL_TREE;
11911
    }
11912
}
11913
 
11914
/* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11915
   to the call.
11916
 
11917
   Return NULL_TREE if no simplification was possible, otherwise return the
11918
   simplified form of the call as a tree.
11919
 
11920
   The simplified form may be a constant or other expression which
11921
   computes the same value, but in a more efficient manner (including
11922
   calls to other builtin functions).
11923
 
11924
   The call may contain arguments which need to be evaluated, but
11925
   which are not useful to determine the result of the call.  In
11926
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11927
   COMPOUND_EXPR will be an argument which must be evaluated.
11928
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11929
   COMPOUND_EXPR in the chain will contain the tree for the simplified
11930
   form of the builtin function call.  */
11931
 
11932
static tree
11933
fold_builtin_strcspn (location_t loc, tree s1, tree s2)
11934
{
11935
  if (!validate_arg (s1, POINTER_TYPE)
11936
      || !validate_arg (s2, POINTER_TYPE))
11937
    return NULL_TREE;
11938
  else
11939
    {
11940
      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11941
 
11942
      /* If both arguments are constants, evaluate at compile-time.  */
11943
      if (p1 && p2)
11944
        {
11945
          const size_t r = strcspn (p1, p2);
11946
          return size_int (r);
11947
        }
11948
 
11949
      /* If the first argument is "", return NULL_TREE.  */
11950
      if (p1 && *p1 == '\0')
11951
        {
11952
          /* Evaluate and ignore argument s2 in case it has
11953
             side-effects.  */
11954
          return omit_one_operand_loc (loc, size_type_node,
11955
                                   size_zero_node, s2);
11956
        }
11957
 
11958
      /* If the second argument is "", return __builtin_strlen(s1).  */
11959
      if (p2 && *p2 == '\0')
11960
        {
11961
          tree fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11962
 
11963
          /* If the replacement _DECL isn't initialized, don't do the
11964
             transformation.  */
11965
          if (!fn)
11966
            return NULL_TREE;
11967
 
11968
          return build_call_expr_loc (loc, fn, 1, s1);
11969
        }
11970
      return NULL_TREE;
11971
    }
11972
}
11973
 
11974
/* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
11975
   to the call.  IGNORE is true if the value returned
11976
   by the builtin will be ignored.  UNLOCKED is true is true if this
11977
   actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
11978
   the known length of the string.  Return NULL_TREE if no simplification
11979
   was possible.  */
11980
 
11981
tree
11982
fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11983
                    bool ignore, bool unlocked, tree len)
11984
{
11985
  /* If we're using an unlocked function, assume the other unlocked
11986
     functions exist explicitly.  */
11987
  tree const fn_fputc = (unlocked
11988
                         ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
11989
                         : builtin_decl_implicit (BUILT_IN_FPUTC));
11990
  tree const fn_fwrite = (unlocked
11991
                          ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
11992
                          : builtin_decl_implicit (BUILT_IN_FWRITE));
11993
 
11994
  /* If the return value is used, don't do the transformation.  */
11995
  if (!ignore)
11996
    return NULL_TREE;
11997
 
11998
  /* Verify the arguments in the original call.  */
11999
  if (!validate_arg (arg0, POINTER_TYPE)
12000
      || !validate_arg (arg1, POINTER_TYPE))
12001
    return NULL_TREE;
12002
 
12003
  if (! len)
12004
    len = c_strlen (arg0, 0);
12005
 
12006
  /* Get the length of the string passed to fputs.  If the length
12007
     can't be determined, punt.  */
12008
  if (!len
12009
      || TREE_CODE (len) != INTEGER_CST)
12010
    return NULL_TREE;
12011
 
12012
  switch (compare_tree_int (len, 1))
12013
    {
12014
    case -1: /* length is 0, delete the call entirely .  */
12015
      return omit_one_operand_loc (loc, integer_type_node,
12016
                               integer_zero_node, arg1);;
12017
 
12018
    case 0: /* length is 1, call fputc.  */
12019
      {
12020
        const char *p = c_getstr (arg0);
12021
 
12022
        if (p != NULL)
12023
          {
12024
            if (fn_fputc)
12025
              return build_call_expr_loc (loc, fn_fputc, 2,
12026
                                          build_int_cst
12027
                                            (integer_type_node, p[0]), arg1);
12028
            else
12029
              return NULL_TREE;
12030
          }
12031
      }
12032
      /* FALLTHROUGH */
12033
    case 1: /* length is greater than 1, call fwrite.  */
12034
      {
12035
        /* If optimizing for size keep fputs.  */
12036
        if (optimize_function_for_size_p (cfun))
12037
          return NULL_TREE;
12038
        /* New argument list transforming fputs(string, stream) to
12039
           fwrite(string, 1, len, stream).  */
12040
        if (fn_fwrite)
12041
          return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
12042
                                  size_one_node, len, arg1);
12043
        else
12044
          return NULL_TREE;
12045
      }
12046
    default:
12047
      gcc_unreachable ();
12048
    }
12049
  return NULL_TREE;
12050
}
12051
 
12052
/* Fold the next_arg or va_start call EXP. Returns true if there was an error
12053
   produced.  False otherwise.  This is done so that we don't output the error
12054
   or warning twice or three times.  */
12055
 
12056
bool
12057
fold_builtin_next_arg (tree exp, bool va_start_p)
12058
{
12059
  tree fntype = TREE_TYPE (current_function_decl);
12060
  int nargs = call_expr_nargs (exp);
12061
  tree arg;
12062
 
12063
  if (!stdarg_p (fntype))
12064
    {
12065
      error ("%<va_start%> used in function with fixed args");
12066
      return true;
12067
    }
12068
 
12069
  if (va_start_p)
12070
    {
12071
      if (va_start_p && (nargs != 2))
12072
        {
12073
          error ("wrong number of arguments to function %<va_start%>");
12074
          return true;
12075
        }
12076
      arg = CALL_EXPR_ARG (exp, 1);
12077
    }
12078
  /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
12079
     when we checked the arguments and if needed issued a warning.  */
12080
  else
12081
    {
12082
      if (nargs == 0)
12083
        {
12084
          /* Evidently an out of date version of <stdarg.h>; can't validate
12085
             va_start's second argument, but can still work as intended.  */
12086
          warning (0, "%<__builtin_next_arg%> called without an argument");
12087
          return true;
12088
        }
12089
      else if (nargs > 1)
12090
        {
12091
          error ("wrong number of arguments to function %<__builtin_next_arg%>");
12092
          return true;
12093
        }
12094
      arg = CALL_EXPR_ARG (exp, 0);
12095
    }
12096
 
12097
  if (TREE_CODE (arg) == SSA_NAME)
12098
    arg = SSA_NAME_VAR (arg);
12099
 
12100
  /* We destructively modify the call to be __builtin_va_start (ap, 0)
12101
     or __builtin_next_arg (0) the first time we see it, after checking
12102
     the arguments and if needed issuing a warning.  */
12103
  if (!integer_zerop (arg))
12104
    {
12105
      tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
12106
 
12107
      /* Strip off all nops for the sake of the comparison.  This
12108
         is not quite the same as STRIP_NOPS.  It does more.
12109
         We must also strip off INDIRECT_EXPR for C++ reference
12110
         parameters.  */
12111
      while (CONVERT_EXPR_P (arg)
12112
             || TREE_CODE (arg) == INDIRECT_REF)
12113
        arg = TREE_OPERAND (arg, 0);
12114
      if (arg != last_parm)
12115
        {
12116
          /* FIXME: Sometimes with the tree optimizers we can get the
12117
             not the last argument even though the user used the last
12118
             argument.  We just warn and set the arg to be the last
12119
             argument so that we will get wrong-code because of
12120
             it.  */
12121
          warning (0, "second parameter of %<va_start%> not last named argument");
12122
        }
12123
 
12124
      /* Undefined by C99 7.15.1.4p4 (va_start):
12125
         "If the parameter parmN is declared with the register storage
12126
         class, with a function or array type, or with a type that is
12127
         not compatible with the type that results after application of
12128
         the default argument promotions, the behavior is undefined."
12129
      */
12130
      else if (DECL_REGISTER (arg))
12131
        warning (0, "undefined behaviour when second parameter of "
12132
                 "%<va_start%> is declared with %<register%> storage");
12133
 
12134
      /* We want to verify the second parameter just once before the tree
12135
         optimizers are run and then avoid keeping it in the tree,
12136
         as otherwise we could warn even for correct code like:
12137
         void foo (int i, ...)
12138
         { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
12139
      if (va_start_p)
12140
        CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12141
      else
12142
        CALL_EXPR_ARG (exp, 0) = integer_zero_node;
12143
    }
12144
  return false;
12145
}
12146
 
12147
 
12148
/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12149
   ORIG may be null if this is a 2-argument call.  We don't attempt to
12150
   simplify calls with more than 3 arguments.
12151
 
12152
   Return NULL_TREE if no simplification was possible, otherwise return the
12153
   simplified form of the call as a tree.  If IGNORED is true, it means that
12154
   the caller does not use the returned value of the function.  */
12155
 
12156
static tree
12157
fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
12158
                      tree orig, int ignored)
12159
{
12160
  tree call, retval;
12161
  const char *fmt_str = NULL;
12162
 
12163
  /* Verify the required arguments in the original call.  We deal with two
12164
     types of sprintf() calls: 'sprintf (str, fmt)' and
12165
     'sprintf (dest, "%s", orig)'.  */
12166
  if (!validate_arg (dest, POINTER_TYPE)
12167
      || !validate_arg (fmt, POINTER_TYPE))
12168
    return NULL_TREE;
12169
  if (orig && !validate_arg (orig, POINTER_TYPE))
12170
    return NULL_TREE;
12171
 
12172
  /* Check whether the format is a literal string constant.  */
12173
  fmt_str = c_getstr (fmt);
12174
  if (fmt_str == NULL)
12175
    return NULL_TREE;
12176
 
12177
  call = NULL_TREE;
12178
  retval = NULL_TREE;
12179
 
12180
  if (!init_target_chars ())
12181
    return NULL_TREE;
12182
 
12183
  /* If the format doesn't contain % args or %%, use strcpy.  */
12184
  if (strchr (fmt_str, target_percent) == NULL)
12185
    {
12186
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12187
 
12188
      if (!fn)
12189
        return NULL_TREE;
12190
 
12191
      /* Don't optimize sprintf (buf, "abc", ptr++).  */
12192
      if (orig)
12193
        return NULL_TREE;
12194
 
12195
      /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12196
         'format' is known to contain no % formats.  */
12197
      call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12198
      if (!ignored)
12199
        retval = build_int_cst (integer_type_node, strlen (fmt_str));
12200
    }
12201
 
12202
  /* If the format is "%s", use strcpy if the result isn't used.  */
12203
  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12204
    {
12205
      tree fn;
12206
      fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12207
 
12208
      if (!fn)
12209
        return NULL_TREE;
12210
 
12211
      /* Don't crash on sprintf (str1, "%s").  */
12212
      if (!orig)
12213
        return NULL_TREE;
12214
 
12215
      /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
12216
      if (!ignored)
12217
        {
12218
          retval = c_strlen (orig, 1);
12219
          if (!retval || TREE_CODE (retval) != INTEGER_CST)
12220
            return NULL_TREE;
12221
        }
12222
      call = build_call_expr_loc (loc, fn, 2, dest, orig);
12223
    }
12224
 
12225
  if (call && retval)
12226
    {
12227
      retval = fold_convert_loc
12228
        (loc, TREE_TYPE (TREE_TYPE (builtin_decl_implicit (BUILT_IN_SPRINTF))),
12229
         retval);
12230
      return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12231
    }
12232
  else
12233
    return call;
12234
}
12235
 
12236
/* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
12237
   FMT, and ORIG.  ORIG may be null if this is a 3-argument call.  We don't
12238
   attempt to simplify calls with more than 4 arguments.
12239
 
12240
   Return NULL_TREE if no simplification was possible, otherwise return the
12241
   simplified form of the call as a tree.  If IGNORED is true, it means that
12242
   the caller does not use the returned value of the function.  */
12243
 
12244
static tree
12245
fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
12246
                       tree orig, int ignored)
12247
{
12248
  tree call, retval;
12249
  const char *fmt_str = NULL;
12250
  unsigned HOST_WIDE_INT destlen;
12251
 
12252
  /* Verify the required arguments in the original call.  We deal with two
12253
     types of snprintf() calls: 'snprintf (str, cst, fmt)' and
12254
     'snprintf (dest, cst, "%s", orig)'.  */
12255
  if (!validate_arg (dest, POINTER_TYPE)
12256
      || !validate_arg (destsize, INTEGER_TYPE)
12257
      || !validate_arg (fmt, POINTER_TYPE))
12258
    return NULL_TREE;
12259
  if (orig && !validate_arg (orig, POINTER_TYPE))
12260
    return NULL_TREE;
12261
 
12262
  if (!host_integerp (destsize, 1))
12263
    return NULL_TREE;
12264
 
12265
  /* Check whether the format is a literal string constant.  */
12266
  fmt_str = c_getstr (fmt);
12267
  if (fmt_str == NULL)
12268
    return NULL_TREE;
12269
 
12270
  call = NULL_TREE;
12271
  retval = NULL_TREE;
12272
 
12273
  if (!init_target_chars ())
12274
    return NULL_TREE;
12275
 
12276
  destlen = tree_low_cst (destsize, 1);
12277
 
12278
  /* If the format doesn't contain % args or %%, use strcpy.  */
12279
  if (strchr (fmt_str, target_percent) == NULL)
12280
    {
12281
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12282
      size_t len = strlen (fmt_str);
12283
 
12284
      /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
12285
      if (orig)
12286
        return NULL_TREE;
12287
 
12288
      /* We could expand this as
12289
         memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
12290
         or to
12291
         memcpy (str, fmt_with_nul_at_cstm1, cst);
12292
         but in the former case that might increase code size
12293
         and in the latter case grow .rodata section too much.
12294
         So punt for now.  */
12295
      if (len >= destlen)
12296
        return NULL_TREE;
12297
 
12298
      if (!fn)
12299
        return NULL_TREE;
12300
 
12301
      /* Convert snprintf (str, cst, fmt) into strcpy (str, fmt) when
12302
         'format' is known to contain no % formats and
12303
         strlen (fmt) < cst.  */
12304
      call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12305
 
12306
      if (!ignored)
12307
        retval = build_int_cst (integer_type_node, strlen (fmt_str));
12308
    }
12309
 
12310
  /* If the format is "%s", use strcpy if the result isn't used.  */
12311
  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12312
    {
12313
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12314
      unsigned HOST_WIDE_INT origlen;
12315
 
12316
      /* Don't crash on snprintf (str1, cst, "%s").  */
12317
      if (!orig)
12318
        return NULL_TREE;
12319
 
12320
      retval = c_strlen (orig, 1);
12321
      if (!retval || !host_integerp (retval, 1))
12322
        return NULL_TREE;
12323
 
12324
      origlen = tree_low_cst (retval, 1);
12325
      /* We could expand this as
12326
         memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
12327
         or to
12328
         memcpy (str1, str2_with_nul_at_cstm1, cst);
12329
         but in the former case that might increase code size
12330
         and in the latter case grow .rodata section too much.
12331
         So punt for now.  */
12332
      if (origlen >= destlen)
12333
        return NULL_TREE;
12334
 
12335
      /* Convert snprintf (str1, cst, "%s", str2) into
12336
         strcpy (str1, str2) if strlen (str2) < cst.  */
12337
      if (!fn)
12338
        return NULL_TREE;
12339
 
12340
      call = build_call_expr_loc (loc, fn, 2, dest, orig);
12341
 
12342
      if (ignored)
12343
        retval = NULL_TREE;
12344
    }
12345
 
12346
  if (call && retval)
12347
    {
12348
      tree fn = builtin_decl_explicit (BUILT_IN_SNPRINTF);
12349
      retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
12350
      return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12351
    }
12352
  else
12353
    return call;
12354
}
12355
 
12356
/* Expand a call EXP to __builtin_object_size.  */
12357
 
12358
rtx
12359
expand_builtin_object_size (tree exp)
12360
{
12361
  tree ost;
12362
  int object_size_type;
12363
  tree fndecl = get_callee_fndecl (exp);
12364
 
12365
  if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
12366
    {
12367
      error ("%Kfirst argument of %D must be a pointer, second integer constant",
12368
             exp, fndecl);
12369
      expand_builtin_trap ();
12370
      return const0_rtx;
12371
    }
12372
 
12373
  ost = CALL_EXPR_ARG (exp, 1);
12374
  STRIP_NOPS (ost);
12375
 
12376
  if (TREE_CODE (ost) != INTEGER_CST
12377
      || tree_int_cst_sgn (ost) < 0
12378
      || compare_tree_int (ost, 3) > 0)
12379
    {
12380
      error ("%Klast argument of %D is not integer constant between 0 and 3",
12381
             exp, fndecl);
12382
      expand_builtin_trap ();
12383
      return const0_rtx;
12384
    }
12385
 
12386
  object_size_type = tree_low_cst (ost, 0);
12387
 
12388
  return object_size_type < 2 ? constm1_rtx : const0_rtx;
12389
}
12390
 
12391
/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12392
   FCODE is the BUILT_IN_* to use.
12393
   Return NULL_RTX if we failed; the caller should emit a normal call,
12394
   otherwise try to get the result in TARGET, if convenient (and in
12395
   mode MODE if that's convenient).  */
12396
 
12397
static rtx
12398
expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12399
                           enum built_in_function fcode)
12400
{
12401
  tree dest, src, len, size;
12402
 
12403
  if (!validate_arglist (exp,
12404
                         POINTER_TYPE,
12405
                         fcode == BUILT_IN_MEMSET_CHK
12406
                         ? INTEGER_TYPE : POINTER_TYPE,
12407
                         INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
12408
    return NULL_RTX;
12409
 
12410
  dest = CALL_EXPR_ARG (exp, 0);
12411
  src = CALL_EXPR_ARG (exp, 1);
12412
  len = CALL_EXPR_ARG (exp, 2);
12413
  size = CALL_EXPR_ARG (exp, 3);
12414
 
12415
  if (! host_integerp (size, 1))
12416
    return NULL_RTX;
12417
 
12418
  if (host_integerp (len, 1) || integer_all_onesp (size))
12419
    {
12420
      tree fn;
12421
 
12422
      if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12423
        {
12424
          warning_at (tree_nonartificial_location (exp),
12425
                      0, "%Kcall to %D will always overflow destination buffer",
12426
                      exp, get_callee_fndecl (exp));
12427
          return NULL_RTX;
12428
        }
12429
 
12430
      fn = NULL_TREE;
12431
      /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12432
         mem{cpy,pcpy,move,set} is available.  */
12433
      switch (fcode)
12434
        {
12435
        case BUILT_IN_MEMCPY_CHK:
12436
          fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12437
          break;
12438
        case BUILT_IN_MEMPCPY_CHK:
12439
          fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12440
          break;
12441
        case BUILT_IN_MEMMOVE_CHK:
12442
          fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12443
          break;
12444
        case BUILT_IN_MEMSET_CHK:
12445
          fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12446
          break;
12447
        default:
12448
          break;
12449
        }
12450
 
12451
      if (! fn)
12452
        return NULL_RTX;
12453
 
12454
      fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len);
12455
      gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12456
      CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12457
      return expand_expr (fn, target, mode, EXPAND_NORMAL);
12458
    }
12459
  else if (fcode == BUILT_IN_MEMSET_CHK)
12460
    return NULL_RTX;
12461
  else
12462
    {
12463
      unsigned int dest_align = get_pointer_alignment (dest);
12464
 
12465
      /* If DEST is not a pointer type, call the normal function.  */
12466
      if (dest_align == 0)
12467
        return NULL_RTX;
12468
 
12469
      /* If SRC and DEST are the same (and not volatile), do nothing.  */
12470
      if (operand_equal_p (src, dest, 0))
12471
        {
12472
          tree expr;
12473
 
12474
          if (fcode != BUILT_IN_MEMPCPY_CHK)
12475
            {
12476
              /* Evaluate and ignore LEN in case it has side-effects.  */
12477
              expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12478
              return expand_expr (dest, target, mode, EXPAND_NORMAL);
12479
            }
12480
 
12481
          expr = fold_build_pointer_plus (dest, len);
12482
          return expand_expr (expr, target, mode, EXPAND_NORMAL);
12483
        }
12484
 
12485
      /* __memmove_chk special case.  */
12486
      if (fcode == BUILT_IN_MEMMOVE_CHK)
12487
        {
12488
          unsigned int src_align = get_pointer_alignment (src);
12489
 
12490
          if (src_align == 0)
12491
            return NULL_RTX;
12492
 
12493
          /* If src is categorized for a readonly section we can use
12494
             normal __memcpy_chk.  */
12495
          if (readonly_data_expr (src))
12496
            {
12497
              tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12498
              if (!fn)
12499
                return NULL_RTX;
12500
              fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4,
12501
                                          dest, src, len, size);
12502
              gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12503
              CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12504
              return expand_expr (fn, target, mode, EXPAND_NORMAL);
12505
            }
12506
        }
12507
      return NULL_RTX;
12508
    }
12509
}
12510
 
12511
/* Emit warning if a buffer overflow is detected at compile time.  */
12512
 
12513
static void
12514
maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12515
{
12516
  int is_strlen = 0;
12517
  tree len, size;
12518
  location_t loc = tree_nonartificial_location (exp);
12519
 
12520
  switch (fcode)
12521
    {
12522
    case BUILT_IN_STRCPY_CHK:
12523
    case BUILT_IN_STPCPY_CHK:
12524
    /* For __strcat_chk the warning will be emitted only if overflowing
12525
       by at least strlen (dest) + 1 bytes.  */
12526
    case BUILT_IN_STRCAT_CHK:
12527
      len = CALL_EXPR_ARG (exp, 1);
12528
      size = CALL_EXPR_ARG (exp, 2);
12529
      is_strlen = 1;
12530
      break;
12531
    case BUILT_IN_STRNCAT_CHK:
12532
    case BUILT_IN_STRNCPY_CHK:
12533
    case BUILT_IN_STPNCPY_CHK:
12534
      len = CALL_EXPR_ARG (exp, 2);
12535
      size = CALL_EXPR_ARG (exp, 3);
12536
      break;
12537
    case BUILT_IN_SNPRINTF_CHK:
12538
    case BUILT_IN_VSNPRINTF_CHK:
12539
      len = CALL_EXPR_ARG (exp, 1);
12540
      size = CALL_EXPR_ARG (exp, 3);
12541
      break;
12542
    default:
12543
      gcc_unreachable ();
12544
    }
12545
 
12546
  if (!len || !size)
12547
    return;
12548
 
12549
  if (! host_integerp (size, 1) || integer_all_onesp (size))
12550
    return;
12551
 
12552
  if (is_strlen)
12553
    {
12554
      len = c_strlen (len, 1);
12555
      if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12556
        return;
12557
    }
12558
  else if (fcode == BUILT_IN_STRNCAT_CHK)
12559
    {
12560
      tree src = CALL_EXPR_ARG (exp, 1);
12561
      if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12562
        return;
12563
      src = c_strlen (src, 1);
12564
      if (! src || ! host_integerp (src, 1))
12565
        {
12566
          warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12567
                      exp, get_callee_fndecl (exp));
12568
          return;
12569
        }
12570
      else if (tree_int_cst_lt (src, size))
12571
        return;
12572
    }
12573
  else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12574
    return;
12575
 
12576
  warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12577
              exp, get_callee_fndecl (exp));
12578
}
12579
 
12580
/* Emit warning if a buffer overflow is detected at compile time
12581
   in __sprintf_chk/__vsprintf_chk calls.  */
12582
 
12583
static void
12584
maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12585
{
12586
  tree size, len, fmt;
12587
  const char *fmt_str;
12588
  int nargs = call_expr_nargs (exp);
12589
 
12590
  /* Verify the required arguments in the original call.  */
12591
 
12592
  if (nargs < 4)
12593
    return;
12594
  size = CALL_EXPR_ARG (exp, 2);
12595
  fmt = CALL_EXPR_ARG (exp, 3);
12596
 
12597
  if (! host_integerp (size, 1) || integer_all_onesp (size))
12598
    return;
12599
 
12600
  /* Check whether the format is a literal string constant.  */
12601
  fmt_str = c_getstr (fmt);
12602
  if (fmt_str == NULL)
12603
    return;
12604
 
12605
  if (!init_target_chars ())
12606
    return;
12607
 
12608
  /* If the format doesn't contain % args or %%, we know its size.  */
12609
  if (strchr (fmt_str, target_percent) == 0)
12610
    len = build_int_cstu (size_type_node, strlen (fmt_str));
12611
  /* If the format is "%s" and first ... argument is a string literal,
12612
     we know it too.  */
12613
  else if (fcode == BUILT_IN_SPRINTF_CHK
12614
           && strcmp (fmt_str, target_percent_s) == 0)
12615
    {
12616
      tree arg;
12617
 
12618
      if (nargs < 5)
12619
        return;
12620
      arg = CALL_EXPR_ARG (exp, 4);
12621
      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12622
        return;
12623
 
12624
      len = c_strlen (arg, 1);
12625
      if (!len || ! host_integerp (len, 1))
12626
        return;
12627
    }
12628
  else
12629
    return;
12630
 
12631
  if (! tree_int_cst_lt (len, size))
12632
    warning_at (tree_nonartificial_location (exp),
12633
                0, "%Kcall to %D will always overflow destination buffer",
12634
                exp, get_callee_fndecl (exp));
12635
}
12636
 
12637
/* Emit warning if a free is called with address of a variable.  */
12638
 
12639
static void
12640
maybe_emit_free_warning (tree exp)
12641
{
12642
  tree arg = CALL_EXPR_ARG (exp, 0);
12643
 
12644
  STRIP_NOPS (arg);
12645
  if (TREE_CODE (arg) != ADDR_EXPR)
12646
    return;
12647
 
12648
  arg = get_base_address (TREE_OPERAND (arg, 0));
12649
  if (arg == NULL || INDIRECT_REF_P (arg) || TREE_CODE (arg) == MEM_REF)
12650
    return;
12651
 
12652
  if (SSA_VAR_P (arg))
12653
    warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12654
                "%Kattempt to free a non-heap object %qD", exp, arg);
12655
  else
12656
    warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12657
                "%Kattempt to free a non-heap object", exp);
12658
}
12659
 
12660
/* Fold a call to __builtin_object_size with arguments PTR and OST,
12661
   if possible.  */
12662
 
12663
tree
12664
fold_builtin_object_size (tree ptr, tree ost)
12665
{
12666
  unsigned HOST_WIDE_INT bytes;
12667
  int object_size_type;
12668
 
12669
  if (!validate_arg (ptr, POINTER_TYPE)
12670
      || !validate_arg (ost, INTEGER_TYPE))
12671
    return NULL_TREE;
12672
 
12673
  STRIP_NOPS (ost);
12674
 
12675
  if (TREE_CODE (ost) != INTEGER_CST
12676
      || tree_int_cst_sgn (ost) < 0
12677
      || compare_tree_int (ost, 3) > 0)
12678
    return NULL_TREE;
12679
 
12680
  object_size_type = tree_low_cst (ost, 0);
12681
 
12682
  /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12683
     if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12684
     and (size_t) 0 for types 2 and 3.  */
12685
  if (TREE_SIDE_EFFECTS (ptr))
12686
    return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12687
 
12688
  if (TREE_CODE (ptr) == ADDR_EXPR)
12689
    {
12690
      bytes = compute_builtin_object_size (ptr, object_size_type);
12691
      if (double_int_fits_to_tree_p (size_type_node,
12692
                                     uhwi_to_double_int (bytes)))
12693
        return build_int_cstu (size_type_node, bytes);
12694
    }
12695
  else if (TREE_CODE (ptr) == SSA_NAME)
12696
    {
12697
      /* If object size is not known yet, delay folding until
12698
       later.  Maybe subsequent passes will help determining
12699
       it.  */
12700
      bytes = compute_builtin_object_size (ptr, object_size_type);
12701
      if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
12702
          && double_int_fits_to_tree_p (size_type_node,
12703
                                        uhwi_to_double_int (bytes)))
12704
        return build_int_cstu (size_type_node, bytes);
12705
    }
12706
 
12707
  return NULL_TREE;
12708
}
12709
 
12710
/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12711
   DEST, SRC, LEN, and SIZE are the arguments to the call.
12712
   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
12713
   code of the builtin.  If MAXLEN is not NULL, it is maximum length
12714
   passed as third argument.  */
12715
 
12716
tree
12717
fold_builtin_memory_chk (location_t loc, tree fndecl,
12718
                         tree dest, tree src, tree len, tree size,
12719
                         tree maxlen, bool ignore,
12720
                         enum built_in_function fcode)
12721
{
12722
  tree fn;
12723
 
12724
  if (!validate_arg (dest, POINTER_TYPE)
12725
      || !validate_arg (src,
12726
                        (fcode == BUILT_IN_MEMSET_CHK
12727
                         ? INTEGER_TYPE : POINTER_TYPE))
12728
      || !validate_arg (len, INTEGER_TYPE)
12729
      || !validate_arg (size, INTEGER_TYPE))
12730
    return NULL_TREE;
12731
 
12732
  /* If SRC and DEST are the same (and not volatile), return DEST
12733
     (resp. DEST+LEN for __mempcpy_chk).  */
12734
  if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12735
    {
12736
      if (fcode != BUILT_IN_MEMPCPY_CHK)
12737
        return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12738
                                 dest, len);
12739
      else
12740
        {
12741
          tree temp = fold_build_pointer_plus_loc (loc, dest, len);
12742
          return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
12743
        }
12744
    }
12745
 
12746
  if (! host_integerp (size, 1))
12747
    return NULL_TREE;
12748
 
12749
  if (! integer_all_onesp (size))
12750
    {
12751
      if (! host_integerp (len, 1))
12752
        {
12753
          /* If LEN is not constant, try MAXLEN too.
12754
             For MAXLEN only allow optimizing into non-_ocs function
12755
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12756
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12757
            {
12758
              if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12759
                {
12760
                  /* (void) __mempcpy_chk () can be optimized into
12761
                     (void) __memcpy_chk ().  */
12762
                  fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12763
                  if (!fn)
12764
                    return NULL_TREE;
12765
 
12766
                  return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12767
                }
12768
              return NULL_TREE;
12769
            }
12770
        }
12771
      else
12772
        maxlen = len;
12773
 
12774
      if (tree_int_cst_lt (size, maxlen))
12775
        return NULL_TREE;
12776
    }
12777
 
12778
  fn = NULL_TREE;
12779
  /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12780
     mem{cpy,pcpy,move,set} is available.  */
12781
  switch (fcode)
12782
    {
12783
    case BUILT_IN_MEMCPY_CHK:
12784
      fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12785
      break;
12786
    case BUILT_IN_MEMPCPY_CHK:
12787
      fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12788
      break;
12789
    case BUILT_IN_MEMMOVE_CHK:
12790
      fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12791
      break;
12792
    case BUILT_IN_MEMSET_CHK:
12793
      fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12794
      break;
12795
    default:
12796
      break;
12797
    }
12798
 
12799
  if (!fn)
12800
    return NULL_TREE;
12801
 
12802
  return build_call_expr_loc (loc, fn, 3, dest, src, len);
12803
}
12804
 
12805
/* Fold a call to the __st[rp]cpy_chk builtin.
12806
   DEST, SRC, and SIZE are the arguments to the call.
12807
   IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12808
   code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12809
   strings passed as second argument.  */
12810
 
12811
tree
12812
fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12813
                         tree src, tree size,
12814
                         tree maxlen, bool ignore,
12815
                         enum built_in_function fcode)
12816
{
12817
  tree len, fn;
12818
 
12819
  if (!validate_arg (dest, POINTER_TYPE)
12820
      || !validate_arg (src, POINTER_TYPE)
12821
      || !validate_arg (size, INTEGER_TYPE))
12822
    return NULL_TREE;
12823
 
12824
  /* If SRC and DEST are the same (and not volatile), return DEST.  */
12825
  if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12826
    return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
12827
 
12828
  if (! host_integerp (size, 1))
12829
    return NULL_TREE;
12830
 
12831
  if (! integer_all_onesp (size))
12832
    {
12833
      len = c_strlen (src, 1);
12834
      if (! len || ! host_integerp (len, 1))
12835
        {
12836
          /* If LEN is not constant, try MAXLEN too.
12837
             For MAXLEN only allow optimizing into non-_ocs function
12838
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12839
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12840
            {
12841
              if (fcode == BUILT_IN_STPCPY_CHK)
12842
                {
12843
                  if (! ignore)
12844
                    return NULL_TREE;
12845
 
12846
                  /* If return value of __stpcpy_chk is ignored,
12847
                     optimize into __strcpy_chk.  */
12848
                  fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
12849
                  if (!fn)
12850
                    return NULL_TREE;
12851
 
12852
                  return build_call_expr_loc (loc, fn, 3, dest, src, size);
12853
                }
12854
 
12855
              if (! len || TREE_SIDE_EFFECTS (len))
12856
                return NULL_TREE;
12857
 
12858
              /* If c_strlen returned something, but not a constant,
12859
                 transform __strcpy_chk into __memcpy_chk.  */
12860
              fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12861
              if (!fn)
12862
                return NULL_TREE;
12863
 
12864
              len = fold_convert_loc (loc, size_type_node, len);
12865
              len = size_binop_loc (loc, PLUS_EXPR, len,
12866
                                    build_int_cst (size_type_node, 1));
12867
              return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12868
                                       build_call_expr_loc (loc, fn, 4,
12869
                                                        dest, src, len, size));
12870
            }
12871
        }
12872
      else
12873
        maxlen = len;
12874
 
12875
      if (! tree_int_cst_lt (maxlen, size))
12876
        return NULL_TREE;
12877
    }
12878
 
12879
  /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12880
  fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
12881
                              ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
12882
  if (!fn)
12883
    return NULL_TREE;
12884
 
12885
  return build_call_expr_loc (loc, fn, 2, dest, src);
12886
}
12887
 
12888
/* Fold a call to the __st{r,p}ncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12889
   are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12890
   length passed as third argument. IGNORE is true if return value can be
12891
   ignored. FCODE is the BUILT_IN_* code of the builtin. */
12892
 
12893
tree
12894
fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src,
12895
                          tree len, tree size, tree maxlen, bool ignore,
12896
                          enum built_in_function fcode)
12897
{
12898
  tree fn;
12899
 
12900
  if (!validate_arg (dest, POINTER_TYPE)
12901
      || !validate_arg (src, POINTER_TYPE)
12902
      || !validate_arg (len, INTEGER_TYPE)
12903
      || !validate_arg (size, INTEGER_TYPE))
12904
    return NULL_TREE;
12905
 
12906
  if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
12907
    {
12908
       /* If return value of __stpncpy_chk is ignored,
12909
          optimize into __strncpy_chk.  */
12910
       fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
12911
       if (fn)
12912
         return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12913
    }
12914
 
12915
  if (! host_integerp (size, 1))
12916
    return NULL_TREE;
12917
 
12918
  if (! integer_all_onesp (size))
12919
    {
12920
      if (! host_integerp (len, 1))
12921
        {
12922
          /* If LEN is not constant, try MAXLEN too.
12923
             For MAXLEN only allow optimizing into non-_ocs function
12924
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12925
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12926
            return NULL_TREE;
12927
        }
12928
      else
12929
        maxlen = len;
12930
 
12931
      if (tree_int_cst_lt (size, maxlen))
12932
        return NULL_TREE;
12933
    }
12934
 
12935
  /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available.  */
12936
  fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
12937
                              ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
12938
  if (!fn)
12939
    return NULL_TREE;
12940
 
12941
  return build_call_expr_loc (loc, fn, 3, dest, src, len);
12942
}
12943
 
12944
/* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
12945
   are the arguments to the call.  */
12946
 
12947
static tree
12948
fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12949
                         tree src, tree size)
12950
{
12951
  tree fn;
12952
  const char *p;
12953
 
12954
  if (!validate_arg (dest, POINTER_TYPE)
12955
      || !validate_arg (src, POINTER_TYPE)
12956
      || !validate_arg (size, INTEGER_TYPE))
12957
    return NULL_TREE;
12958
 
12959
  p = c_getstr (src);
12960
  /* If the SRC parameter is "", return DEST.  */
12961
  if (p && *p == '\0')
12962
    return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12963
 
12964
  if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12965
    return NULL_TREE;
12966
 
12967
  /* If __builtin_strcat_chk is used, assume strcat is available.  */
12968
  fn = builtin_decl_explicit (BUILT_IN_STRCAT);
12969
  if (!fn)
12970
    return NULL_TREE;
12971
 
12972
  return build_call_expr_loc (loc, fn, 2, dest, src);
12973
}
12974
 
12975
/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12976
   LEN, and SIZE.  */
12977
 
12978
static tree
12979
fold_builtin_strncat_chk (location_t loc, tree fndecl,
12980
                          tree dest, tree src, tree len, tree size)
12981
{
12982
  tree fn;
12983
  const char *p;
12984
 
12985
  if (!validate_arg (dest, POINTER_TYPE)
12986
      || !validate_arg (src, POINTER_TYPE)
12987
      || !validate_arg (size, INTEGER_TYPE)
12988
      || !validate_arg (size, INTEGER_TYPE))
12989
    return NULL_TREE;
12990
 
12991
  p = c_getstr (src);
12992
  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
12993
  if (p && *p == '\0')
12994
    return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12995
  else if (integer_zerop (len))
12996
    return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12997
 
12998
  if (! host_integerp (size, 1))
12999
    return NULL_TREE;
13000
 
13001
  if (! integer_all_onesp (size))
13002
    {
13003
      tree src_len = c_strlen (src, 1);
13004
      if (src_len
13005
          && host_integerp (src_len, 1)
13006
          && host_integerp (len, 1)
13007
          && ! tree_int_cst_lt (len, src_len))
13008
        {
13009
          /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
13010
          fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
13011
          if (!fn)
13012
            return NULL_TREE;
13013
 
13014
          return build_call_expr_loc (loc, fn, 3, dest, src, size);
13015
        }
13016
      return NULL_TREE;
13017
    }
13018
 
13019
  /* If __builtin_strncat_chk is used, assume strncat is available.  */
13020
  fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
13021
  if (!fn)
13022
    return NULL_TREE;
13023
 
13024
  return build_call_expr_loc (loc, fn, 3, dest, src, len);
13025
}
13026
 
13027
/* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
13028
   Return NULL_TREE if a normal call should be emitted rather than
13029
   expanding the function inline.  FCODE is either BUILT_IN_SPRINTF_CHK
13030
   or BUILT_IN_VSPRINTF_CHK.  */
13031
 
13032
static tree
13033
fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
13034
                            enum built_in_function fcode)
13035
{
13036
  tree dest, size, len, fn, fmt, flag;
13037
  const char *fmt_str;
13038
 
13039
  /* Verify the required arguments in the original call.  */
13040
  if (nargs < 4)
13041
    return NULL_TREE;
13042
  dest = args[0];
13043
  if (!validate_arg (dest, POINTER_TYPE))
13044
    return NULL_TREE;
13045
  flag = args[1];
13046
  if (!validate_arg (flag, INTEGER_TYPE))
13047
    return NULL_TREE;
13048
  size = args[2];
13049
  if (!validate_arg (size, INTEGER_TYPE))
13050
    return NULL_TREE;
13051
  fmt = args[3];
13052
  if (!validate_arg (fmt, POINTER_TYPE))
13053
    return NULL_TREE;
13054
 
13055
  if (! host_integerp (size, 1))
13056
    return NULL_TREE;
13057
 
13058
  len = NULL_TREE;
13059
 
13060
  if (!init_target_chars ())
13061
    return NULL_TREE;
13062
 
13063
  /* Check whether the format is a literal string constant.  */
13064
  fmt_str = c_getstr (fmt);
13065
  if (fmt_str != NULL)
13066
    {
13067
      /* If the format doesn't contain % args or %%, we know the size.  */
13068
      if (strchr (fmt_str, target_percent) == 0)
13069
        {
13070
          if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13071
            len = build_int_cstu (size_type_node, strlen (fmt_str));
13072
        }
13073
      /* If the format is "%s" and first ... argument is a string literal,
13074
         we know the size too.  */
13075
      else if (fcode == BUILT_IN_SPRINTF_CHK
13076
               && strcmp (fmt_str, target_percent_s) == 0)
13077
        {
13078
          tree arg;
13079
 
13080
          if (nargs == 5)
13081
            {
13082
              arg = args[4];
13083
              if (validate_arg (arg, POINTER_TYPE))
13084
                {
13085
                  len = c_strlen (arg, 1);
13086
                  if (! len || ! host_integerp (len, 1))
13087
                    len = NULL_TREE;
13088
                }
13089
            }
13090
        }
13091
    }
13092
 
13093
  if (! integer_all_onesp (size))
13094
    {
13095
      if (! len || ! tree_int_cst_lt (len, size))
13096
        return NULL_TREE;
13097
    }
13098
 
13099
  /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13100
     or if format doesn't contain % chars or is "%s".  */
13101
  if (! integer_zerop (flag))
13102
    {
13103
      if (fmt_str == NULL)
13104
        return NULL_TREE;
13105
      if (strchr (fmt_str, target_percent) != NULL
13106
          && strcmp (fmt_str, target_percent_s))
13107
        return NULL_TREE;
13108
    }
13109
 
13110
  /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
13111
  fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
13112
                              ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
13113
  if (!fn)
13114
    return NULL_TREE;
13115
 
13116
  return rewrite_call_expr_array (loc, nargs, args, 4, fn, 2, dest, fmt);
13117
}
13118
 
13119
/* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
13120
   a normal call should be emitted rather than expanding the function
13121
   inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
13122
 
13123
static tree
13124
fold_builtin_sprintf_chk (location_t loc, tree exp,
13125
                          enum built_in_function fcode)
13126
{
13127
  return fold_builtin_sprintf_chk_1 (loc, call_expr_nargs (exp),
13128
                                     CALL_EXPR_ARGP (exp), fcode);
13129
}
13130
 
13131
/* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
13132
   NULL_TREE if a normal call should be emitted rather than expanding
13133
   the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13134
   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13135
   passed as second argument.  */
13136
 
13137
static tree
13138
fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
13139
                             tree maxlen, enum built_in_function fcode)
13140
{
13141
  tree dest, size, len, fn, fmt, flag;
13142
  const char *fmt_str;
13143
 
13144
  /* Verify the required arguments in the original call.  */
13145
  if (nargs < 5)
13146
    return NULL_TREE;
13147
  dest = args[0];
13148
  if (!validate_arg (dest, POINTER_TYPE))
13149
    return NULL_TREE;
13150
  len = args[1];
13151
  if (!validate_arg (len, INTEGER_TYPE))
13152
    return NULL_TREE;
13153
  flag = args[2];
13154
  if (!validate_arg (flag, INTEGER_TYPE))
13155
    return NULL_TREE;
13156
  size = args[3];
13157
  if (!validate_arg (size, INTEGER_TYPE))
13158
    return NULL_TREE;
13159
  fmt = args[4];
13160
  if (!validate_arg (fmt, POINTER_TYPE))
13161
    return NULL_TREE;
13162
 
13163
  if (! host_integerp (size, 1))
13164
    return NULL_TREE;
13165
 
13166
  if (! integer_all_onesp (size))
13167
    {
13168
      if (! host_integerp (len, 1))
13169
        {
13170
          /* If LEN is not constant, try MAXLEN too.
13171
             For MAXLEN only allow optimizing into non-_ocs function
13172
             if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13173
          if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13174
            return NULL_TREE;
13175
        }
13176
      else
13177
        maxlen = len;
13178
 
13179
      if (tree_int_cst_lt (size, maxlen))
13180
        return NULL_TREE;
13181
    }
13182
 
13183
  if (!init_target_chars ())
13184
    return NULL_TREE;
13185
 
13186
  /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13187
     or if format doesn't contain % chars or is "%s".  */
13188
  if (! integer_zerop (flag))
13189
    {
13190
      fmt_str = c_getstr (fmt);
13191
      if (fmt_str == NULL)
13192
        return NULL_TREE;
13193
      if (strchr (fmt_str, target_percent) != NULL
13194
          && strcmp (fmt_str, target_percent_s))
13195
        return NULL_TREE;
13196
    }
13197
 
13198
  /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13199
     available.  */
13200
  fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
13201
                              ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
13202
  if (!fn)
13203
    return NULL_TREE;
13204
 
13205
  return rewrite_call_expr_array (loc, nargs, args, 5, fn, 3, dest, len, fmt);
13206
}
13207
 
13208
/* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
13209
   a normal call should be emitted rather than expanding the function
13210
   inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13211
   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13212
   passed as second argument.  */
13213
 
13214
tree
13215
fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
13216
                           enum built_in_function fcode)
13217
{
13218
  return fold_builtin_snprintf_chk_1 (loc, call_expr_nargs (exp),
13219
                                      CALL_EXPR_ARGP (exp), maxlen, fcode);
13220
}
13221
 
13222
/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
13223
   FMT and ARG are the arguments to the call; we don't fold cases with
13224
   more than 2 arguments, and ARG may be null if this is a 1-argument case.
13225
 
13226
   Return NULL_TREE if no simplification was possible, otherwise return the
13227
   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13228
   code of the function to be simplified.  */
13229
 
13230
static tree
13231
fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
13232
                     tree arg, bool ignore,
13233
                     enum built_in_function fcode)
13234
{
13235
  tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
13236
  const char *fmt_str = NULL;
13237
 
13238
  /* If the return value is used, don't do the transformation.  */
13239
  if (! ignore)
13240
    return NULL_TREE;
13241
 
13242
  /* Verify the required arguments in the original call.  */
13243
  if (!validate_arg (fmt, POINTER_TYPE))
13244
    return NULL_TREE;
13245
 
13246
  /* Check whether the format is a literal string constant.  */
13247
  fmt_str = c_getstr (fmt);
13248
  if (fmt_str == NULL)
13249
    return NULL_TREE;
13250
 
13251
  if (fcode == BUILT_IN_PRINTF_UNLOCKED)
13252
    {
13253
      /* If we're using an unlocked function, assume the other
13254
         unlocked functions exist explicitly.  */
13255
      fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
13256
      fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
13257
    }
13258
  else
13259
    {
13260
      fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
13261
      fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
13262
    }
13263
 
13264
  if (!init_target_chars ())
13265
    return NULL_TREE;
13266
 
13267
  if (strcmp (fmt_str, target_percent_s) == 0
13268
      || strchr (fmt_str, target_percent) == NULL)
13269
    {
13270
      const char *str;
13271
 
13272
      if (strcmp (fmt_str, target_percent_s) == 0)
13273
        {
13274
          if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13275
            return NULL_TREE;
13276
 
13277
          if (!arg || !validate_arg (arg, POINTER_TYPE))
13278
            return NULL_TREE;
13279
 
13280
          str = c_getstr (arg);
13281
          if (str == NULL)
13282
            return NULL_TREE;
13283
        }
13284
      else
13285
        {
13286
          /* The format specifier doesn't contain any '%' characters.  */
13287
          if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
13288
              && arg)
13289
            return NULL_TREE;
13290
          str = fmt_str;
13291
        }
13292
 
13293
      /* If the string was "", printf does nothing.  */
13294
      if (str[0] == '\0')
13295
        return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13296
 
13297
      /* If the string has length of 1, call putchar.  */
13298
      if (str[1] == '\0')
13299
        {
13300
          /* Given printf("c"), (where c is any one character,)
13301
             convert "c"[0] to an int and pass that to the replacement
13302
             function.  */
13303
          newarg = build_int_cst (integer_type_node, str[0]);
13304
          if (fn_putchar)
13305
            call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
13306
        }
13307
      else
13308
        {
13309
          /* If the string was "string\n", call puts("string").  */
13310
          size_t len = strlen (str);
13311
          if ((unsigned char)str[len - 1] == target_newline
13312
              && (size_t) (int) len == len
13313
              && (int) len > 0)
13314
            {
13315
              char *newstr;
13316
              tree offset_node, string_cst;
13317
 
13318
              /* Create a NUL-terminated string that's one char shorter
13319
                 than the original, stripping off the trailing '\n'.  */
13320
              newarg = build_string_literal (len, str);
13321
              string_cst = string_constant (newarg, &offset_node);
13322
              gcc_checking_assert (string_cst
13323
                                   && (TREE_STRING_LENGTH (string_cst)
13324
                                       == (int) len)
13325
                                   && integer_zerop (offset_node)
13326
                                   && (unsigned char)
13327
                                      TREE_STRING_POINTER (string_cst)[len - 1]
13328
                                      == target_newline);
13329
              /* build_string_literal creates a new STRING_CST,
13330
                 modify it in place to avoid double copying.  */
13331
              newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst));
13332
              newstr[len - 1] = '\0';
13333
              if (fn_puts)
13334
                call = build_call_expr_loc (loc, fn_puts, 1, newarg);
13335
            }
13336
          else
13337
            /* We'd like to arrange to call fputs(string,stdout) here,
13338
               but we need stdout and don't have a way to get it yet.  */
13339
            return NULL_TREE;
13340
        }
13341
    }
13342
 
13343
  /* The other optimizations can be done only on the non-va_list variants.  */
13344
  else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13345
    return NULL_TREE;
13346
 
13347
  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
13348
  else if (strcmp (fmt_str, target_percent_s_newline) == 0)
13349
    {
13350
      if (!arg || !validate_arg (arg, POINTER_TYPE))
13351
        return NULL_TREE;
13352
      if (fn_puts)
13353
        call = build_call_expr_loc (loc, fn_puts, 1, arg);
13354
    }
13355
 
13356
  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
13357
  else if (strcmp (fmt_str, target_percent_c) == 0)
13358
    {
13359
      if (!arg || !validate_arg (arg, INTEGER_TYPE))
13360
        return NULL_TREE;
13361
      if (fn_putchar)
13362
        call = build_call_expr_loc (loc, fn_putchar, 1, arg);
13363
    }
13364
 
13365
  if (!call)
13366
    return NULL_TREE;
13367
 
13368
  return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13369
}
13370
 
13371
/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
13372
   FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
13373
   more than 3 arguments, and ARG may be null in the 2-argument case.
13374
 
13375
   Return NULL_TREE if no simplification was possible, otherwise return the
13376
   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13377
   code of the function to be simplified.  */
13378
 
13379
static tree
13380
fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
13381
                      tree fmt, tree arg, bool ignore,
13382
                      enum built_in_function fcode)
13383
{
13384
  tree fn_fputc, fn_fputs, call = NULL_TREE;
13385
  const char *fmt_str = NULL;
13386
 
13387
  /* If the return value is used, don't do the transformation.  */
13388
  if (! ignore)
13389
    return NULL_TREE;
13390
 
13391
  /* Verify the required arguments in the original call.  */
13392
  if (!validate_arg (fp, POINTER_TYPE))
13393
    return NULL_TREE;
13394
  if (!validate_arg (fmt, POINTER_TYPE))
13395
    return NULL_TREE;
13396
 
13397
  /* Check whether the format is a literal string constant.  */
13398
  fmt_str = c_getstr (fmt);
13399
  if (fmt_str == NULL)
13400
    return NULL_TREE;
13401
 
13402
  if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13403
    {
13404
      /* If we're using an unlocked function, assume the other
13405
         unlocked functions exist explicitly.  */
13406
      fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
13407
      fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
13408
    }
13409
  else
13410
    {
13411
      fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
13412
      fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
13413
    }
13414
 
13415
  if (!init_target_chars ())
13416
    return NULL_TREE;
13417
 
13418
  /* If the format doesn't contain % args or %%, use strcpy.  */
13419
  if (strchr (fmt_str, target_percent) == NULL)
13420
    {
13421
      if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
13422
          && arg)
13423
        return NULL_TREE;
13424
 
13425
      /* If the format specifier was "", fprintf does nothing.  */
13426
      if (fmt_str[0] == '\0')
13427
        {
13428
          /* If FP has side-effects, just wait until gimplification is
13429
             done.  */
13430
          if (TREE_SIDE_EFFECTS (fp))
13431
            return NULL_TREE;
13432
 
13433
          return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13434
        }
13435
 
13436
      /* When "string" doesn't contain %, replace all cases of
13437
         fprintf (fp, string) with fputs (string, fp).  The fputs
13438
         builtin will take care of special cases like length == 1.  */
13439
      if (fn_fputs)
13440
        call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
13441
    }
13442
 
13443
  /* The other optimizations can be done only on the non-va_list variants.  */
13444
  else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
13445
    return NULL_TREE;
13446
 
13447
  /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
13448
  else if (strcmp (fmt_str, target_percent_s) == 0)
13449
    {
13450
      if (!arg || !validate_arg (arg, POINTER_TYPE))
13451
        return NULL_TREE;
13452
      if (fn_fputs)
13453
        call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
13454
    }
13455
 
13456
  /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
13457
  else if (strcmp (fmt_str, target_percent_c) == 0)
13458
    {
13459
      if (!arg || !validate_arg (arg, INTEGER_TYPE))
13460
        return NULL_TREE;
13461
      if (fn_fputc)
13462
        call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
13463
    }
13464
 
13465
  if (!call)
13466
    return NULL_TREE;
13467
  return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13468
}
13469
 
13470
/* Initialize format string characters in the target charset.  */
13471
 
13472
static bool
13473
init_target_chars (void)
13474
{
13475
  static bool init;
13476
  if (!init)
13477
    {
13478
      target_newline = lang_hooks.to_target_charset ('\n');
13479
      target_percent = lang_hooks.to_target_charset ('%');
13480
      target_c = lang_hooks.to_target_charset ('c');
13481
      target_s = lang_hooks.to_target_charset ('s');
13482
      if (target_newline == 0 || target_percent == 0 || target_c == 0
13483
          || target_s == 0)
13484
        return false;
13485
 
13486
      target_percent_c[0] = target_percent;
13487
      target_percent_c[1] = target_c;
13488
      target_percent_c[2] = '\0';
13489
 
13490
      target_percent_s[0] = target_percent;
13491
      target_percent_s[1] = target_s;
13492
      target_percent_s[2] = '\0';
13493
 
13494
      target_percent_s_newline[0] = target_percent;
13495
      target_percent_s_newline[1] = target_s;
13496
      target_percent_s_newline[2] = target_newline;
13497
      target_percent_s_newline[3] = '\0';
13498
 
13499
      init = true;
13500
    }
13501
  return true;
13502
}
13503
 
13504
/* Helper function for do_mpfr_arg*().  Ensure M is a normal number
13505
   and no overflow/underflow occurred.  INEXACT is true if M was not
13506
   exactly calculated.  TYPE is the tree type for the result.  This
13507
   function assumes that you cleared the MPFR flags and then
13508
   calculated M to see if anything subsequently set a flag prior to
13509
   entering this function.  Return NULL_TREE if any checks fail.  */
13510
 
13511
static tree
13512
do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13513
{
13514
  /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13515
     overflow/underflow occurred.  If -frounding-math, proceed iff the
13516
     result of calling FUNC was exact.  */
13517
  if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13518
      && (!flag_rounding_math || !inexact))
13519
    {
13520
      REAL_VALUE_TYPE rr;
13521
 
13522
      real_from_mpfr (&rr, m, type, GMP_RNDN);
13523
      /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13524
         check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13525
         but the mpft_t is not, then we underflowed in the
13526
         conversion.  */
13527
      if (real_isfinite (&rr)
13528
          && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13529
        {
13530
          REAL_VALUE_TYPE rmode;
13531
 
13532
          real_convert (&rmode, TYPE_MODE (type), &rr);
13533
          /* Proceed iff the specified mode can hold the value.  */
13534
          if (real_identical (&rmode, &rr))
13535
            return build_real (type, rmode);
13536
        }
13537
    }
13538
  return NULL_TREE;
13539
}
13540
 
13541
/* Helper function for do_mpc_arg*().  Ensure M is a normal complex
13542
   number and no overflow/underflow occurred.  INEXACT is true if M
13543
   was not exactly calculated.  TYPE is the tree type for the result.
13544
   This function assumes that you cleared the MPFR flags and then
13545
   calculated M to see if anything subsequently set a flag prior to
13546
   entering this function.  Return NULL_TREE if any checks fail, if
13547
   FORCE_CONVERT is true, then bypass the checks.  */
13548
 
13549
static tree
13550
do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
13551
{
13552
  /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13553
     overflow/underflow occurred.  If -frounding-math, proceed iff the
13554
     result of calling FUNC was exact.  */
13555
  if (force_convert
13556
      || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13557
          && !mpfr_overflow_p () && !mpfr_underflow_p ()
13558
          && (!flag_rounding_math || !inexact)))
13559
    {
13560
      REAL_VALUE_TYPE re, im;
13561
 
13562
      real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN);
13563
      real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN);
13564
      /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13565
         check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13566
         but the mpft_t is not, then we underflowed in the
13567
         conversion.  */
13568
      if (force_convert
13569
          || (real_isfinite (&re) && real_isfinite (&im)
13570
              && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13571
              && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
13572
        {
13573
          REAL_VALUE_TYPE re_mode, im_mode;
13574
 
13575
          real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13576
          real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13577
          /* Proceed iff the specified mode can hold the value.  */
13578
          if (force_convert
13579
              || (real_identical (&re_mode, &re)
13580
                  && real_identical (&im_mode, &im)))
13581
            return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13582
                                  build_real (TREE_TYPE (type), im_mode));
13583
        }
13584
    }
13585
  return NULL_TREE;
13586
}
13587
 
13588
/* If argument ARG is a REAL_CST, call the one-argument mpfr function
13589
   FUNC on it and return the resulting value as a tree with type TYPE.
13590
   If MIN and/or MAX are not NULL, then the supplied ARG must be
13591
   within those bounds.  If INCLUSIVE is true, then MIN/MAX are
13592
   acceptable values, otherwise they are not.  The mpfr precision is
13593
   set to the precision of TYPE.  We assume that function FUNC returns
13594
   zero if the result could be calculated exactly within the requested
13595
   precision.  */
13596
 
13597
static tree
13598
do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13599
              const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13600
              bool inclusive)
13601
{
13602
  tree result = NULL_TREE;
13603
 
13604
  STRIP_NOPS (arg);
13605
 
13606
  /* To proceed, MPFR must exactly represent the target floating point
13607
     format, which only happens when the target base equals two.  */
13608
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13609
      && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13610
    {
13611
      const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13612
 
13613
      if (real_isfinite (ra)
13614
          && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13615
          && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13616
        {
13617
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13618
          const int prec = fmt->p;
13619
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13620
          int inexact;
13621
          mpfr_t m;
13622
 
13623
          mpfr_init2 (m, prec);
13624
          mpfr_from_real (m, ra, GMP_RNDN);
13625
          mpfr_clear_flags ();
13626
          inexact = func (m, m, rnd);
13627
          result = do_mpfr_ckconv (m, type, inexact);
13628
          mpfr_clear (m);
13629
        }
13630
    }
13631
 
13632
  return result;
13633
}
13634
 
13635
/* If argument ARG is a REAL_CST, call the two-argument mpfr function
13636
   FUNC on it and return the resulting value as a tree with type TYPE.
13637
   The mpfr precision is set to the precision of TYPE.  We assume that
13638
   function FUNC returns zero if the result could be calculated
13639
   exactly within the requested precision.  */
13640
 
13641
static tree
13642
do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13643
              int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13644
{
13645
  tree result = NULL_TREE;
13646
 
13647
  STRIP_NOPS (arg1);
13648
  STRIP_NOPS (arg2);
13649
 
13650
  /* To proceed, MPFR must exactly represent the target floating point
13651
     format, which only happens when the target base equals two.  */
13652
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13653
      && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13654
      && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13655
    {
13656
      const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13657
      const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13658
 
13659
      if (real_isfinite (ra1) && real_isfinite (ra2))
13660
        {
13661
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13662
          const int prec = fmt->p;
13663
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13664
          int inexact;
13665
          mpfr_t m1, m2;
13666
 
13667
          mpfr_inits2 (prec, m1, m2, NULL);
13668
          mpfr_from_real (m1, ra1, GMP_RNDN);
13669
          mpfr_from_real (m2, ra2, GMP_RNDN);
13670
          mpfr_clear_flags ();
13671
          inexact = func (m1, m1, m2, rnd);
13672
          result = do_mpfr_ckconv (m1, type, inexact);
13673
          mpfr_clears (m1, m2, NULL);
13674
        }
13675
    }
13676
 
13677
  return result;
13678
}
13679
 
13680
/* If argument ARG is a REAL_CST, call the three-argument mpfr function
13681
   FUNC on it and return the resulting value as a tree with type TYPE.
13682
   The mpfr precision is set to the precision of TYPE.  We assume that
13683
   function FUNC returns zero if the result could be calculated
13684
   exactly within the requested precision.  */
13685
 
13686
static tree
13687
do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13688
              int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13689
{
13690
  tree result = NULL_TREE;
13691
 
13692
  STRIP_NOPS (arg1);
13693
  STRIP_NOPS (arg2);
13694
  STRIP_NOPS (arg3);
13695
 
13696
  /* To proceed, MPFR must exactly represent the target floating point
13697
     format, which only happens when the target base equals two.  */
13698
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13699
      && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13700
      && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13701
      && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13702
    {
13703
      const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13704
      const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13705
      const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13706
 
13707
      if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13708
        {
13709
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13710
          const int prec = fmt->p;
13711
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13712
          int inexact;
13713
          mpfr_t m1, m2, m3;
13714
 
13715
          mpfr_inits2 (prec, m1, m2, m3, NULL);
13716
          mpfr_from_real (m1, ra1, GMP_RNDN);
13717
          mpfr_from_real (m2, ra2, GMP_RNDN);
13718
          mpfr_from_real (m3, ra3, GMP_RNDN);
13719
          mpfr_clear_flags ();
13720
          inexact = func (m1, m1, m2, m3, rnd);
13721
          result = do_mpfr_ckconv (m1, type, inexact);
13722
          mpfr_clears (m1, m2, m3, NULL);
13723
        }
13724
    }
13725
 
13726
  return result;
13727
}
13728
 
13729
/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13730
   the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13731
   If ARG_SINP and ARG_COSP are NULL then the result is returned
13732
   as a complex value.
13733
   The type is taken from the type of ARG and is used for setting the
13734
   precision of the calculation and results.  */
13735
 
13736
static tree
13737
do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13738
{
13739
  tree const type = TREE_TYPE (arg);
13740
  tree result = NULL_TREE;
13741
 
13742
  STRIP_NOPS (arg);
13743
 
13744
  /* To proceed, MPFR must exactly represent the target floating point
13745
     format, which only happens when the target base equals two.  */
13746
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13747
      && TREE_CODE (arg) == REAL_CST
13748
      && !TREE_OVERFLOW (arg))
13749
    {
13750
      const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13751
 
13752
      if (real_isfinite (ra))
13753
        {
13754
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13755
          const int prec = fmt->p;
13756
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13757
          tree result_s, result_c;
13758
          int inexact;
13759
          mpfr_t m, ms, mc;
13760
 
13761
          mpfr_inits2 (prec, m, ms, mc, NULL);
13762
          mpfr_from_real (m, ra, GMP_RNDN);
13763
          mpfr_clear_flags ();
13764
          inexact = mpfr_sin_cos (ms, mc, m, rnd);
13765
          result_s = do_mpfr_ckconv (ms, type, inexact);
13766
          result_c = do_mpfr_ckconv (mc, type, inexact);
13767
          mpfr_clears (m, ms, mc, NULL);
13768
          if (result_s && result_c)
13769
            {
13770
              /* If we are to return in a complex value do so.  */
13771
              if (!arg_sinp && !arg_cosp)
13772
                return build_complex (build_complex_type (type),
13773
                                      result_c, result_s);
13774
 
13775
              /* Dereference the sin/cos pointer arguments.  */
13776
              arg_sinp = build_fold_indirect_ref (arg_sinp);
13777
              arg_cosp = build_fold_indirect_ref (arg_cosp);
13778
              /* Proceed if valid pointer type were passed in.  */
13779
              if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13780
                  && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13781
                {
13782
                  /* Set the values. */
13783
                  result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13784
                                          result_s);
13785
                  TREE_SIDE_EFFECTS (result_s) = 1;
13786
                  result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13787
                                          result_c);
13788
                  TREE_SIDE_EFFECTS (result_c) = 1;
13789
                  /* Combine the assignments into a compound expr.  */
13790
                  result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13791
                                                    result_s, result_c));
13792
                }
13793
            }
13794
        }
13795
    }
13796
  return result;
13797
}
13798
 
13799
/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13800
   two-argument mpfr order N Bessel function FUNC on them and return
13801
   the resulting value as a tree with type TYPE.  The mpfr precision
13802
   is set to the precision of TYPE.  We assume that function FUNC
13803
   returns zero if the result could be calculated exactly within the
13804
   requested precision.  */
13805
static tree
13806
do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13807
                  int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13808
                  const REAL_VALUE_TYPE *min, bool inclusive)
13809
{
13810
  tree result = NULL_TREE;
13811
 
13812
  STRIP_NOPS (arg1);
13813
  STRIP_NOPS (arg2);
13814
 
13815
  /* To proceed, MPFR must exactly represent the target floating point
13816
     format, which only happens when the target base equals two.  */
13817
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13818
      && host_integerp (arg1, 0)
13819
      && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13820
    {
13821
      const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13822
      const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13823
 
13824
      if (n == (long)n
13825
          && real_isfinite (ra)
13826
          && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13827
        {
13828
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13829
          const int prec = fmt->p;
13830
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13831
          int inexact;
13832
          mpfr_t m;
13833
 
13834
          mpfr_init2 (m, prec);
13835
          mpfr_from_real (m, ra, GMP_RNDN);
13836
          mpfr_clear_flags ();
13837
          inexact = func (m, n, m, rnd);
13838
          result = do_mpfr_ckconv (m, type, inexact);
13839
          mpfr_clear (m);
13840
        }
13841
    }
13842
 
13843
  return result;
13844
}
13845
 
13846
/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13847
   the pointer *(ARG_QUO) and return the result.  The type is taken
13848
   from the type of ARG0 and is used for setting the precision of the
13849
   calculation and results.  */
13850
 
13851
static tree
13852
do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13853
{
13854
  tree const type = TREE_TYPE (arg0);
13855
  tree result = NULL_TREE;
13856
 
13857
  STRIP_NOPS (arg0);
13858
  STRIP_NOPS (arg1);
13859
 
13860
  /* To proceed, MPFR must exactly represent the target floating point
13861
     format, which only happens when the target base equals two.  */
13862
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13863
      && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13864
      && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13865
    {
13866
      const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13867
      const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13868
 
13869
      if (real_isfinite (ra0) && real_isfinite (ra1))
13870
        {
13871
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13872
          const int prec = fmt->p;
13873
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13874
          tree result_rem;
13875
          long integer_quo;
13876
          mpfr_t m0, m1;
13877
 
13878
          mpfr_inits2 (prec, m0, m1, NULL);
13879
          mpfr_from_real (m0, ra0, GMP_RNDN);
13880
          mpfr_from_real (m1, ra1, GMP_RNDN);
13881
          mpfr_clear_flags ();
13882
          mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13883
          /* Remquo is independent of the rounding mode, so pass
13884
             inexact=0 to do_mpfr_ckconv().  */
13885
          result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13886
          mpfr_clears (m0, m1, NULL);
13887
          if (result_rem)
13888
            {
13889
              /* MPFR calculates quo in the host's long so it may
13890
                 return more bits in quo than the target int can hold
13891
                 if sizeof(host long) > sizeof(target int).  This can
13892
                 happen even for native compilers in LP64 mode.  In
13893
                 these cases, modulo the quo value with the largest
13894
                 number that the target int can hold while leaving one
13895
                 bit for the sign.  */
13896
              if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13897
                integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13898
 
13899
              /* Dereference the quo pointer argument.  */
13900
              arg_quo = build_fold_indirect_ref (arg_quo);
13901
              /* Proceed iff a valid pointer type was passed in.  */
13902
              if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13903
                {
13904
                  /* Set the value. */
13905
                  tree result_quo
13906
                    = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg_quo), arg_quo,
13907
                                   build_int_cst (TREE_TYPE (arg_quo),
13908
                                                  integer_quo));
13909
                  TREE_SIDE_EFFECTS (result_quo) = 1;
13910
                  /* Combine the quo assignment with the rem.  */
13911
                  result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13912
                                                    result_quo, result_rem));
13913
                }
13914
            }
13915
        }
13916
    }
13917
  return result;
13918
}
13919
 
13920
/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13921
   resulting value as a tree with type TYPE.  The mpfr precision is
13922
   set to the precision of TYPE.  We assume that this mpfr function
13923
   returns zero if the result could be calculated exactly within the
13924
   requested precision.  In addition, the integer pointer represented
13925
   by ARG_SG will be dereferenced and set to the appropriate signgam
13926
   (-1,1) value.  */
13927
 
13928
static tree
13929
do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13930
{
13931
  tree result = NULL_TREE;
13932
 
13933
  STRIP_NOPS (arg);
13934
 
13935
  /* To proceed, MPFR must exactly represent the target floating point
13936
     format, which only happens when the target base equals two.  Also
13937
     verify ARG is a constant and that ARG_SG is an int pointer.  */
13938
  if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13939
      && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13940
      && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13941
      && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13942
    {
13943
      const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13944
 
13945
      /* In addition to NaN and Inf, the argument cannot be zero or a
13946
         negative integer.  */
13947
      if (real_isfinite (ra)
13948
          && ra->cl != rvc_zero
13949
          && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13950
        {
13951
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13952
          const int prec = fmt->p;
13953
          const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13954
          int inexact, sg;
13955
          mpfr_t m;
13956
          tree result_lg;
13957
 
13958
          mpfr_init2 (m, prec);
13959
          mpfr_from_real (m, ra, GMP_RNDN);
13960
          mpfr_clear_flags ();
13961
          inexact = mpfr_lgamma (m, &sg, m, rnd);
13962
          result_lg = do_mpfr_ckconv (m, type, inexact);
13963
          mpfr_clear (m);
13964
          if (result_lg)
13965
            {
13966
              tree result_sg;
13967
 
13968
              /* Dereference the arg_sg pointer argument.  */
13969
              arg_sg = build_fold_indirect_ref (arg_sg);
13970
              /* Assign the signgam value into *arg_sg. */
13971
              result_sg = fold_build2 (MODIFY_EXPR,
13972
                                       TREE_TYPE (arg_sg), arg_sg,
13973
                                       build_int_cst (TREE_TYPE (arg_sg), sg));
13974
              TREE_SIDE_EFFECTS (result_sg) = 1;
13975
              /* Combine the signgam assignment with the lgamma result.  */
13976
              result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13977
                                                result_sg, result_lg));
13978
            }
13979
        }
13980
    }
13981
 
13982
  return result;
13983
}
13984
 
13985
/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13986
   function FUNC on it and return the resulting value as a tree with
13987
   type TYPE.  The mpfr precision is set to the precision of TYPE.  We
13988
   assume that function FUNC returns zero if the result could be
13989
   calculated exactly within the requested precision.  */
13990
 
13991
static tree
13992
do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13993
{
13994
  tree result = NULL_TREE;
13995
 
13996
  STRIP_NOPS (arg);
13997
 
13998
  /* To proceed, MPFR must exactly represent the target floating point
13999
     format, which only happens when the target base equals two.  */
14000
  if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
14001
      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
14002
      && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
14003
    {
14004
      const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
14005
      const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
14006
 
14007
      if (real_isfinite (re) && real_isfinite (im))
14008
        {
14009
          const struct real_format *const fmt =
14010
            REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14011
          const int prec = fmt->p;
14012
          const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14013
          const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14014
          int inexact;
14015
          mpc_t m;
14016
 
14017
          mpc_init2 (m, prec);
14018
          mpfr_from_real (mpc_realref(m), re, rnd);
14019
          mpfr_from_real (mpc_imagref(m), im, rnd);
14020
          mpfr_clear_flags ();
14021
          inexact = func (m, m, crnd);
14022
          result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
14023
          mpc_clear (m);
14024
        }
14025
    }
14026
 
14027
  return result;
14028
}
14029
 
14030
/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
14031
   mpc function FUNC on it and return the resulting value as a tree
14032
   with type TYPE.  The mpfr precision is set to the precision of
14033
   TYPE.  We assume that function FUNC returns zero if the result
14034
   could be calculated exactly within the requested precision.  If
14035
   DO_NONFINITE is true, then fold expressions containing Inf or NaN
14036
   in the arguments and/or results.  */
14037
 
14038
tree
14039
do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
14040
             int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
14041
{
14042
  tree result = NULL_TREE;
14043
 
14044
  STRIP_NOPS (arg0);
14045
  STRIP_NOPS (arg1);
14046
 
14047
  /* To proceed, MPFR must exactly represent the target floating point
14048
     format, which only happens when the target base equals two.  */
14049
  if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
14050
      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
14051
      && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
14052
      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
14053
      && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
14054
    {
14055
      const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
14056
      const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
14057
      const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
14058
      const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
14059
 
14060
      if (do_nonfinite
14061
          || (real_isfinite (re0) && real_isfinite (im0)
14062
              && real_isfinite (re1) && real_isfinite (im1)))
14063
        {
14064
          const struct real_format *const fmt =
14065
            REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14066
          const int prec = fmt->p;
14067
          const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14068
          const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14069
          int inexact;
14070
          mpc_t m0, m1;
14071
 
14072
          mpc_init2 (m0, prec);
14073
          mpc_init2 (m1, prec);
14074
          mpfr_from_real (mpc_realref(m0), re0, rnd);
14075
          mpfr_from_real (mpc_imagref(m0), im0, rnd);
14076
          mpfr_from_real (mpc_realref(m1), re1, rnd);
14077
          mpfr_from_real (mpc_imagref(m1), im1, rnd);
14078
          mpfr_clear_flags ();
14079
          inexact = func (m0, m0, m1, crnd);
14080
          result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
14081
          mpc_clear (m0);
14082
          mpc_clear (m1);
14083
        }
14084
    }
14085
 
14086
  return result;
14087
}
14088
 
14089
/* Fold a call STMT to __{,v}sprintf_chk.  Return NULL_TREE if
14090
   a normal call should be emitted rather than expanding the function
14091
   inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
14092
 
14093
static tree
14094
gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
14095
{
14096
  int nargs = gimple_call_num_args (stmt);
14097
 
14098
  return fold_builtin_sprintf_chk_1 (gimple_location (stmt), nargs,
14099
                                     (nargs > 0
14100
                                      ? gimple_call_arg_ptr (stmt, 0)
14101
                                      : &error_mark_node), fcode);
14102
}
14103
 
14104
/* Fold a call STMT to {,v}snprintf.  Return NULL_TREE if
14105
   a normal call should be emitted rather than expanding the function
14106
   inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
14107
   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
14108
   passed as second argument.  */
14109
 
14110
tree
14111
gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
14112
                                  enum built_in_function fcode)
14113
{
14114
  int nargs = gimple_call_num_args (stmt);
14115
 
14116
  return fold_builtin_snprintf_chk_1 (gimple_location (stmt), nargs,
14117
                                      (nargs > 0
14118
                                       ? gimple_call_arg_ptr (stmt, 0)
14119
                                       : &error_mark_node), maxlen, fcode);
14120
}
14121
 
14122
/* Builtins with folding operations that operate on "..." arguments
14123
   need special handling; we need to store the arguments in a convenient
14124
   data structure before attempting any folding.  Fortunately there are
14125
   only a few builtins that fall into this category.  FNDECL is the
14126
   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14127
   result of the function call is ignored.  */
14128
 
14129
static tree
14130
gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
14131
                             bool ignore ATTRIBUTE_UNUSED)
14132
{
14133
  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14134
  tree ret = NULL_TREE;
14135
 
14136
  switch (fcode)
14137
    {
14138
    case BUILT_IN_SPRINTF_CHK:
14139
    case BUILT_IN_VSPRINTF_CHK:
14140
      ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14141
      break;
14142
 
14143
    case BUILT_IN_SNPRINTF_CHK:
14144
    case BUILT_IN_VSNPRINTF_CHK:
14145
      ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14146
 
14147
    default:
14148
      break;
14149
    }
14150
  if (ret)
14151
    {
14152
      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14153
      TREE_NO_WARNING (ret) = 1;
14154
      return ret;
14155
    }
14156
  return NULL_TREE;
14157
}
14158
 
14159
/* A wrapper function for builtin folding that prevents warnings for
14160
   "statement without effect" and the like, caused by removing the
14161
   call node earlier than the warning is generated.  */
14162
 
14163
tree
14164
fold_call_stmt (gimple stmt, bool ignore)
14165
{
14166
  tree ret = NULL_TREE;
14167
  tree fndecl = gimple_call_fndecl (stmt);
14168
  location_t loc = gimple_location (stmt);
14169
  if (fndecl
14170
      && TREE_CODE (fndecl) == FUNCTION_DECL
14171
      && DECL_BUILT_IN (fndecl)
14172
      && !gimple_call_va_arg_pack_p (stmt))
14173
    {
14174
      int nargs = gimple_call_num_args (stmt);
14175
      tree *args = (nargs > 0
14176
                    ? gimple_call_arg_ptr (stmt, 0)
14177
                    : &error_mark_node);
14178
 
14179
      if (avoid_folding_inline_builtin (fndecl))
14180
        return NULL_TREE;
14181
      if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14182
        {
14183
          return targetm.fold_builtin (fndecl, nargs, args, ignore);
14184
        }
14185
      else
14186
        {
14187
          if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14188
            ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
14189
          if (!ret)
14190
            ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14191
          if (ret)
14192
            {
14193
              /* Propagate location information from original call to
14194
                 expansion of builtin.  Otherwise things like
14195
                 maybe_emit_chk_warning, that operate on the expansion
14196
                 of a builtin, will use the wrong location information.  */
14197
              if (gimple_has_location (stmt))
14198
                {
14199
                  tree realret = ret;
14200
                  if (TREE_CODE (ret) == NOP_EXPR)
14201
                    realret = TREE_OPERAND (ret, 0);
14202
                  if (CAN_HAVE_LOCATION_P (realret)
14203
                      && !EXPR_HAS_LOCATION (realret))
14204
                    SET_EXPR_LOCATION (realret, loc);
14205
                  return realret;
14206
                }
14207
              return ret;
14208
            }
14209
        }
14210
    }
14211
  return NULL_TREE;
14212
}
14213
 
14214
/* Look up the function in builtin_decl that corresponds to DECL
14215
   and set ASMSPEC as its user assembler name.  DECL must be a
14216
   function decl that declares a builtin.  */
14217
 
14218
void
14219
set_builtin_user_assembler_name (tree decl, const char *asmspec)
14220
{
14221
  tree builtin;
14222
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
14223
              && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
14224
              && asmspec != 0);
14225
 
14226
  builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
14227
  set_user_assembler_name (builtin, asmspec);
14228
  switch (DECL_FUNCTION_CODE (decl))
14229
    {
14230
    case BUILT_IN_MEMCPY:
14231
      init_block_move_fn (asmspec);
14232
      memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
14233
      break;
14234
    case BUILT_IN_MEMSET:
14235
      init_block_clear_fn (asmspec);
14236
      memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
14237
      break;
14238
    case BUILT_IN_MEMMOVE:
14239
      memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
14240
      break;
14241
    case BUILT_IN_MEMCMP:
14242
      memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
14243
      break;
14244
    case BUILT_IN_ABORT:
14245
      abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
14246
      break;
14247
    case BUILT_IN_FFS:
14248
      if (INT_TYPE_SIZE < BITS_PER_WORD)
14249
        {
14250
          set_user_assembler_libfunc ("ffs", asmspec);
14251
          set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE,
14252
                                                       MODE_INT, 0), "ffs");
14253
        }
14254
      break;
14255
    default:
14256
      break;
14257
    }
14258
}
14259
 
14260
/* Return true if DECL is a builtin that expands to a constant or similarly
14261
   simple code.  */
14262
bool
14263
is_simple_builtin (tree decl)
14264
{
14265
  if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14266
    switch (DECL_FUNCTION_CODE (decl))
14267
      {
14268
        /* Builtins that expand to constants.  */
14269
      case BUILT_IN_CONSTANT_P:
14270
      case BUILT_IN_EXPECT:
14271
      case BUILT_IN_OBJECT_SIZE:
14272
      case BUILT_IN_UNREACHABLE:
14273
        /* Simple register moves or loads from stack.  */
14274
      case BUILT_IN_ASSUME_ALIGNED:
14275
      case BUILT_IN_RETURN_ADDRESS:
14276
      case BUILT_IN_EXTRACT_RETURN_ADDR:
14277
      case BUILT_IN_FROB_RETURN_ADDR:
14278
      case BUILT_IN_RETURN:
14279
      case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
14280
      case BUILT_IN_FRAME_ADDRESS:
14281
      case BUILT_IN_VA_END:
14282
      case BUILT_IN_STACK_SAVE:
14283
      case BUILT_IN_STACK_RESTORE:
14284
        /* Exception state returns or moves registers around.  */
14285
      case BUILT_IN_EH_FILTER:
14286
      case BUILT_IN_EH_POINTER:
14287
      case BUILT_IN_EH_COPY_VALUES:
14288
        return true;
14289
 
14290
      default:
14291
        return false;
14292
      }
14293
 
14294
  return false;
14295
}
14296
 
14297
/* Return true if DECL is a builtin that is not expensive, i.e., they are
14298
   most probably expanded inline into reasonably simple code.  This is a
14299
   superset of is_simple_builtin.  */
14300
bool
14301
is_inexpensive_builtin (tree decl)
14302
{
14303
  if (!decl)
14304
    return false;
14305
  else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
14306
    return true;
14307
  else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14308
    switch (DECL_FUNCTION_CODE (decl))
14309
      {
14310
      case BUILT_IN_ABS:
14311
      case BUILT_IN_ALLOCA:
14312
      case BUILT_IN_ALLOCA_WITH_ALIGN:
14313
      case BUILT_IN_BSWAP32:
14314
      case BUILT_IN_BSWAP64:
14315
      case BUILT_IN_CLZ:
14316
      case BUILT_IN_CLZIMAX:
14317
      case BUILT_IN_CLZL:
14318
      case BUILT_IN_CLZLL:
14319
      case BUILT_IN_CTZ:
14320
      case BUILT_IN_CTZIMAX:
14321
      case BUILT_IN_CTZL:
14322
      case BUILT_IN_CTZLL:
14323
      case BUILT_IN_FFS:
14324
      case BUILT_IN_FFSIMAX:
14325
      case BUILT_IN_FFSL:
14326
      case BUILT_IN_FFSLL:
14327
      case BUILT_IN_IMAXABS:
14328
      case BUILT_IN_FINITE:
14329
      case BUILT_IN_FINITEF:
14330
      case BUILT_IN_FINITEL:
14331
      case BUILT_IN_FINITED32:
14332
      case BUILT_IN_FINITED64:
14333
      case BUILT_IN_FINITED128:
14334
      case BUILT_IN_FPCLASSIFY:
14335
      case BUILT_IN_ISFINITE:
14336
      case BUILT_IN_ISINF_SIGN:
14337
      case BUILT_IN_ISINF:
14338
      case BUILT_IN_ISINFF:
14339
      case BUILT_IN_ISINFL:
14340
      case BUILT_IN_ISINFD32:
14341
      case BUILT_IN_ISINFD64:
14342
      case BUILT_IN_ISINFD128:
14343
      case BUILT_IN_ISNAN:
14344
      case BUILT_IN_ISNANF:
14345
      case BUILT_IN_ISNANL:
14346
      case BUILT_IN_ISNAND32:
14347
      case BUILT_IN_ISNAND64:
14348
      case BUILT_IN_ISNAND128:
14349
      case BUILT_IN_ISNORMAL:
14350
      case BUILT_IN_ISGREATER:
14351
      case BUILT_IN_ISGREATEREQUAL:
14352
      case BUILT_IN_ISLESS:
14353
      case BUILT_IN_ISLESSEQUAL:
14354
      case BUILT_IN_ISLESSGREATER:
14355
      case BUILT_IN_ISUNORDERED:
14356
      case BUILT_IN_VA_ARG_PACK:
14357
      case BUILT_IN_VA_ARG_PACK_LEN:
14358
      case BUILT_IN_VA_COPY:
14359
      case BUILT_IN_TRAP:
14360
      case BUILT_IN_SAVEREGS:
14361
      case BUILT_IN_POPCOUNTL:
14362
      case BUILT_IN_POPCOUNTLL:
14363
      case BUILT_IN_POPCOUNTIMAX:
14364
      case BUILT_IN_POPCOUNT:
14365
      case BUILT_IN_PARITYL:
14366
      case BUILT_IN_PARITYLL:
14367
      case BUILT_IN_PARITYIMAX:
14368
      case BUILT_IN_PARITY:
14369
      case BUILT_IN_LABS:
14370
      case BUILT_IN_LLABS:
14371
      case BUILT_IN_PREFETCH:
14372
        return true;
14373
 
14374
      default:
14375
        return is_simple_builtin (decl);
14376
      }
14377
 
14378
  return false;
14379
}

powered by: WebSVN 2.1.0

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