mirror of
https://github.com/rtlduino/RTL8710AF_GCC.git
synced 2026-07-15 15:55:41 +00:00
motify compile link error
motify compile link error
This commit is contained in:
parent
923914edae
commit
03e74a8e50
5418 changed files with 1367914 additions and 206149 deletions
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,74 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* GNAT COMPILER COMPONENTS *
|
||||
* *
|
||||
* GNAT-SPECIFIC GCC TREE CODES *
|
||||
* *
|
||||
* Specification *
|
||||
* *
|
||||
* Copyright (C) 1992-2009, Free Software Foundation, Inc. *
|
||||
* *
|
||||
* GNAT is free software; you can redistribute it and/or modify it under *
|
||||
* terms of the GNU General Public License as published by the Free Soft- *
|
||||
* ware Foundation; either version 3, or (at your option) any later ver- *
|
||||
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
||||
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
||||
* for more details. You should have received a copy of the GNU General *
|
||||
* Public License along with GCC; see the file COPYING3. If not see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* GNAT was originally developed by the GNAT team at New York University. *
|
||||
* Extensive contributions were provided by Ada Core Technologies Inc. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
/* A type that is an unconstrained array. This node is never passed to GCC.
|
||||
TREE_TYPE is the type of the fat pointer and TYPE_OBJECT_RECORD_TYPE is
|
||||
the type of a record containing the template and data. */
|
||||
DEFTREECODE (UNCONSTRAINED_ARRAY_TYPE, "unconstrained_array_type", tcc_type, 0)
|
||||
|
||||
/* A reference to an unconstrained array. This node only exists as an
|
||||
intermediate node during the translation of a GNAT tree to a GCC tree;
|
||||
it is never passed to GCC. The only field used is operand 0, which
|
||||
is the fat pointer object. */
|
||||
DEFTREECODE (UNCONSTRAINED_ARRAY_REF, "unconstrained_array_ref",
|
||||
tcc_reference, 1)
|
||||
|
||||
/* An expression that returns an RTL suitable for its type. Operand 0
|
||||
is an expression to be evaluated for side effects only. */
|
||||
DEFTREECODE (NULL_EXPR, "null_expr", tcc_expression, 1)
|
||||
|
||||
/* Same as PLUS_EXPR, except that no modulo reduction is applied.
|
||||
This is used for loops and never shows up in the tree. */
|
||||
DEFTREECODE (PLUS_NOMOD_EXPR, "plus_nomod_expr", tcc_binary, 2)
|
||||
|
||||
/* Same as MINUS_EXPR, except that no modulo reduction is applied.
|
||||
This is used for loops and never shows up in the tree. */
|
||||
DEFTREECODE (MINUS_NOMOD_EXPR, "minus_nomod_expr", tcc_binary, 2)
|
||||
|
||||
/* Same as ADDR_EXPR, except that if the operand represents a bit field,
|
||||
return the address of the byte containing the bit. This is used
|
||||
for the Address attribute and never shows up in the tree. */
|
||||
DEFTREECODE (ATTR_ADDR_EXPR, "attr_addr_expr", tcc_reference, 1)
|
||||
|
||||
/* Here are the tree codes for the statement types known to Ada. These
|
||||
must be at the end of this file to allow IS_ADA_STMT to work. */
|
||||
|
||||
/* This is how record_code_position and insert_code_for work. The former
|
||||
makes this tree node, whose operand is a statement. The latter inserts
|
||||
the actual statements into this node. Gimplification consists of
|
||||
just returning the inner statement. */
|
||||
DEFTREECODE (STMT_STMT, "stmt_stmt", tcc_statement, 1)
|
||||
|
||||
/* A loop. LOOP_STMT_COND is the test to exit the loop. LOOP_STMT_UPDATE
|
||||
is the statement to update the loop iteration variable at the continue
|
||||
point. LOOP_STMT_BODY are the statements in the body of the loop. And
|
||||
LOOP_STMT_LABEL points to the LABEL_DECL of the end label of the loop. */
|
||||
DEFTREECODE (LOOP_STMT, "loop_stmt", tcc_statement, 4)
|
||||
|
||||
/* Conditionally exit a loop. EXIT_STMT_COND is the condition, which, if
|
||||
true, will cause the loop to be exited. If no condition is specified,
|
||||
the loop is unconditionally exited. EXIT_STMT_LABEL is the end label
|
||||
corresponding to the loop to exit. */
|
||||
DEFTREECODE (EXIT_STMT, "exit_stmt", tcc_statement, 2)
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/* Exported functions from alias.c
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_ALIAS_H
|
||||
#define GCC_ALIAS_H
|
||||
|
||||
/* The type of an alias set. Code currently assumes that variables of
|
||||
this type can take the values 0 (the alias set which aliases
|
||||
everything) and -1 (sometimes indicating that the alias set is
|
||||
unknown, sometimes indicating a memory barrier) and -2 (indicating
|
||||
that the alias set should be set to a unique value but has not been
|
||||
set yet). */
|
||||
typedef int alias_set_type;
|
||||
|
||||
extern alias_set_type new_alias_set (void);
|
||||
extern alias_set_type get_alias_set (tree);
|
||||
extern alias_set_type get_deref_alias_set (tree);
|
||||
extern alias_set_type get_varargs_alias_set (void);
|
||||
extern alias_set_type get_frame_alias_set (void);
|
||||
extern bool component_uses_parent_alias_set (const_tree);
|
||||
extern bool alias_set_subset_of (alias_set_type, alias_set_type);
|
||||
extern void record_alias_subset (alias_set_type, alias_set_type);
|
||||
extern void record_component_aliases (tree);
|
||||
extern int alias_sets_conflict_p (alias_set_type, alias_set_type);
|
||||
extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type);
|
||||
extern int objects_must_conflict_p (tree, tree);
|
||||
extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool);
|
||||
|
||||
/* This alias set can be used to force a memory to conflict with all
|
||||
other memories, creating a barrier across which no memory reference
|
||||
can move. Note that there are other legacy ways to create such
|
||||
memory barriers, including an address of SCRATCH. */
|
||||
#define ALIAS_SET_MEMORY_BARRIER ((alias_set_type) -1)
|
||||
|
||||
#endif /* GCC_ALIAS_H */
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "tree.def"
|
||||
END_OF_BASE_TREE_CODES
|
||||
#include "c-family/c-common.def"
|
||||
#include "ada/gcc-interface/ada-tree.def"
|
||||
#include "cp/cp-tree.def"
|
||||
#include "java/java-tree.def"
|
||||
#include "objc/objc-tree.def"
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* Functions to support a pool of allocatable objects
|
||||
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
||||
Contributed by Daniel Berlin <dan@cgsoftware.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
#ifndef ALLOC_POOL_H
|
||||
#define ALLOC_POOL_H
|
||||
|
||||
typedef unsigned long ALLOC_POOL_ID_TYPE;
|
||||
|
||||
typedef struct alloc_pool_list_def
|
||||
{
|
||||
struct alloc_pool_list_def *next;
|
||||
}
|
||||
*alloc_pool_list;
|
||||
|
||||
typedef struct alloc_pool_def
|
||||
{
|
||||
const char *name;
|
||||
#ifdef ENABLE_CHECKING
|
||||
ALLOC_POOL_ID_TYPE id;
|
||||
#endif
|
||||
size_t elts_per_block;
|
||||
|
||||
/* These are the elements that have been allocated at least once and freed. */
|
||||
alloc_pool_list returned_free_list;
|
||||
|
||||
/* These are the elements that have not yet been allocated out of
|
||||
the last block obtained from XNEWVEC. */
|
||||
char* virgin_free_list;
|
||||
|
||||
/* The number of elements in the virgin_free_list that can be
|
||||
allocated before needing another block. */
|
||||
size_t virgin_elts_remaining;
|
||||
|
||||
size_t elts_allocated;
|
||||
size_t elts_free;
|
||||
size_t blocks_allocated;
|
||||
alloc_pool_list block_list;
|
||||
size_t block_size;
|
||||
size_t elt_size;
|
||||
}
|
||||
*alloc_pool;
|
||||
|
||||
extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
|
||||
extern void free_alloc_pool (alloc_pool);
|
||||
extern void empty_alloc_pool (alloc_pool);
|
||||
extern void free_alloc_pool_if_empty (alloc_pool *);
|
||||
extern void *pool_alloc (alloc_pool) ATTRIBUTE_MALLOC;
|
||||
extern void pool_free (alloc_pool, void *);
|
||||
extern void dump_alloc_pool_statistics (void);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,441 @@
|
|||
/* ANSI and traditional C compatability macros
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* ANSI and traditional C compatibility macros
|
||||
|
||||
ANSI C is assumed if __STDC__ is #defined.
|
||||
|
||||
Macro ANSI C definition Traditional C definition
|
||||
----- ---- - ---------- ----------- - ----------
|
||||
ANSI_PROTOTYPES 1 not defined
|
||||
PTR `void *' `char *'
|
||||
PTRCONST `void *const' `char *'
|
||||
LONG_DOUBLE `long double' `double'
|
||||
const not defined `'
|
||||
volatile not defined `'
|
||||
signed not defined `'
|
||||
VA_START(ap, var) va_start(ap, var) va_start(ap)
|
||||
|
||||
Note that it is safe to write "void foo();" indicating a function
|
||||
with no return value, in all K+R compilers we have been able to test.
|
||||
|
||||
For declaring functions with prototypes, we also provide these:
|
||||
|
||||
PARAMS ((prototype))
|
||||
-- for functions which take a fixed number of arguments. Use this
|
||||
when declaring the function. When defining the function, write a
|
||||
K+R style argument list. For example:
|
||||
|
||||
char *strcpy PARAMS ((char *dest, char *source));
|
||||
...
|
||||
char *
|
||||
strcpy (dest, source)
|
||||
char *dest;
|
||||
char *source;
|
||||
{ ... }
|
||||
|
||||
|
||||
VPARAMS ((prototype, ...))
|
||||
-- for functions which take a variable number of arguments. Use
|
||||
PARAMS to declare the function, VPARAMS to define it. For example:
|
||||
|
||||
int printf PARAMS ((const char *format, ...));
|
||||
...
|
||||
int
|
||||
printf VPARAMS ((const char *format, ...))
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
For writing functions which take variable numbers of arguments, we
|
||||
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
|
||||
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
|
||||
thoroughly than the simple VA_START() macro mentioned above.
|
||||
|
||||
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
|
||||
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
|
||||
corresponding to the list of fixed arguments. Then use va_arg
|
||||
normally to get the variable arguments, or pass your va_list object
|
||||
around. You do not declare the va_list yourself; VA_OPEN does it
|
||||
for you.
|
||||
|
||||
Here is a complete example:
|
||||
|
||||
int
|
||||
printf VPARAMS ((const char *format, ...))
|
||||
{
|
||||
int result;
|
||||
|
||||
VA_OPEN (ap, format);
|
||||
VA_FIXEDARG (ap, const char *, format);
|
||||
|
||||
result = vfprintf (stdout, format, ap);
|
||||
VA_CLOSE (ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
You can declare variables either before or after the VA_OPEN,
|
||||
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
|
||||
and end of a block. They must appear at the same nesting level,
|
||||
and any variables declared after VA_OPEN go out of scope at
|
||||
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
|
||||
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
|
||||
pairs in a single function in case you need to traverse the
|
||||
argument list more than once.
|
||||
|
||||
For ease of writing code which uses GCC extensions but needs to be
|
||||
portable to other compilers, we provide the GCC_VERSION macro that
|
||||
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
|
||||
wrappers around __attribute__. Also, __extension__ will be #defined
|
||||
to nothing if it doesn't work. See below.
|
||||
|
||||
This header also defines a lot of obsolete macros:
|
||||
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
|
||||
AND, DOTS, NOARGS. Don't use them. */
|
||||
|
||||
#ifndef _ANSIDECL_H
|
||||
#define _ANSIDECL_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Every source file includes this file,
|
||||
so they will all get the switch for lint. */
|
||||
/* LINTLIBRARY */
|
||||
|
||||
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
|
||||
older preprocessors. Thus we can't define something like this:
|
||||
|
||||
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
|
||||
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
|
||||
|
||||
and then test "#if HAVE_GCC_VERSION(2,7)".
|
||||
|
||||
So instead we use the macro below and test it against specific values. */
|
||||
|
||||
/* This macro simplifies testing whether we are using gcc, and if it
|
||||
is of a particular minimum version. (Both major & minor numbers are
|
||||
significant.) This macro will evaluate to 0 if we are not using
|
||||
gcc at all. */
|
||||
#ifndef GCC_VERSION
|
||||
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||
#endif /* GCC_VERSION */
|
||||
|
||||
#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
|
||||
/* All known AIX compilers implement these things (but don't always
|
||||
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||
in SVR4 mode, but does not define __STDC__. */
|
||||
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
|
||||
C++ compilers, does not define __STDC__, though it acts as if this
|
||||
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
|
||||
|
||||
#define ANSI_PROTOTYPES 1
|
||||
#define PTR void *
|
||||
#define PTRCONST void *const
|
||||
#define LONG_DOUBLE long double
|
||||
|
||||
/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
|
||||
a #ifndef. */
|
||||
#ifndef PARAMS
|
||||
#define PARAMS(ARGS) ARGS
|
||||
#endif
|
||||
|
||||
#define VPARAMS(ARGS) ARGS
|
||||
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
|
||||
|
||||
/* variadic function helper macros */
|
||||
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
|
||||
use without inhibiting further decls and without declaring an
|
||||
actual variable. */
|
||||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
|
||||
#define VA_CLOSE(AP) } va_end(AP); }
|
||||
#define VA_FIXEDARG(AP, T, N) struct Qdmy
|
||||
|
||||
#undef const
|
||||
#undef volatile
|
||||
#undef signed
|
||||
|
||||
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
|
||||
it too, but it's not in C89. */
|
||||
#undef inline
|
||||
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
|
||||
/* it's a keyword */
|
||||
#else
|
||||
# if GCC_VERSION >= 2007
|
||||
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
|
||||
# else
|
||||
# define inline /* nothing */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* These are obsolete. Do not use. */
|
||||
#ifndef IN_GCC
|
||||
#define CONST const
|
||||
#define VOLATILE volatile
|
||||
#define SIGNED signed
|
||||
|
||||
#define PROTO(type, name, arglist) type name arglist
|
||||
#define EXFUN(name, proto) name proto
|
||||
#define DEFUN(name, arglist, args) name(args)
|
||||
#define DEFUN_VOID(name) name(void)
|
||||
#define AND ,
|
||||
#define DOTS , ...
|
||||
#define NOARGS void
|
||||
#endif /* ! IN_GCC */
|
||||
|
||||
#else /* Not ANSI C. */
|
||||
|
||||
#undef ANSI_PROTOTYPES
|
||||
#define PTR char *
|
||||
#define PTRCONST PTR
|
||||
#define LONG_DOUBLE double
|
||||
|
||||
#define PARAMS(args) ()
|
||||
#define VPARAMS(args) (va_alist) va_dcl
|
||||
#define VA_START(va_list, var) va_start(va_list)
|
||||
|
||||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
|
||||
#define VA_CLOSE(AP) } va_end(AP); }
|
||||
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
|
||||
|
||||
/* some systems define these in header files for non-ansi mode */
|
||||
#undef const
|
||||
#undef volatile
|
||||
#undef signed
|
||||
#undef inline
|
||||
#define const
|
||||
#define volatile
|
||||
#define signed
|
||||
#define inline
|
||||
|
||||
#ifndef IN_GCC
|
||||
#define CONST
|
||||
#define VOLATILE
|
||||
#define SIGNED
|
||||
|
||||
#define PROTO(type, name, arglist) type name ()
|
||||
#define EXFUN(name, proto) name()
|
||||
#define DEFUN(name, arglist, args) name arglist args;
|
||||
#define DEFUN_VOID(name) name()
|
||||
#define AND ;
|
||||
#define DOTS
|
||||
#define NOARGS
|
||||
#endif /* ! IN_GCC */
|
||||
|
||||
#endif /* ANSI C. */
|
||||
|
||||
/* Define macros for some gcc attributes. This permits us to use the
|
||||
macros freely, and know that they will come into play for the
|
||||
version of gcc in which they are supported. */
|
||||
|
||||
#if (GCC_VERSION < 2007)
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
|
||||
#ifndef ATTRIBUTE_MALLOC
|
||||
# if (GCC_VERSION >= 2096)
|
||||
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||
# else
|
||||
# define ATTRIBUTE_MALLOC
|
||||
# endif /* GNUC >= 2.96 */
|
||||
#endif /* ATTRIBUTE_MALLOC */
|
||||
|
||||
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
|
||||
g++ an attribute on a label must be followed by a semicolon. */
|
||||
#ifndef ATTRIBUTE_UNUSED_LABEL
|
||||
# ifndef __cplusplus
|
||||
# if GCC_VERSION >= 2093
|
||||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
|
||||
# else
|
||||
# define ATTRIBUTE_UNUSED_LABEL
|
||||
# endif
|
||||
# else
|
||||
# if GCC_VERSION >= 4005
|
||||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
|
||||
# else
|
||||
# define ATTRIBUTE_UNUSED_LABEL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend
|
||||
couldn't parse attributes placed after the identifier name, and now
|
||||
the entire compiler is built with C++. */
|
||||
#ifndef ATTRIBUTE_UNUSED
|
||||
#if GCC_VERSION >= 3004
|
||||
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||
#else
|
||||
#define ATTRIBUTE_UNUSED
|
||||
#endif
|
||||
#endif /* ATTRIBUTE_UNUSED */
|
||||
|
||||
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
|
||||
identifier name. */
|
||||
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
|
||||
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
|
||||
#else /* !__cplusplus || GNUC >= 3.4 */
|
||||
# define ARG_UNUSED(NAME) NAME
|
||||
#endif /* !__cplusplus || GNUC >= 3.4 */
|
||||
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
#endif /* ATTRIBUTE_NORETURN */
|
||||
|
||||
/* Attribute `nonnull' was valid as of gcc 3.3. */
|
||||
#ifndef ATTRIBUTE_NONNULL
|
||||
# if (GCC_VERSION >= 3003)
|
||||
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
|
||||
# else
|
||||
# define ATTRIBUTE_NONNULL(m)
|
||||
# endif /* GNUC >= 3.3 */
|
||||
#endif /* ATTRIBUTE_NONNULL */
|
||||
|
||||
/* Attribute `pure' was valid as of gcc 3.0. */
|
||||
#ifndef ATTRIBUTE_PURE
|
||||
# if (GCC_VERSION >= 3000)
|
||||
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||
# else
|
||||
# define ATTRIBUTE_PURE
|
||||
# endif /* GNUC >= 3.0 */
|
||||
#endif /* ATTRIBUTE_PURE */
|
||||
|
||||
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
|
||||
This was the case for the `printf' format attribute by itself
|
||||
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
|
||||
attribute to retain this behavior. */
|
||||
#ifndef ATTRIBUTE_PRINTF
|
||||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
|
||||
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
||||
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
||||
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
|
||||
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
|
||||
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
|
||||
#endif /* ATTRIBUTE_PRINTF */
|
||||
|
||||
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
|
||||
a function pointer. Format attributes were allowed on function
|
||||
pointers as of gcc 3.1. */
|
||||
#ifndef ATTRIBUTE_FPTR_PRINTF
|
||||
# if (GCC_VERSION >= 3001)
|
||||
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
|
||||
# else
|
||||
# define ATTRIBUTE_FPTR_PRINTF(m, n)
|
||||
# endif /* GNUC >= 3.1 */
|
||||
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
|
||||
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
|
||||
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
|
||||
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
|
||||
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
|
||||
#endif /* ATTRIBUTE_FPTR_PRINTF */
|
||||
|
||||
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
|
||||
NULL format specifier was allowed as of gcc 3.3. */
|
||||
#ifndef ATTRIBUTE_NULL_PRINTF
|
||||
# if (GCC_VERSION >= 3003)
|
||||
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||
# else
|
||||
# define ATTRIBUTE_NULL_PRINTF(m, n)
|
||||
# endif /* GNUC >= 3.3 */
|
||||
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
|
||||
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
|
||||
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
|
||||
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
|
||||
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
|
||||
#endif /* ATTRIBUTE_NULL_PRINTF */
|
||||
|
||||
/* Attribute `sentinel' was valid as of gcc 3.5. */
|
||||
#ifndef ATTRIBUTE_SENTINEL
|
||||
# if (GCC_VERSION >= 3005)
|
||||
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
|
||||
# else
|
||||
# define ATTRIBUTE_SENTINEL
|
||||
# endif /* GNUC >= 3.5 */
|
||||
#endif /* ATTRIBUTE_SENTINEL */
|
||||
|
||||
|
||||
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
|
||||
# if (GCC_VERSION >= 3000)
|
||||
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
|
||||
# else
|
||||
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
|
||||
# endif /* GNUC >= 3.0 */
|
||||
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
|
||||
|
||||
/* Useful for structures whose layout must much some binary specification
|
||||
regardless of the alignment and padding qualities of the compiler. */
|
||||
#ifndef ATTRIBUTE_PACKED
|
||||
# define ATTRIBUTE_PACKED __attribute__ ((packed))
|
||||
#endif
|
||||
|
||||
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
|
||||
#ifndef ATTRIBUTE_COLD
|
||||
# if (GCC_VERSION >= 4003)
|
||||
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
|
||||
# else
|
||||
# define ATTRIBUTE_COLD
|
||||
# endif /* GNUC >= 4.3 */
|
||||
#endif /* ATTRIBUTE_COLD */
|
||||
#ifndef ATTRIBUTE_HOT
|
||||
# if (GCC_VERSION >= 4003)
|
||||
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
|
||||
# else
|
||||
# define ATTRIBUTE_HOT
|
||||
# endif /* GNUC >= 4.3 */
|
||||
#endif /* ATTRIBUTE_HOT */
|
||||
|
||||
/* We use __extension__ in some places to suppress -pedantic warnings
|
||||
about GCC extensions. This feature didn't work properly before
|
||||
gcc 2.8. */
|
||||
#if GCC_VERSION < 2008
|
||||
#define __extension__
|
||||
#endif
|
||||
|
||||
/* This is used to declare a const variable which should be visible
|
||||
outside of the current compilation unit. Use it as
|
||||
EXPORTED_CONST int i = 1;
|
||||
This is because the semantics of const are different in C and C++.
|
||||
"extern const" is permitted in C but it looks strange, and gcc
|
||||
warns about it when -Wc++-compat is not used. */
|
||||
#ifdef __cplusplus
|
||||
#define EXPORTED_CONST extern const
|
||||
#else
|
||||
#define EXPORTED_CONST const
|
||||
#endif
|
||||
|
||||
/* Be conservative and only use enum bitfields with C++ or GCC.
|
||||
FIXME: provide a complete autoconf test for buggy enum bitfields. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define ENUM_BITFIELD(TYPE) enum TYPE
|
||||
#elif (GCC_VERSION > 2000)
|
||||
#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
|
||||
#else
|
||||
#define ENUM_BITFIELD(TYPE) unsigned int
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ansidecl.h */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,121 @@
|
|||
USER_H=unwind-arm-common.h
|
||||
HASHTAB_H=hashtab.h
|
||||
OBSTACK_H=obstack.h
|
||||
SPLAY_TREE_H=splay-tree.h
|
||||
FIBHEAP_H=fibheap.h
|
||||
PARTITION_H=partition.h
|
||||
DWARF2_H=dwarf2.def
|
||||
XREGEX_H=xregex.h
|
||||
FNMATCH_H=fnmatch.h
|
||||
LINKER_PLUGIN_API_H=plugin-api.h
|
||||
LTO_SYMTAB_H=lto-symtab.h
|
||||
BCONFIG_H=bconfig.h auto-host.h ansidecl.h
|
||||
CONFIG_H=config.h auto-host.h ansidecl.h
|
||||
TCONFIG_H=tconfig.h auto-host.h ansidecl.h
|
||||
TM_P_H=tm_p.h config/arm/arm-protos.h aarch-common-protos.h tm-preds.h
|
||||
GTM_H=tm.h options.h config/dbxelf.h defaults.h insn-constants.h
|
||||
TM_H=tm.h options.h config/dbxelf.h arm-cores.def
|
||||
VEC_H=vec.h statistics.h ggc.h gtype-desc.h statistics.h
|
||||
HASH_TABLE_H=hashtab.h hash-table.h
|
||||
EXCEPT_H=except.h hashtab.h
|
||||
TARGET_H=tm.h options.h config/dbxelf.h arm-cores.def target.h target.def target-hooks-macros.h insn-modes.h
|
||||
C_TARGET_H=c-family/c-target.h c-family/c-target.def target-hooks-macros.h
|
||||
COMMON_TARGET_H=common/common-target.h common-target.def target-hooks-macros.h
|
||||
MACHMODE_H=machmode.h mode-classes.def insn-modes.h
|
||||
HOOKS_H=hooks.h machmode.h mode-classes.def insn-modes.h
|
||||
HOSTHOOKS_DEF_H=hosthooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
||||
LANGHOOKS_DEF_H=langhooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
||||
TARGET_DEF_H=target-def.h target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h targhooks.h
|
||||
C_TARGET_DEF_H=c-family/c-target-def.h c-family/c-target-hooks-def.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def common-targhooks.h
|
||||
COMMON_TARGET_DEF_H=common/common-target-def.h common/common-target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
||||
RTL_BASE_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def hashtab.h
|
||||
FIXED_VALUE_H=fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||
RTL_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def arm-cores.def genrtl.h
|
||||
RTL_ERROR_H=rtl-error.h coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def line-map.h input.h bversion.h diagnostic.def
|
||||
READ_MD_H=hashtab.h read-md.h
|
||||
PARAMS_H=params.h params.def
|
||||
INTERNAL_FN_H=internal-fn.h internal-fn.def
|
||||
TREE_H=coretypes.h tree.h all-tree.def tree.def c-family/c-common.def arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||
REGSET_H=regset.h bitmap.h hashtab.h statistics.h hard-reg-set.h
|
||||
BASIC_BLOCK_H=basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h
|
||||
GIMPLE_H=gimple.h gimple.def gsstruct.def pointer-set.h vec.h statistics.h ggc.h gtype-desc.h statistics.h ggc.h gtype-desc.h statistics.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def
|
||||
TRANS_MEM_H=trans-mem.h
|
||||
GCOV_IO_H=gcov-io.h gcov-iov.h auto-host.h
|
||||
COVERAGE_H=coverage.h gcov-io.h gcov-iov.h auto-host.h
|
||||
DEMANGLE_H=demangle.h
|
||||
RECOG_H=recog.h
|
||||
ALIAS_H=alias.h
|
||||
EMIT_RTL_H=emit-rtl.h
|
||||
FLAGS_H=flags.h flag-types.h options.h flag-types.h config/arm/arm-opts.h arm-cores.def
|
||||
OPTIONS_H=options.h flag-types.h config/arm/arm-opts.h arm-cores.def
|
||||
FUNCTION_H=function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h
|
||||
EXPR_H=expr.h insn-config.h function.h arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h machmode.h mode-classes.def insn-modes.h emit-rtl.h
|
||||
OPTABS_H=optabs.h insn-codes.h insn-opinit.h
|
||||
REGS_H=regs.h machmode.h mode-classes.def insn-modes.h hard-reg-set.h
|
||||
SCHED_INT_H=sched-int.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
||||
SEL_SCHED_IR_H=sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
||||
SEL_SCHED_DUMP_H=sel-sched-dump.h sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
||||
CFGLOOP_H=cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h
|
||||
IPA_UTILS_H=ipa-utils.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h
|
||||
IPA_REFERENCE_H=ipa-reference.h bitmap.h arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||
CGRAPH_H=cgraph.h vec.h statistics.h ggc.h gtype-desc.h statistics.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h
|
||||
DF_H=df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
||||
VALTRACK_H=valtrack.h bitmap.h hashtab.h hash-table.h
|
||||
RESOURCE_H=resource.h hard-reg-set.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
||||
DDG_H=ddg.h sbitmap.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
||||
GCC_H=gcc.h version.h diagnostic-core.h line-map.h input.h bversion.h diagnostic.def
|
||||
GGC_H=ggc.h gtype-desc.h statistics.h
|
||||
GGC_INTERNAL_H=ggc-internal.h ggc.h gtype-desc.h statistics.h
|
||||
TIMEVAR_H=timevar.h timevar.def
|
||||
INSN_ATTR_H=insn-attr.h insn-attr-common.h insn-addr.h
|
||||
INSN_ADDR_H=insn-addr.h
|
||||
C_COMMON_H=c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def line-map.h input.h bversion.h diagnostic.def
|
||||
C_PRAGMA_H=c-family/c-pragma.h cpplib.h
|
||||
C_TREE_H=c/c-tree.h c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def obstack.h
|
||||
SYSTEM_H=system.h hwint.h filenames.h
|
||||
PREDICT_H=predict.h predict.def
|
||||
CPPLIB_H=cpplib.h
|
||||
INPUT_H=line-map.h input.h
|
||||
OPTS_H=obstack.h
|
||||
DECNUM_H=decimal128Local.h
|
||||
BACKTRACE_H=backtrace.h
|
||||
MKDEPS_H=mkdeps.h
|
||||
SYMTAB_H=obstack.h
|
||||
CPP_ID_DATA_H=cpp-id-data.h
|
||||
CPP_INTERNAL_H=cpp-id-data.h
|
||||
TREE_DUMP_H=tree-dump.h splay-tree.h dumpfile.h
|
||||
TREE_PASS_H=tree-pass.h timevar.h timevar.def dumpfile.h
|
||||
TREE_FLOW_H=tree-flow.h tree-flow-inline.h tree-ssa-operands.h bitmap.h arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-alias.h
|
||||
TREE_SSA_LIVE_H=tree-ssa-live.h partition.h
|
||||
SSAEXPAND_H=ssaexpand.h tree-ssa-live.h partition.h
|
||||
PRETTY_PRINT_H=pretty-print.h obstack.h
|
||||
TREE_PRETTY_PRINT_H=tree-pretty-print.h pretty-print.h obstack.h
|
||||
GIMPLE_PRETTY_PRINT_H=gimple-pretty-print.h tree-pretty-print.h pretty-print.h obstack.h
|
||||
DIAGNOSTIC_CORE_H=diagnostic-core.h line-map.h input.h bversion.h diagnostic.def
|
||||
DIAGNOSTIC_H=diagnostic.h diagnostic-core.h obstack.h
|
||||
DWARF2OUT_H=dwarf2out.h dwarf2.def
|
||||
C_PRETTY_PRINT_H=c-family/c-pretty-print.h pretty-print.h arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||
SCEV_H=tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def
|
||||
OMEGA_H=omega.h params.h params.def
|
||||
TREE_DATA_REF_H=tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def
|
||||
TREE_INLINE_H=tree-inline.h
|
||||
REAL_H=real.h machmode.h mode-classes.def insn-modes.h
|
||||
IRA_INT_H=ira.h ira-int.h cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h alloc-pool.h
|
||||
LRA_INT_H=lra.h bitmap.h insn-addr.h insn-codes.h lra-int.h
|
||||
DBGCNT_H=dbgcnt.h dbgcnt.def
|
||||
LTO_STREAMER_H=lto-streamer.h obstack.h alloc-pool.h
|
||||
DATA_STREAMER_H=data-streamer.h vec.h statistics.h ggc.h gtype-desc.h statistics.h lto-streamer.h obstack.h alloc-pool.h
|
||||
GIMPLE_STREAMER_H=gimple-streamer.h lto-streamer.h line-map.h input.h machmode.h mode-classes.def insn-modes.h
|
||||
TREE_STREAMER_H=tree-streamer.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||
STREAMER_HOOKS_H=streamer-hooks.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||
TREE_VECTORIZER_H=tree-vectorizer.h tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def tm.h options.h config/dbxelf.h arm-cores.def target.h target.def target-hooks-macros.h insn-modes.h
|
||||
IPA_PROP_H=ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h
|
||||
IPA_INLINE_H=ipa-inline.h ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def arm-cores.def real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h
|
||||
GSTAB_H=gstab.h stab.def
|
||||
BITMAP_H=bitmap.h hashtab.h statistics.h
|
||||
GCC_PLUGIN_H=gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h
|
||||
PLUGIN_H=plugin.h gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h
|
||||
PLUGIN_VERSION_H=plugin-version.h configargs.h
|
||||
LIBFUNCS_H=libfuncs.h hashtab.h
|
||||
GTFILES_H=gt-coverage.h gt-caller-save.h gt-symtab.h gt-alias.h gt-bitmap.h gt-cselib.h gt-cgraph.h gt-ipa-prop.h gt-ipa-cp.h gt-dbxout.h gt-dwarf2asm.h gt-dwarf2cfi.h gt-dwarf2out.h gt-tree-vect-generic.h gt-dojump.h gt-emit-rtl.h gt-explow.h gt-expr.h gt-function.h gt-except.h gt-gcse.h gt-godump.h gt-lists.h gt-optabs.h gt-profile.h gt-mcf.h gt-reg-stack.h gt-cfgrtl.h gt-sdbout.h gt-stor-layout.h gt-stringpool.h gt-tree.h gt-varasm.h gt-gimple.h gt-tree-mudflap.h gt-tree-ssanames.h gt-tree-eh.h gt-tree-ssa-address.h gt-tree-cfg.h gt-tree-dfa.h gt-tree-iterator.h gt-gimplify.h gt-tree-scalar-evolution.h gt-tree-profile.h gt-tree-nested.h gt-tree-parloops.h gt-omp-low.h gt-targhooks.h gt-arm.h gt-passes.h gt-cgraphunit.h gt-cgraphclones.h gt-tree-ssa-propagate.h gt-tree-phinodes.h gt-lto-symtab.h gt-trans-mem.h gt-asan.h gt-tsan.h gt-ada-decl.h gt-ada-trans.h gt-ada-utils.h gt-ada-misc.h gt-c-c-lang.h gt-c-c-decl.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-c-c-objc-common.h gt-c-c-parser.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-cp-cp-lang.h gt-cp-except.h gt-fortran-f95-lang.h gt-fortran-trans-decl.h gt-fortran-trans-intrinsic.h gt-fortran-trans-io.h gt-fortran-trans-stmt.h gt-fortran-trans-types.h gt-go-go-lang.h gt-java-builtins.h gt-java-class.h gt-java-constants.h gt-java-decl.h gt-java-expr.h gt-java-jcf-parse.h gt-java-lang.h gt-java-mangle.h gt-java-resource.h gt-lto-lto-lang.h gt-lto-lto.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-c-parser.h gt-c-c-decl.h gt-c-c-objc-common.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-family-c-cppbuiltin.h
|
||||
GTFILES_LANG_H=gtype-ada.h gtype-c.h gtype-cp.h gtype-fortran.h gtype-go.h gtype-java.h gtype-lto.h gtype-objc.h gtype-objcp.h
|
||||
|
|
@ -0,0 +1,974 @@
|
|||
/* Define control flow data structures for the CFG.
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_BASIC_BLOCK_H
|
||||
#define GCC_BASIC_BLOCK_H
|
||||
|
||||
#include "predict.h"
|
||||
#include "vec.h"
|
||||
#include "function.h"
|
||||
|
||||
/* Type we use to hold basic block counters. Should be at least
|
||||
64bit. Although a counter cannot be negative, we use a signed
|
||||
type, because erroneous negative counts can be generated when the
|
||||
flow graph is manipulated by various optimizations. A signed type
|
||||
makes those easy to detect. */
|
||||
typedef HOST_WIDEST_INT gcov_type;
|
||||
typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
|
||||
|
||||
/* Control flow edge information. */
|
||||
struct GTY((user)) edge_def {
|
||||
/* The two blocks at the ends of the edge. */
|
||||
basic_block src;
|
||||
basic_block dest;
|
||||
|
||||
/* Instructions queued on the edge. */
|
||||
union edge_def_insns {
|
||||
gimple_seq g;
|
||||
rtx r;
|
||||
} insns;
|
||||
|
||||
/* Auxiliary info specific to a pass. */
|
||||
PTR aux;
|
||||
|
||||
/* Location of any goto implicit in the edge. */
|
||||
location_t goto_locus;
|
||||
|
||||
/* The index number corresponding to this edge in the edge vector
|
||||
dest->preds. */
|
||||
unsigned int dest_idx;
|
||||
|
||||
int flags; /* see cfg-flags.def */
|
||||
int probability; /* biased by REG_BR_PROB_BASE */
|
||||
gcov_type count; /* Expected number of executions calculated
|
||||
in profile.c */
|
||||
};
|
||||
|
||||
|
||||
/* Garbage collection and PCH support for edge_def. */
|
||||
extern void gt_ggc_mx (edge_def *e);
|
||||
extern void gt_pch_nx (edge_def *e);
|
||||
extern void gt_pch_nx (edge_def *e, gt_pointer_operator, void *);
|
||||
|
||||
/* Masks for edge.flags. */
|
||||
#define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX ,
|
||||
enum cfg_edge_flags {
|
||||
#include "cfg-flags.def"
|
||||
LAST_CFG_EDGE_FLAG /* this is only used for EDGE_ALL_FLAGS */
|
||||
};
|
||||
#undef DEF_EDGE_FLAG
|
||||
|
||||
/* Bit mask for all edge flags. */
|
||||
#define EDGE_ALL_FLAGS ((LAST_CFG_EDGE_FLAG - 1) * 2 - 1)
|
||||
|
||||
/* The following four flags all indicate something special about an edge.
|
||||
Test the edge flags on EDGE_COMPLEX to detect all forms of "strange"
|
||||
control flow transfers. */
|
||||
#define EDGE_COMPLEX \
|
||||
(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE)
|
||||
|
||||
/* Counter summary from the last set of coverage counts read by
|
||||
profile.c. */
|
||||
extern const struct gcov_ctr_summary *profile_info;
|
||||
|
||||
/* Working set size statistics for a given percentage of the entire
|
||||
profile (sum_all from the counter summary). */
|
||||
typedef struct gcov_working_set_info
|
||||
{
|
||||
/* Number of hot counters included in this working set. */
|
||||
unsigned num_counters;
|
||||
/* Smallest counter included in this working set. */
|
||||
gcov_type min_counter;
|
||||
} gcov_working_set_t;
|
||||
|
||||
/* Structure to gather statistic about profile consistency, per pass.
|
||||
An array of this structure, indexed by pass static number, is allocated
|
||||
in passes.c. The structure is defined here so that different CFG modes
|
||||
can do their book-keeping via CFG hooks.
|
||||
|
||||
For every field[2], field[0] is the count before the pass runs, and
|
||||
field[1] is the post-pass count. This allows us to monitor the effect
|
||||
of each individual pass on the profile consistency.
|
||||
|
||||
This structure is not supposed to be used by anything other than passes.c
|
||||
and one CFG hook per CFG mode. */
|
||||
struct profile_record
|
||||
{
|
||||
/* The number of basic blocks where sum(freq) of the block's predecessors
|
||||
doesn't match reasonably well with the incoming frequency. */
|
||||
int num_mismatched_freq_in[2];
|
||||
/* Likewise for a basic block's successors. */
|
||||
int num_mismatched_freq_out[2];
|
||||
/* The number of basic blocks where sum(count) of the block's predecessors
|
||||
doesn't match reasonably well with the incoming frequency. */
|
||||
int num_mismatched_count_in[2];
|
||||
/* Likewise for a basic block's successors. */
|
||||
int num_mismatched_count_out[2];
|
||||
/* A weighted cost of the run-time of the function body. */
|
||||
gcov_type time[2];
|
||||
/* A weighted cost of the size of the function body. */
|
||||
int size[2];
|
||||
/* True iff this pass actually was run. */
|
||||
bool run;
|
||||
};
|
||||
|
||||
/* Declared in cfgloop.h. */
|
||||
struct loop;
|
||||
|
||||
struct GTY(()) rtl_bb_info {
|
||||
/* The first insn of the block is embedded into bb->il.x. */
|
||||
/* The last insn of the block. */
|
||||
rtx end_;
|
||||
|
||||
/* In CFGlayout mode points to insn notes/jumptables to be placed just before
|
||||
and after the block. */
|
||||
rtx header_;
|
||||
rtx footer_;
|
||||
};
|
||||
|
||||
struct GTY(()) gimple_bb_info {
|
||||
/* Sequence of statements in this block. */
|
||||
gimple_seq seq;
|
||||
|
||||
/* PHI nodes for this block. */
|
||||
gimple_seq phi_nodes;
|
||||
};
|
||||
|
||||
/* A basic block is a sequence of instructions with only one entry and
|
||||
only one exit. If any one of the instructions are executed, they
|
||||
will all be executed, and in sequence from first to last.
|
||||
|
||||
There may be COND_EXEC instructions in the basic block. The
|
||||
COND_EXEC *instructions* will be executed -- but if the condition
|
||||
is false the conditionally executed *expressions* will of course
|
||||
not be executed. We don't consider the conditionally executed
|
||||
expression (which might have side-effects) to be in a separate
|
||||
basic block because the program counter will always be at the same
|
||||
location after the COND_EXEC instruction, regardless of whether the
|
||||
condition is true or not.
|
||||
|
||||
Basic blocks need not start with a label nor end with a jump insn.
|
||||
For example, a previous basic block may just "conditionally fall"
|
||||
into the succeeding basic block, and the last basic block need not
|
||||
end with a jump insn. Block 0 is a descendant of the entry block.
|
||||
|
||||
A basic block beginning with two labels cannot have notes between
|
||||
the labels.
|
||||
|
||||
Data for jump tables are stored in jump_insns that occur in no
|
||||
basic block even though these insns can follow or precede insns in
|
||||
basic blocks. */
|
||||
|
||||
/* Basic block information indexed by block number. */
|
||||
struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_def {
|
||||
/* The edges into and out of the block. */
|
||||
vec<edge, va_gc> *preds;
|
||||
vec<edge, va_gc> *succs;
|
||||
|
||||
/* Auxiliary info specific to a pass. */
|
||||
PTR GTY ((skip (""))) aux;
|
||||
|
||||
/* Innermost loop containing the block. */
|
||||
struct loop *loop_father;
|
||||
|
||||
/* The dominance and postdominance information node. */
|
||||
struct et_node * GTY ((skip (""))) dom[2];
|
||||
|
||||
/* Previous and next blocks in the chain. */
|
||||
basic_block prev_bb;
|
||||
basic_block next_bb;
|
||||
|
||||
union basic_block_il_dependent {
|
||||
struct gimple_bb_info GTY ((tag ("0"))) gimple;
|
||||
struct {
|
||||
rtx head_;
|
||||
struct rtl_bb_info * rtl;
|
||||
} GTY ((tag ("1"))) x;
|
||||
} GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
|
||||
|
||||
/* Various flags. See cfg-flags.def. */
|
||||
int flags;
|
||||
|
||||
/* The index of this block. */
|
||||
int index;
|
||||
|
||||
/* Expected number of executions: calculated in profile.c. */
|
||||
gcov_type count;
|
||||
|
||||
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
|
||||
int frequency;
|
||||
|
||||
/* The discriminator for this block. The discriminator distinguishes
|
||||
among several basic blocks that share a common locus, allowing for
|
||||
more accurate sample-based profiling. */
|
||||
int discriminator;
|
||||
};
|
||||
|
||||
/* This ensures that struct gimple_bb_info is smaller than
|
||||
struct rtl_bb_info, so that inlining the former into basic_block_def
|
||||
is the better choice. */
|
||||
typedef int __assert_gimple_bb_smaller_rtl_bb
|
||||
[(int)sizeof(struct rtl_bb_info)
|
||||
- (int)sizeof (struct gimple_bb_info)];
|
||||
|
||||
|
||||
#define BB_FREQ_MAX 10000
|
||||
|
||||
/* Masks for basic_block.flags. */
|
||||
#define DEF_BASIC_BLOCK_FLAG(NAME,IDX) BB_##NAME = 1 << IDX ,
|
||||
enum cfg_bb_flags
|
||||
{
|
||||
#include "cfg-flags.def"
|
||||
LAST_CFG_BB_FLAG /* this is only used for BB_ALL_FLAGS */
|
||||
};
|
||||
#undef DEF_BASIC_BLOCK_FLAG
|
||||
|
||||
/* Bit mask for all basic block flags. */
|
||||
#define BB_ALL_FLAGS ((LAST_CFG_BB_FLAG - 1) * 2 - 1)
|
||||
|
||||
/* Bit mask for all basic block flags that must be preserved. These are
|
||||
the bit masks that are *not* cleared by clear_bb_flags. */
|
||||
#define BB_FLAGS_TO_PRESERVE \
|
||||
(BB_DISABLE_SCHEDULE | BB_RTL | BB_NON_LOCAL_GOTO_TARGET \
|
||||
| BB_HOT_PARTITION | BB_COLD_PARTITION)
|
||||
|
||||
/* Dummy bitmask for convenience in the hot/cold partitioning code. */
|
||||
#define BB_UNPARTITIONED 0
|
||||
|
||||
/* Partitions, to be used when partitioning hot and cold basic blocks into
|
||||
separate sections. */
|
||||
#define BB_PARTITION(bb) ((bb)->flags & (BB_HOT_PARTITION|BB_COLD_PARTITION))
|
||||
#define BB_SET_PARTITION(bb, part) do { \
|
||||
basic_block bb_ = (bb); \
|
||||
bb_->flags = ((bb_->flags & ~(BB_HOT_PARTITION|BB_COLD_PARTITION)) \
|
||||
| (part)); \
|
||||
} while (0)
|
||||
|
||||
#define BB_COPY_PARTITION(dstbb, srcbb) \
|
||||
BB_SET_PARTITION (dstbb, BB_PARTITION (srcbb))
|
||||
|
||||
/* State of dominance information. */
|
||||
|
||||
enum dom_state
|
||||
{
|
||||
DOM_NONE, /* Not computed at all. */
|
||||
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
|
||||
DOM_OK /* Everything is ok. */
|
||||
};
|
||||
|
||||
/* What sort of profiling information we have. */
|
||||
enum profile_status_d
|
||||
{
|
||||
PROFILE_ABSENT,
|
||||
PROFILE_GUESSED,
|
||||
PROFILE_READ,
|
||||
PROFILE_LAST /* Last value, used by profile streaming. */
|
||||
};
|
||||
|
||||
/* A structure to group all the per-function control flow graph data.
|
||||
The x_* prefixing is necessary because otherwise references to the
|
||||
fields of this struct are interpreted as the defines for backward
|
||||
source compatibility following the definition of this struct. */
|
||||
struct GTY(()) control_flow_graph {
|
||||
/* Block pointers for the exit and entry of a function.
|
||||
These are always the head and tail of the basic block list. */
|
||||
basic_block x_entry_block_ptr;
|
||||
basic_block x_exit_block_ptr;
|
||||
|
||||
/* Index by basic block number, get basic block struct info. */
|
||||
vec<basic_block, va_gc> *x_basic_block_info;
|
||||
|
||||
/* Number of basic blocks in this flow graph. */
|
||||
int x_n_basic_blocks;
|
||||
|
||||
/* Number of edges in this flow graph. */
|
||||
int x_n_edges;
|
||||
|
||||
/* The first free basic block number. */
|
||||
int x_last_basic_block;
|
||||
|
||||
/* UIDs for LABEL_DECLs. */
|
||||
int last_label_uid;
|
||||
|
||||
/* Mapping of labels to their associated blocks. At present
|
||||
only used for the gimple CFG. */
|
||||
vec<basic_block, va_gc> *x_label_to_block_map;
|
||||
|
||||
enum profile_status_d x_profile_status;
|
||||
|
||||
/* Whether the dominators and the postdominators are available. */
|
||||
enum dom_state x_dom_computed[2];
|
||||
|
||||
/* Number of basic blocks in the dominance tree. */
|
||||
unsigned x_n_bbs_in_dom_tree[2];
|
||||
|
||||
/* Maximal number of entities in the single jumptable. Used to estimate
|
||||
final flowgraph size. */
|
||||
int max_jumptable_ents;
|
||||
};
|
||||
|
||||
/* Defines for accessing the fields of the CFG structure for function FN. */
|
||||
#define ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_entry_block_ptr)
|
||||
#define EXIT_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_exit_block_ptr)
|
||||
#define basic_block_info_for_function(FN) ((FN)->cfg->x_basic_block_info)
|
||||
#define n_basic_blocks_for_function(FN) ((FN)->cfg->x_n_basic_blocks)
|
||||
#define n_edges_for_function(FN) ((FN)->cfg->x_n_edges)
|
||||
#define last_basic_block_for_function(FN) ((FN)->cfg->x_last_basic_block)
|
||||
#define label_to_block_map_for_function(FN) ((FN)->cfg->x_label_to_block_map)
|
||||
#define profile_status_for_function(FN) ((FN)->cfg->x_profile_status)
|
||||
|
||||
#define BASIC_BLOCK_FOR_FUNCTION(FN,N) \
|
||||
((*basic_block_info_for_function(FN))[(N)])
|
||||
#define SET_BASIC_BLOCK_FOR_FUNCTION(FN,N,BB) \
|
||||
((*basic_block_info_for_function(FN))[(N)] = (BB))
|
||||
|
||||
/* Defines for textual backward source compatibility. */
|
||||
#define ENTRY_BLOCK_PTR (cfun->cfg->x_entry_block_ptr)
|
||||
#define EXIT_BLOCK_PTR (cfun->cfg->x_exit_block_ptr)
|
||||
#define basic_block_info (cfun->cfg->x_basic_block_info)
|
||||
#define n_basic_blocks (cfun->cfg->x_n_basic_blocks)
|
||||
#define n_edges (cfun->cfg->x_n_edges)
|
||||
#define last_basic_block (cfun->cfg->x_last_basic_block)
|
||||
#define label_to_block_map (cfun->cfg->x_label_to_block_map)
|
||||
#define profile_status (cfun->cfg->x_profile_status)
|
||||
|
||||
#define BASIC_BLOCK(N) ((*basic_block_info)[(N)])
|
||||
#define SET_BASIC_BLOCK(N,BB) ((*basic_block_info)[(N)] = (BB))
|
||||
|
||||
/* For iterating over basic blocks. */
|
||||
#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
|
||||
for (BB = FROM; BB != TO; BB = BB->DIR)
|
||||
|
||||
#define FOR_EACH_BB_FN(BB, FN) \
|
||||
FOR_BB_BETWEEN (BB, (FN)->cfg->x_entry_block_ptr->next_bb, (FN)->cfg->x_exit_block_ptr, next_bb)
|
||||
|
||||
#define FOR_EACH_BB(BB) FOR_EACH_BB_FN (BB, cfun)
|
||||
|
||||
#define FOR_EACH_BB_REVERSE_FN(BB, FN) \
|
||||
FOR_BB_BETWEEN (BB, (FN)->cfg->x_exit_block_ptr->prev_bb, (FN)->cfg->x_entry_block_ptr, prev_bb)
|
||||
|
||||
#define FOR_EACH_BB_REVERSE(BB) FOR_EACH_BB_REVERSE_FN(BB, cfun)
|
||||
|
||||
/* For iterating over insns in basic block. */
|
||||
#define FOR_BB_INSNS(BB, INSN) \
|
||||
for ((INSN) = BB_HEAD (BB); \
|
||||
(INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
|
||||
(INSN) = NEXT_INSN (INSN))
|
||||
|
||||
/* For iterating over insns in basic block when we might remove the
|
||||
current insn. */
|
||||
#define FOR_BB_INSNS_SAFE(BB, INSN, CURR) \
|
||||
for ((INSN) = BB_HEAD (BB), (CURR) = (INSN) ? NEXT_INSN ((INSN)): NULL; \
|
||||
(INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
|
||||
(INSN) = (CURR), (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL)
|
||||
|
||||
#define FOR_BB_INSNS_REVERSE(BB, INSN) \
|
||||
for ((INSN) = BB_END (BB); \
|
||||
(INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
|
||||
(INSN) = PREV_INSN (INSN))
|
||||
|
||||
#define FOR_BB_INSNS_REVERSE_SAFE(BB, INSN, CURR) \
|
||||
for ((INSN) = BB_END (BB),(CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL; \
|
||||
(INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
|
||||
(INSN) = (CURR), (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL)
|
||||
|
||||
/* Cycles through _all_ basic blocks, even the fake ones (entry and
|
||||
exit block). */
|
||||
|
||||
#define FOR_ALL_BB(BB) \
|
||||
for (BB = ENTRY_BLOCK_PTR; BB; BB = BB->next_bb)
|
||||
|
||||
#define FOR_ALL_BB_FN(BB, FN) \
|
||||
for (BB = ENTRY_BLOCK_PTR_FOR_FUNCTION (FN); BB; BB = BB->next_bb)
|
||||
|
||||
|
||||
/* Stuff for recording basic block info. */
|
||||
|
||||
#define BB_HEAD(B) (B)->il.x.head_
|
||||
#define BB_END(B) (B)->il.x.rtl->end_
|
||||
#define BB_HEADER(B) (B)->il.x.rtl->header_
|
||||
#define BB_FOOTER(B) (B)->il.x.rtl->footer_
|
||||
|
||||
/* Special block numbers [markers] for entry and exit.
|
||||
Neither of them is supposed to hold actual statements. */
|
||||
#define ENTRY_BLOCK (0)
|
||||
#define EXIT_BLOCK (1)
|
||||
|
||||
/* The two blocks that are always in the cfg. */
|
||||
#define NUM_FIXED_BLOCKS (2)
|
||||
|
||||
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
|
||||
|
||||
extern void compute_bb_for_insn (void);
|
||||
extern unsigned int free_bb_for_insn (void);
|
||||
extern void update_bb_for_insn (basic_block);
|
||||
|
||||
extern void insert_insn_on_edge (rtx, edge);
|
||||
basic_block split_edge_and_insert (edge, rtx);
|
||||
|
||||
extern void commit_one_edge_insertion (edge e);
|
||||
extern void commit_edge_insertions (void);
|
||||
|
||||
extern edge unchecked_make_edge (basic_block, basic_block, int);
|
||||
extern edge cached_make_edge (sbitmap, basic_block, basic_block, int);
|
||||
extern edge make_edge (basic_block, basic_block, int);
|
||||
extern edge make_single_succ_edge (basic_block, basic_block, int);
|
||||
extern void remove_edge_raw (edge);
|
||||
extern void redirect_edge_succ (edge, basic_block);
|
||||
extern edge redirect_edge_succ_nodup (edge, basic_block);
|
||||
extern void redirect_edge_pred (edge, basic_block);
|
||||
extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
|
||||
extern void clear_bb_flags (void);
|
||||
extern void dump_bb_info (FILE *, basic_block, int, int, bool, bool);
|
||||
extern void dump_edge_info (FILE *, edge, int, int);
|
||||
extern void brief_dump_cfg (FILE *, int);
|
||||
extern void clear_edges (void);
|
||||
extern void scale_bbs_frequencies_int (basic_block *, int, int, int);
|
||||
extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type,
|
||||
gcov_type);
|
||||
|
||||
/* Structure to group all of the information to process IF-THEN and
|
||||
IF-THEN-ELSE blocks for the conditional execution support. This
|
||||
needs to be in a public file in case the IFCVT macros call
|
||||
functions passing the ce_if_block data structure. */
|
||||
|
||||
typedef struct ce_if_block
|
||||
{
|
||||
basic_block test_bb; /* First test block. */
|
||||
basic_block then_bb; /* THEN block. */
|
||||
basic_block else_bb; /* ELSE block or NULL. */
|
||||
basic_block join_bb; /* Join THEN/ELSE blocks. */
|
||||
basic_block last_test_bb; /* Last bb to hold && or || tests. */
|
||||
int num_multiple_test_blocks; /* # of && and || basic blocks. */
|
||||
int num_and_and_blocks; /* # of && blocks. */
|
||||
int num_or_or_blocks; /* # of || blocks. */
|
||||
int num_multiple_test_insns; /* # of insns in && and || blocks. */
|
||||
int and_and_p; /* Complex test is &&. */
|
||||
int num_then_insns; /* # of insns in THEN block. */
|
||||
int num_else_insns; /* # of insns in ELSE block. */
|
||||
int pass; /* Pass number. */
|
||||
} ce_if_block_t;
|
||||
|
||||
/* This structure maintains an edge list vector. */
|
||||
/* FIXME: Make this a vec<edge>. */
|
||||
struct edge_list
|
||||
{
|
||||
int num_edges;
|
||||
edge *index_to_edge;
|
||||
};
|
||||
|
||||
/* The base value for branch probability notes and edge probabilities. */
|
||||
#define REG_BR_PROB_BASE 10000
|
||||
|
||||
/* This is the value which indicates no edge is present. */
|
||||
#define EDGE_INDEX_NO_EDGE -1
|
||||
|
||||
/* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE
|
||||
if there is no edge between the 2 basic blocks. */
|
||||
#define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ)))
|
||||
|
||||
/* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic
|
||||
block which is either the pred or succ end of the indexed edge. */
|
||||
#define INDEX_EDGE_PRED_BB(el, index) ((el)->index_to_edge[(index)]->src)
|
||||
#define INDEX_EDGE_SUCC_BB(el, index) ((el)->index_to_edge[(index)]->dest)
|
||||
|
||||
/* INDEX_EDGE returns a pointer to the edge. */
|
||||
#define INDEX_EDGE(el, index) ((el)->index_to_edge[(index)])
|
||||
|
||||
/* Number of edges in the compressed edge list. */
|
||||
#define NUM_EDGES(el) ((el)->num_edges)
|
||||
|
||||
/* BB is assumed to contain conditional jump. Return the fallthru edge. */
|
||||
#define FALLTHRU_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
|
||||
? EDGE_SUCC ((bb), 0) : EDGE_SUCC ((bb), 1))
|
||||
|
||||
/* BB is assumed to contain conditional jump. Return the branch edge. */
|
||||
#define BRANCH_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
|
||||
? EDGE_SUCC ((bb), 1) : EDGE_SUCC ((bb), 0))
|
||||
|
||||
#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
|
||||
/* Return expected execution frequency of the edge E. */
|
||||
#define EDGE_FREQUENCY(e) RDIV ((e)->src->frequency * (e)->probability, \
|
||||
REG_BR_PROB_BASE)
|
||||
|
||||
/* Return nonzero if edge is critical. */
|
||||
#define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \
|
||||
&& EDGE_COUNT ((e)->dest->preds) >= 2)
|
||||
|
||||
#define EDGE_COUNT(ev) vec_safe_length (ev)
|
||||
#define EDGE_I(ev,i) (*ev)[(i)]
|
||||
#define EDGE_PRED(bb,i) (*(bb)->preds)[(i)]
|
||||
#define EDGE_SUCC(bb,i) (*(bb)->succs)[(i)]
|
||||
|
||||
/* Returns true if BB has precisely one successor. */
|
||||
|
||||
static inline bool
|
||||
single_succ_p (const_basic_block bb)
|
||||
{
|
||||
return EDGE_COUNT (bb->succs) == 1;
|
||||
}
|
||||
|
||||
/* Returns true if BB has precisely one predecessor. */
|
||||
|
||||
static inline bool
|
||||
single_pred_p (const_basic_block bb)
|
||||
{
|
||||
return EDGE_COUNT (bb->preds) == 1;
|
||||
}
|
||||
|
||||
/* Returns the single successor edge of basic block BB. Aborts if
|
||||
BB does not have exactly one successor. */
|
||||
|
||||
static inline edge
|
||||
single_succ_edge (const_basic_block bb)
|
||||
{
|
||||
gcc_checking_assert (single_succ_p (bb));
|
||||
return EDGE_SUCC (bb, 0);
|
||||
}
|
||||
|
||||
/* Returns the single predecessor edge of basic block BB. Aborts
|
||||
if BB does not have exactly one predecessor. */
|
||||
|
||||
static inline edge
|
||||
single_pred_edge (const_basic_block bb)
|
||||
{
|
||||
gcc_checking_assert (single_pred_p (bb));
|
||||
return EDGE_PRED (bb, 0);
|
||||
}
|
||||
|
||||
/* Returns the single successor block of basic block BB. Aborts
|
||||
if BB does not have exactly one successor. */
|
||||
|
||||
static inline basic_block
|
||||
single_succ (const_basic_block bb)
|
||||
{
|
||||
return single_succ_edge (bb)->dest;
|
||||
}
|
||||
|
||||
/* Returns the single predecessor block of basic block BB. Aborts
|
||||
if BB does not have exactly one predecessor.*/
|
||||
|
||||
static inline basic_block
|
||||
single_pred (const_basic_block bb)
|
||||
{
|
||||
return single_pred_edge (bb)->src;
|
||||
}
|
||||
|
||||
/* Iterator object for edges. */
|
||||
|
||||
typedef struct {
|
||||
unsigned index;
|
||||
vec<edge, va_gc> **container;
|
||||
} edge_iterator;
|
||||
|
||||
static inline vec<edge, va_gc> *
|
||||
ei_container (edge_iterator i)
|
||||
{
|
||||
gcc_checking_assert (i.container);
|
||||
return *i.container;
|
||||
}
|
||||
|
||||
#define ei_start(iter) ei_start_1 (&(iter))
|
||||
#define ei_last(iter) ei_last_1 (&(iter))
|
||||
|
||||
/* Return an iterator pointing to the start of an edge vector. */
|
||||
static inline edge_iterator
|
||||
ei_start_1 (vec<edge, va_gc> **ev)
|
||||
{
|
||||
edge_iterator i;
|
||||
|
||||
i.index = 0;
|
||||
i.container = ev;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Return an iterator pointing to the last element of an edge
|
||||
vector. */
|
||||
static inline edge_iterator
|
||||
ei_last_1 (vec<edge, va_gc> **ev)
|
||||
{
|
||||
edge_iterator i;
|
||||
|
||||
i.index = EDGE_COUNT (*ev) - 1;
|
||||
i.container = ev;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Is the iterator `i' at the end of the sequence? */
|
||||
static inline bool
|
||||
ei_end_p (edge_iterator i)
|
||||
{
|
||||
return (i.index == EDGE_COUNT (ei_container (i)));
|
||||
}
|
||||
|
||||
/* Is the iterator `i' at one position before the end of the
|
||||
sequence? */
|
||||
static inline bool
|
||||
ei_one_before_end_p (edge_iterator i)
|
||||
{
|
||||
return (i.index + 1 == EDGE_COUNT (ei_container (i)));
|
||||
}
|
||||
|
||||
/* Advance the iterator to the next element. */
|
||||
static inline void
|
||||
ei_next (edge_iterator *i)
|
||||
{
|
||||
gcc_checking_assert (i->index < EDGE_COUNT (ei_container (*i)));
|
||||
i->index++;
|
||||
}
|
||||
|
||||
/* Move the iterator to the previous element. */
|
||||
static inline void
|
||||
ei_prev (edge_iterator *i)
|
||||
{
|
||||
gcc_checking_assert (i->index > 0);
|
||||
i->index--;
|
||||
}
|
||||
|
||||
/* Return the edge pointed to by the iterator `i'. */
|
||||
static inline edge
|
||||
ei_edge (edge_iterator i)
|
||||
{
|
||||
return EDGE_I (ei_container (i), i.index);
|
||||
}
|
||||
|
||||
/* Return an edge pointed to by the iterator. Do it safely so that
|
||||
NULL is returned when the iterator is pointing at the end of the
|
||||
sequence. */
|
||||
static inline edge
|
||||
ei_safe_edge (edge_iterator i)
|
||||
{
|
||||
return !ei_end_p (i) ? ei_edge (i) : NULL;
|
||||
}
|
||||
|
||||
/* Return 1 if we should continue to iterate. Return 0 otherwise.
|
||||
*Edge P is set to the next edge if we are to continue to iterate
|
||||
and NULL otherwise. */
|
||||
|
||||
static inline bool
|
||||
ei_cond (edge_iterator ei, edge *p)
|
||||
{
|
||||
if (!ei_end_p (ei))
|
||||
{
|
||||
*p = ei_edge (ei);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This macro serves as a convenient way to iterate each edge in a
|
||||
vector of predecessor or successor edges. It must not be used when
|
||||
an element might be removed during the traversal, otherwise
|
||||
elements will be missed. Instead, use a for-loop like that shown
|
||||
in the following pseudo-code:
|
||||
|
||||
FOR (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
|
||||
{
|
||||
IF (e != taken_edge)
|
||||
remove_edge (e);
|
||||
ELSE
|
||||
ei_next (&ei);
|
||||
}
|
||||
*/
|
||||
|
||||
#define FOR_EACH_EDGE(EDGE,ITER,EDGE_VEC) \
|
||||
for ((ITER) = ei_start ((EDGE_VEC)); \
|
||||
ei_cond ((ITER), &(EDGE)); \
|
||||
ei_next (&(ITER)))
|
||||
|
||||
#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
|
||||
except for edge forwarding */
|
||||
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
|
||||
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
|
||||
to care REG_DEAD notes. */
|
||||
#define CLEANUP_THREADING 8 /* Do jump threading. */
|
||||
#define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead
|
||||
insns. */
|
||||
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
|
||||
#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
|
||||
|
||||
/* In cfganal.c */
|
||||
extern void bitmap_intersection_of_succs (sbitmap, sbitmap *, basic_block);
|
||||
extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block);
|
||||
extern void bitmap_union_of_succs (sbitmap, sbitmap *, basic_block);
|
||||
extern void bitmap_union_of_preds (sbitmap, sbitmap *, basic_block);
|
||||
|
||||
/* In lcm.c */
|
||||
extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *,
|
||||
sbitmap *, sbitmap *, sbitmap **,
|
||||
sbitmap **);
|
||||
extern struct edge_list *pre_edge_rev_lcm (int, sbitmap *,
|
||||
sbitmap *, sbitmap *,
|
||||
sbitmap *, sbitmap **,
|
||||
sbitmap **);
|
||||
extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
|
||||
|
||||
/* In predict.c */
|
||||
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
|
||||
extern bool maybe_hot_edge_p (edge);
|
||||
extern bool probably_never_executed_bb_p (struct function *, const_basic_block);
|
||||
extern bool optimize_bb_for_size_p (const_basic_block);
|
||||
extern bool optimize_bb_for_speed_p (const_basic_block);
|
||||
extern bool optimize_edge_for_size_p (edge);
|
||||
extern bool optimize_edge_for_speed_p (edge);
|
||||
extern bool optimize_loop_for_size_p (struct loop *);
|
||||
extern bool optimize_loop_for_speed_p (struct loop *);
|
||||
extern bool optimize_loop_nest_for_size_p (struct loop *);
|
||||
extern bool optimize_loop_nest_for_speed_p (struct loop *);
|
||||
extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor);
|
||||
extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor);
|
||||
extern void gimple_predict_edge (edge, enum br_predictor, int);
|
||||
extern void rtl_predict_edge (edge, enum br_predictor, int);
|
||||
extern void predict_edge_def (edge, enum br_predictor, enum prediction);
|
||||
extern void guess_outgoing_edge_probabilities (basic_block);
|
||||
extern void remove_predictions_associated_with_edge (edge);
|
||||
extern bool edge_probability_reliable_p (const_edge);
|
||||
extern bool br_prob_note_reliable_p (const_rtx);
|
||||
extern bool predictable_edge_p (edge);
|
||||
|
||||
/* In cfg.c */
|
||||
extern void init_flow (struct function *);
|
||||
extern void debug_bb (basic_block);
|
||||
extern basic_block debug_bb_n (int);
|
||||
extern void dump_flow_info (FILE *, int);
|
||||
extern void expunge_block (basic_block);
|
||||
extern void link_block (basic_block, basic_block);
|
||||
extern void unlink_block (basic_block);
|
||||
extern void compact_blocks (void);
|
||||
extern basic_block alloc_block (void);
|
||||
extern void alloc_aux_for_blocks (int);
|
||||
extern void clear_aux_for_blocks (void);
|
||||
extern void free_aux_for_blocks (void);
|
||||
extern void alloc_aux_for_edge (edge, int);
|
||||
extern void alloc_aux_for_edges (int);
|
||||
extern void clear_aux_for_edges (void);
|
||||
extern void free_aux_for_edges (void);
|
||||
|
||||
/* In cfganal.c */
|
||||
extern void find_unreachable_blocks (void);
|
||||
extern bool mark_dfs_back_edges (void);
|
||||
struct edge_list * create_edge_list (void);
|
||||
void free_edge_list (struct edge_list *);
|
||||
void print_edge_list (FILE *, struct edge_list *);
|
||||
void verify_edge_list (FILE *, struct edge_list *);
|
||||
int find_edge_index (struct edge_list *, basic_block, basic_block);
|
||||
edge find_edge (basic_block, basic_block);
|
||||
extern void remove_fake_edges (void);
|
||||
extern void remove_fake_exit_edges (void);
|
||||
extern void add_noreturn_fake_exit_edges (void);
|
||||
extern void connect_infinite_loops_to_exit (void);
|
||||
extern int post_order_compute (int *, bool, bool);
|
||||
extern basic_block dfs_find_deadend (basic_block);
|
||||
extern int inverted_post_order_compute (int *);
|
||||
extern int pre_and_rev_post_order_compute (int *, int *, bool);
|
||||
extern int dfs_enumerate_from (basic_block, int,
|
||||
bool (*)(const_basic_block, const void *),
|
||||
basic_block *, int, const void *);
|
||||
extern void compute_dominance_frontiers (struct bitmap_head_def *);
|
||||
extern bitmap compute_idf (bitmap, struct bitmap_head_def *);
|
||||
|
||||
/* In cfgrtl.c */
|
||||
extern rtx block_label (basic_block);
|
||||
extern rtx bb_note (basic_block);
|
||||
extern bool purge_all_dead_edges (void);
|
||||
extern bool purge_dead_edges (basic_block);
|
||||
extern bool fixup_abnormal_edges (void);
|
||||
extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
|
||||
extern bool contains_no_active_insn_p (const_basic_block);
|
||||
extern bool forwarder_block_p (const_basic_block);
|
||||
extern bool can_fallthru (basic_block, basic_block);
|
||||
|
||||
/* In cfgbuild.c. */
|
||||
extern void find_many_sub_basic_blocks (sbitmap);
|
||||
extern void rtl_make_eh_edge (sbitmap, basic_block, rtx);
|
||||
|
||||
enum replace_direction { dir_none, dir_forward, dir_backward, dir_both };
|
||||
|
||||
/* In cfgcleanup.c. */
|
||||
extern bool cleanup_cfg (int);
|
||||
extern int flow_find_cross_jump (basic_block, basic_block, rtx *, rtx *,
|
||||
enum replace_direction*);
|
||||
extern int flow_find_head_matching_sequence (basic_block, basic_block,
|
||||
rtx *, rtx *, int);
|
||||
|
||||
extern bool delete_unreachable_blocks (void);
|
||||
|
||||
extern void update_br_prob_note (basic_block);
|
||||
extern bool inside_basic_block_p (const_rtx);
|
||||
extern bool control_flow_insn_p (const_rtx);
|
||||
extern rtx get_last_bb_insn (basic_block);
|
||||
|
||||
/* In dominance.c */
|
||||
|
||||
enum cdi_direction
|
||||
{
|
||||
CDI_DOMINATORS = 1,
|
||||
CDI_POST_DOMINATORS = 2
|
||||
};
|
||||
|
||||
extern enum dom_state dom_info_state (enum cdi_direction);
|
||||
extern void set_dom_info_availability (enum cdi_direction, enum dom_state);
|
||||
extern bool dom_info_available_p (enum cdi_direction);
|
||||
extern void calculate_dominance_info (enum cdi_direction);
|
||||
extern void free_dominance_info (enum cdi_direction);
|
||||
extern basic_block nearest_common_dominator (enum cdi_direction,
|
||||
basic_block, basic_block);
|
||||
extern basic_block nearest_common_dominator_for_set (enum cdi_direction,
|
||||
bitmap);
|
||||
extern void set_immediate_dominator (enum cdi_direction, basic_block,
|
||||
basic_block);
|
||||
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
|
||||
extern bool dominated_by_p (enum cdi_direction, const_basic_block, const_basic_block);
|
||||
extern vec<basic_block> get_dominated_by (enum cdi_direction, basic_block);
|
||||
extern vec<basic_block> get_dominated_by_region (enum cdi_direction,
|
||||
basic_block *,
|
||||
unsigned);
|
||||
extern vec<basic_block> get_dominated_to_depth (enum cdi_direction,
|
||||
basic_block, int);
|
||||
extern vec<basic_block> get_all_dominated_blocks (enum cdi_direction,
|
||||
basic_block);
|
||||
extern void add_to_dominance_info (enum cdi_direction, basic_block);
|
||||
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
|
||||
basic_block recompute_dominator (enum cdi_direction, basic_block);
|
||||
extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
|
||||
basic_block);
|
||||
extern void iterate_fix_dominators (enum cdi_direction,
|
||||
vec<basic_block> , bool);
|
||||
extern void verify_dominators (enum cdi_direction);
|
||||
extern basic_block first_dom_son (enum cdi_direction, basic_block);
|
||||
extern basic_block next_dom_son (enum cdi_direction, basic_block);
|
||||
unsigned bb_dom_dfs_in (enum cdi_direction, basic_block);
|
||||
unsigned bb_dom_dfs_out (enum cdi_direction, basic_block);
|
||||
|
||||
extern edge try_redirect_by_replacing_jump (edge, basic_block, bool);
|
||||
extern void break_superblocks (void);
|
||||
extern void relink_block_chain (bool);
|
||||
extern void update_bb_profile_for_threading (basic_block, int, gcov_type, edge);
|
||||
extern void init_rtl_bb_info (basic_block);
|
||||
|
||||
extern void initialize_original_copy_tables (void);
|
||||
extern void free_original_copy_tables (void);
|
||||
extern void set_bb_original (basic_block, basic_block);
|
||||
extern basic_block get_bb_original (basic_block);
|
||||
extern void set_bb_copy (basic_block, basic_block);
|
||||
extern basic_block get_bb_copy (basic_block);
|
||||
void set_loop_copy (struct loop *, struct loop *);
|
||||
struct loop *get_loop_copy (struct loop *);
|
||||
|
||||
#include "cfghooks.h"
|
||||
|
||||
/* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */
|
||||
static inline bool
|
||||
bb_has_eh_pred (basic_block bb)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
if (e->flags & EDGE_EH)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */
|
||||
static inline bool
|
||||
bb_has_abnormal_pred (basic_block bb)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
if (e->flags & EDGE_ABNORMAL)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return the fallthru edge in EDGES if it exists, NULL otherwise. */
|
||||
static inline edge
|
||||
find_fallthru_edge (vec<edge, va_gc> *edges)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, edges)
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
break;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/* In cfgloopmanip.c. */
|
||||
extern edge mfb_kj_edge;
|
||||
extern bool mfb_keep_just (edge);
|
||||
|
||||
/* In cfgexpand.c. */
|
||||
extern void rtl_profile_for_bb (basic_block);
|
||||
extern void rtl_profile_for_edge (edge);
|
||||
extern void default_rtl_profile (void);
|
||||
|
||||
/* In profile.c. */
|
||||
extern gcov_working_set_t *find_working_set(unsigned pct_times_10);
|
||||
|
||||
/* Check tha probability is sane. */
|
||||
|
||||
static inline void
|
||||
check_probability (int prob)
|
||||
{
|
||||
gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
|
||||
}
|
||||
|
||||
/* Given PROB1 and PROB2, return PROB1*PROB2/REG_BR_PROB_BASE.
|
||||
Used to combine BB probabilities. */
|
||||
|
||||
static inline int
|
||||
combine_probabilities (int prob1, int prob2)
|
||||
{
|
||||
check_probability (prob1);
|
||||
check_probability (prob2);
|
||||
return RDIV (prob1 * prob2, REG_BR_PROB_BASE);
|
||||
}
|
||||
|
||||
/* Apply probability PROB on frequency or count FREQ. */
|
||||
|
||||
static inline gcov_type
|
||||
apply_probability (gcov_type freq, int prob)
|
||||
{
|
||||
check_probability (prob);
|
||||
return RDIV (freq * prob, REG_BR_PROB_BASE);
|
||||
}
|
||||
|
||||
/* Return inverse probability for PROB. */
|
||||
|
||||
static inline int
|
||||
inverse_probability (int prob1)
|
||||
{
|
||||
check_probability (prob1);
|
||||
return REG_BR_PROB_BASE - prob1;
|
||||
}
|
||||
#endif /* GCC_BASIC_BLOCK_H */
|
||||
|
|
@ -0,0 +1,713 @@
|
|||
/* Functions to support general ended bitmaps.
|
||||
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_BITMAP_H
|
||||
#define GCC_BITMAP_H
|
||||
|
||||
/* Implementation of sparse integer sets as a linked list.
|
||||
|
||||
This sparse set representation is suitable for sparse sets with an
|
||||
unknown (a priori) universe. The set is represented as a double-linked
|
||||
list of container nodes (struct bitmap_element_def). Each node consists
|
||||
of an index for the first member that could be held in the container,
|
||||
a small array of integers that represent the members in the container,
|
||||
and pointers to the next and previous element in the linked list. The
|
||||
elements in the list are sorted in ascending order, i.e. the head of
|
||||
the list holds the element with the smallest member of the set.
|
||||
|
||||
For a given member I in the set:
|
||||
- the element for I will have index is I / (bits per element)
|
||||
- the position for I within element is I % (bits per element)
|
||||
|
||||
This representation is very space-efficient for large sparse sets, and
|
||||
the size of the set can be changed dynamically without much overhead.
|
||||
An important parameter is the number of bits per element. In this
|
||||
implementation, there are 128 bits per element. This results in a
|
||||
high storage overhead *per element*, but a small overall overhead if
|
||||
the set is very sparse.
|
||||
|
||||
The downside is that many operations are relatively slow because the
|
||||
linked list has to be traversed to test membership (i.e. member_p/
|
||||
add_member/remove_member). To improve the performance of this set
|
||||
representation, the last accessed element and its index are cached.
|
||||
For membership tests on members close to recently accessed members,
|
||||
the cached last element improves membership test to a constant-time
|
||||
operation.
|
||||
|
||||
The following operations can always be performed in O(1) time:
|
||||
|
||||
* clear : bitmap_clear
|
||||
* choose_one : (not implemented, but could be
|
||||
implemented in constant time)
|
||||
|
||||
The following operations can be performed in O(E) time worst-case (with
|
||||
E the number of elements in the linked list), but in O(1) time with a
|
||||
suitable access patterns:
|
||||
|
||||
* member_p : bitmap_bit_p
|
||||
* add_member : bitmap_set_bit
|
||||
* remove_member : bitmap_clear_bit
|
||||
|
||||
The following operations can be performed in O(E) time:
|
||||
|
||||
* cardinality : bitmap_count_bits
|
||||
* set_size : bitmap_last_set_bit (but this could
|
||||
in constant time with a pointer to
|
||||
the last element in the chain)
|
||||
|
||||
Additionally, the linked-list sparse set representation supports
|
||||
enumeration of the members in O(E) time:
|
||||
|
||||
* forall : EXECUTE_IF_SET_IN_BITMAP
|
||||
* set_copy : bitmap_copy
|
||||
* set_intersection : bitmap_intersect_p /
|
||||
bitmap_and / bitmap_and_into /
|
||||
EXECUTE_IF_AND_IN_BITMAP
|
||||
* set_union : bitmap_ior / bitmap_ior_into
|
||||
* set_difference : bitmap_intersect_compl_p /
|
||||
bitmap_and_comp / bitmap_and_comp_into /
|
||||
EXECUTE_IF_AND_COMPL_IN_BITMAP
|
||||
* set_disjuction : bitmap_xor_comp / bitmap_xor_comp_into
|
||||
* set_compare : bitmap_equal_p
|
||||
|
||||
Some operations on 3 sets that occur frequently in in data flow problems
|
||||
are also implemented:
|
||||
|
||||
* A | (B & C) : bitmap_ior_and_into
|
||||
* A | (B & ~C) : bitmap_ior_and_compl /
|
||||
bitmap_ior_and_compl_into
|
||||
|
||||
The storage requirements for linked-list sparse sets are O(E), with E->N
|
||||
in the worst case (a sparse set with large distances between the values
|
||||
of the set members).
|
||||
|
||||
The linked-list set representation works well for problems involving very
|
||||
sparse sets. The canonical example in GCC is, of course, the "set of
|
||||
sets" for some CFG-based data flow problems (liveness analysis, dominance
|
||||
frontiers, etc.).
|
||||
|
||||
This representation also works well for data flow problems where the size
|
||||
of the set may grow dynamically, but care must be taken that the member_p,
|
||||
add_member, and remove_member operations occur with a suitable access
|
||||
pattern.
|
||||
|
||||
For random-access sets with a known, relatively small universe size, the
|
||||
SparseSet or simple bitmap representations may be more efficient than a
|
||||
linked-list set. For random-access sets of unknown universe, a hash table
|
||||
or a balanced binary tree representation is likely to be a more suitable
|
||||
choice.
|
||||
|
||||
Traversing linked lists is usually cache-unfriendly, even with the last
|
||||
accessed element cached.
|
||||
|
||||
Cache performance can be improved by keeping the elements in the set
|
||||
grouped together in memory, using a dedicated obstack for a set (or group
|
||||
of related sets). Elements allocated on obstacks are released to a
|
||||
free-list and taken off the free list. If multiple sets are allocated on
|
||||
the same obstack, elements freed from one set may be re-used for one of
|
||||
the other sets. This usually helps avoid cache misses.
|
||||
|
||||
A single free-list is used for all sets allocated in GGC space. This is
|
||||
bad for persistent sets, so persistent sets should be allocated on an
|
||||
obstack whenever possible. */
|
||||
|
||||
#include "hashtab.h"
|
||||
#include "statistics.h"
|
||||
#include "obstack.h"
|
||||
|
||||
/* Fundamental storage type for bitmap. */
|
||||
|
||||
typedef unsigned long BITMAP_WORD;
|
||||
/* BITMAP_WORD_BITS needs to be unsigned, but cannot contain casts as
|
||||
it is used in preprocessor directives -- hence the 1u. */
|
||||
#define BITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG * 1u)
|
||||
|
||||
/* Number of words to use for each element in the linked list. */
|
||||
|
||||
#ifndef BITMAP_ELEMENT_WORDS
|
||||
#define BITMAP_ELEMENT_WORDS ((128 + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
|
||||
#endif
|
||||
|
||||
/* Number of bits in each actual element of a bitmap. */
|
||||
|
||||
#define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS)
|
||||
|
||||
/* Obstack for allocating bitmaps and elements from. */
|
||||
typedef struct GTY (()) bitmap_obstack {
|
||||
struct bitmap_element_def *elements;
|
||||
struct bitmap_head_def *heads;
|
||||
struct obstack GTY ((skip)) obstack;
|
||||
} bitmap_obstack;
|
||||
|
||||
/* Bitmap set element. We use a linked list to hold only the bits that
|
||||
are set. This allows for use to grow the bitset dynamically without
|
||||
having to realloc and copy a giant bit array.
|
||||
|
||||
The free list is implemented as a list of lists. There is one
|
||||
outer list connected together by prev fields. Each element of that
|
||||
outer is an inner list (that may consist only of the outer list
|
||||
element) that are connected by the next fields. The prev pointer
|
||||
is undefined for interior elements. This allows
|
||||
bitmap_elt_clear_from to be implemented in unit time rather than
|
||||
linear in the number of elements to be freed. */
|
||||
|
||||
typedef struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) bitmap_element_def {
|
||||
struct bitmap_element_def *next; /* Next element. */
|
||||
struct bitmap_element_def *prev; /* Previous element. */
|
||||
unsigned int indx; /* regno/BITMAP_ELEMENT_ALL_BITS. */
|
||||
BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */
|
||||
} bitmap_element;
|
||||
|
||||
/* Head of bitmap linked list. The 'current' member points to something
|
||||
already pointed to by the chain started by first, so GTY((skip)) it. */
|
||||
|
||||
typedef struct GTY(()) bitmap_head_def {
|
||||
unsigned int indx; /* Index of last element looked at. */
|
||||
unsigned int descriptor_id; /* Unique identifier for the allocation
|
||||
site of this bitmap, for detailed
|
||||
statistics gathering. */
|
||||
bitmap_element *first; /* First element in linked list. */
|
||||
bitmap_element * GTY((skip(""))) current; /* Last element looked at. */
|
||||
bitmap_obstack *obstack; /* Obstack to allocate elements from.
|
||||
If NULL, then use GGC allocation. */
|
||||
} bitmap_head;
|
||||
|
||||
/* Global data */
|
||||
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
|
||||
extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */
|
||||
|
||||
/* Clear a bitmap by freeing up the linked list. */
|
||||
extern void bitmap_clear (bitmap);
|
||||
|
||||
/* Copy a bitmap to another bitmap. */
|
||||
extern void bitmap_copy (bitmap, const_bitmap);
|
||||
|
||||
/* True if two bitmaps are identical. */
|
||||
extern bool bitmap_equal_p (const_bitmap, const_bitmap);
|
||||
|
||||
/* True if the bitmaps intersect (their AND is non-empty). */
|
||||
extern bool bitmap_intersect_p (const_bitmap, const_bitmap);
|
||||
|
||||
/* True if the complement of the second intersects the first (their
|
||||
AND_COMPL is non-empty). */
|
||||
extern bool bitmap_intersect_compl_p (const_bitmap, const_bitmap);
|
||||
|
||||
/* True if MAP is an empty bitmap. */
|
||||
inline bool bitmap_empty_p (const_bitmap map)
|
||||
{
|
||||
return !map->first;
|
||||
}
|
||||
|
||||
/* True if the bitmap has only a single bit set. */
|
||||
extern bool bitmap_single_bit_set_p (const_bitmap);
|
||||
|
||||
/* Count the number of bits set in the bitmap. */
|
||||
extern unsigned long bitmap_count_bits (const_bitmap);
|
||||
|
||||
/* Boolean operations on bitmaps. The _into variants are two operand
|
||||
versions that modify the first source operand. The other variants
|
||||
are three operand versions that to not destroy the source bitmaps.
|
||||
The operations supported are &, & ~, |, ^. */
|
||||
extern void bitmap_and (bitmap, const_bitmap, const_bitmap);
|
||||
extern bool bitmap_and_into (bitmap, const_bitmap);
|
||||
extern bool bitmap_and_compl (bitmap, const_bitmap, const_bitmap);
|
||||
extern bool bitmap_and_compl_into (bitmap, const_bitmap);
|
||||
#define bitmap_compl_and(DST, A, B) bitmap_and_compl (DST, B, A)
|
||||
extern void bitmap_compl_and_into (bitmap, const_bitmap);
|
||||
extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
|
||||
extern void bitmap_set_range (bitmap, unsigned int, unsigned int);
|
||||
extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap);
|
||||
extern bool bitmap_ior_into (bitmap, const_bitmap);
|
||||
extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
|
||||
extern void bitmap_xor_into (bitmap, const_bitmap);
|
||||
|
||||
/* DST = A | (B & C). Return true if DST changes. */
|
||||
extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C);
|
||||
/* DST = A | (B & ~C). Return true if DST changes. */
|
||||
extern bool bitmap_ior_and_compl (bitmap DST, const_bitmap A,
|
||||
const_bitmap B, const_bitmap C);
|
||||
/* A |= (B & ~C). Return true if A changes. */
|
||||
extern bool bitmap_ior_and_compl_into (bitmap A,
|
||||
const_bitmap B, const_bitmap C);
|
||||
|
||||
/* Clear a single bit in a bitmap. Return true if the bit changed. */
|
||||
extern bool bitmap_clear_bit (bitmap, int);
|
||||
|
||||
/* Set a single bit in a bitmap. Return true if the bit changed. */
|
||||
extern bool bitmap_set_bit (bitmap, int);
|
||||
|
||||
/* Return true if a register is set in a register set. */
|
||||
extern int bitmap_bit_p (bitmap, int);
|
||||
|
||||
/* Debug functions to print a bitmap linked list. */
|
||||
extern void debug_bitmap (const_bitmap);
|
||||
extern void debug_bitmap_file (FILE *, const_bitmap);
|
||||
|
||||
/* Print a bitmap. */
|
||||
extern void bitmap_print (FILE *, const_bitmap, const char *, const char *);
|
||||
|
||||
/* Initialize and release a bitmap obstack. */
|
||||
extern void bitmap_obstack_initialize (bitmap_obstack *);
|
||||
extern void bitmap_obstack_release (bitmap_obstack *);
|
||||
extern void bitmap_register (bitmap MEM_STAT_DECL);
|
||||
extern void dump_bitmap_statistics (void);
|
||||
|
||||
/* Initialize a bitmap header. OBSTACK indicates the bitmap obstack
|
||||
to allocate from, NULL for GC'd bitmap. */
|
||||
|
||||
static inline void
|
||||
bitmap_initialize_stat (bitmap head, bitmap_obstack *obstack MEM_STAT_DECL)
|
||||
{
|
||||
head->first = head->current = NULL;
|
||||
head->obstack = obstack;
|
||||
if (GATHER_STATISTICS)
|
||||
bitmap_register (head PASS_MEM_STAT);
|
||||
}
|
||||
#define bitmap_initialize(h,o) bitmap_initialize_stat (h,o MEM_STAT_INFO)
|
||||
|
||||
/* Allocate and free bitmaps from obstack, malloc and gc'd memory. */
|
||||
extern bitmap bitmap_obstack_alloc_stat (bitmap_obstack *obstack MEM_STAT_DECL);
|
||||
#define bitmap_obstack_alloc(t) bitmap_obstack_alloc_stat (t MEM_STAT_INFO)
|
||||
extern bitmap bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL);
|
||||
#define bitmap_gc_alloc() bitmap_gc_alloc_stat (ALONE_MEM_STAT_INFO)
|
||||
extern void bitmap_obstack_free (bitmap);
|
||||
|
||||
/* A few compatibility/functions macros for compatibility with sbitmaps */
|
||||
inline void dump_bitmap (FILE *file, const_bitmap map)
|
||||
{
|
||||
bitmap_print (file, map, "", "\n");
|
||||
}
|
||||
|
||||
extern unsigned bitmap_first_set_bit (const_bitmap);
|
||||
extern unsigned bitmap_last_set_bit (const_bitmap);
|
||||
|
||||
/* Compute bitmap hash (for purposes of hashing etc.) */
|
||||
extern hashval_t bitmap_hash(const_bitmap);
|
||||
|
||||
/* Allocate a bitmap from a bit obstack. */
|
||||
#define BITMAP_ALLOC(OBSTACK) bitmap_obstack_alloc (OBSTACK)
|
||||
|
||||
/* Allocate a gc'd bitmap. */
|
||||
#define BITMAP_GGC_ALLOC() bitmap_gc_alloc ()
|
||||
|
||||
/* Do any cleanup needed on a bitmap when it is no longer used. */
|
||||
#define BITMAP_FREE(BITMAP) \
|
||||
((void) (bitmap_obstack_free ((bitmap) BITMAP), (BITMAP) = (bitmap) NULL))
|
||||
|
||||
/* Iterator for bitmaps. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Pointer to the current bitmap element. */
|
||||
bitmap_element *elt1;
|
||||
|
||||
/* Pointer to 2nd bitmap element when two are involved. */
|
||||
bitmap_element *elt2;
|
||||
|
||||
/* Word within the current element. */
|
||||
unsigned word_no;
|
||||
|
||||
/* Contents of the actually processed word. When finding next bit
|
||||
it is shifted right, so that the actual bit is always the least
|
||||
significant bit of ACTUAL. */
|
||||
BITMAP_WORD bits;
|
||||
} bitmap_iterator;
|
||||
|
||||
/* Initialize a single bitmap iterator. START_BIT is the first bit to
|
||||
iterate from. */
|
||||
|
||||
static inline void
|
||||
bmp_iter_set_init (bitmap_iterator *bi, const_bitmap map,
|
||||
unsigned start_bit, unsigned *bit_no)
|
||||
{
|
||||
bi->elt1 = map->first;
|
||||
bi->elt2 = NULL;
|
||||
|
||||
/* Advance elt1 until it is not before the block containing start_bit. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt1)
|
||||
{
|
||||
bi->elt1 = &bitmap_zero_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
break;
|
||||
bi->elt1 = bi->elt1->next;
|
||||
}
|
||||
|
||||
/* We might have gone past the start bit, so reinitialize it. */
|
||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
/* Initialize for what is now start_bit. */
|
||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||
|
||||
/* If this word is zero, we must make sure we're not pointing at the
|
||||
first bit, otherwise our incrementing to the next word boundary
|
||||
will fail. It won't matter if this increment moves us into the
|
||||
next word. */
|
||||
start_bit += !bi->bits;
|
||||
|
||||
*bit_no = start_bit;
|
||||
}
|
||||
|
||||
/* Initialize an iterator to iterate over the intersection of two
|
||||
bitmaps. START_BIT is the bit to commence from. */
|
||||
|
||||
static inline void
|
||||
bmp_iter_and_init (bitmap_iterator *bi, const_bitmap map1, const_bitmap map2,
|
||||
unsigned start_bit, unsigned *bit_no)
|
||||
{
|
||||
bi->elt1 = map1->first;
|
||||
bi->elt2 = map2->first;
|
||||
|
||||
/* Advance elt1 until it is not before the block containing
|
||||
start_bit. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt1)
|
||||
{
|
||||
bi->elt2 = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
break;
|
||||
bi->elt1 = bi->elt1->next;
|
||||
}
|
||||
|
||||
/* Advance elt2 until it is not before elt1. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt2)
|
||||
{
|
||||
bi->elt1 = bi->elt2 = &bitmap_zero_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt2->indx >= bi->elt1->indx)
|
||||
break;
|
||||
bi->elt2 = bi->elt2->next;
|
||||
}
|
||||
|
||||
/* If we're at the same index, then we have some intersecting bits. */
|
||||
if (bi->elt1->indx == bi->elt2->indx)
|
||||
{
|
||||
/* We might have advanced beyond the start_bit, so reinitialize
|
||||
for that. */
|
||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we must immediately advance elt1, so initialize for
|
||||
that. */
|
||||
bi->word_no = BITMAP_ELEMENT_WORDS - 1;
|
||||
bi->bits = 0;
|
||||
}
|
||||
|
||||
/* If this word is zero, we must make sure we're not pointing at the
|
||||
first bit, otherwise our incrementing to the next word boundary
|
||||
will fail. It won't matter if this increment moves us into the
|
||||
next word. */
|
||||
start_bit += !bi->bits;
|
||||
|
||||
*bit_no = start_bit;
|
||||
}
|
||||
|
||||
/* Initialize an iterator to iterate over the bits in MAP1 & ~MAP2.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
bmp_iter_and_compl_init (bitmap_iterator *bi,
|
||||
const_bitmap map1, const_bitmap map2,
|
||||
unsigned start_bit, unsigned *bit_no)
|
||||
{
|
||||
bi->elt1 = map1->first;
|
||||
bi->elt2 = map2->first;
|
||||
|
||||
/* Advance elt1 until it is not before the block containing start_bit. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt1)
|
||||
{
|
||||
bi->elt1 = &bitmap_zero_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
break;
|
||||
bi->elt1 = bi->elt1->next;
|
||||
}
|
||||
|
||||
/* Advance elt2 until it is not before elt1. */
|
||||
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
||||
bi->elt2 = bi->elt2->next;
|
||||
|
||||
/* We might have advanced beyond the start_bit, so reinitialize for
|
||||
that. */
|
||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
if (bi->elt2 && bi->elt1->indx == bi->elt2->indx)
|
||||
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||
|
||||
/* If this word is zero, we must make sure we're not pointing at the
|
||||
first bit, otherwise our incrementing to the next word boundary
|
||||
will fail. It won't matter if this increment moves us into the
|
||||
next word. */
|
||||
start_bit += !bi->bits;
|
||||
|
||||
*bit_no = start_bit;
|
||||
}
|
||||
|
||||
/* Advance to the next bit in BI. We don't advance to the next
|
||||
nonzero bit yet. */
|
||||
|
||||
static inline void
|
||||
bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
bi->bits >>= 1;
|
||||
*bit_no += 1;
|
||||
}
|
||||
|
||||
/* Advance to first set bit in BI. */
|
||||
|
||||
static inline void
|
||||
bmp_iter_next_bit (bitmap_iterator * bi, unsigned *bit_no)
|
||||
{
|
||||
#if (GCC_VERSION >= 3004)
|
||||
{
|
||||
unsigned int n = __builtin_ctzl (bi->bits);
|
||||
gcc_assert (sizeof (unsigned long) == sizeof (BITMAP_WORD));
|
||||
bi->bits >>= n;
|
||||
*bit_no += n;
|
||||
}
|
||||
#else
|
||||
while (!(bi->bits & 1))
|
||||
{
|
||||
bi->bits >>= 1;
|
||||
*bit_no += 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Advance to the next nonzero bit of a single bitmap, we will have
|
||||
already advanced past the just iterated bit. Return true if there
|
||||
is a bit to iterate. */
|
||||
|
||||
static inline bool
|
||||
bmp_iter_set (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
/* If our current word is nonzero, it contains the bit we want. */
|
||||
if (bi->bits)
|
||||
{
|
||||
next_bit:
|
||||
bmp_iter_next_bit (bi, bit_no);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Round up to the word boundary. We might have just iterated past
|
||||
the end of the last word, hence the -1. It is not possible for
|
||||
bit_no to point at the beginning of the now last word. */
|
||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||
bi->word_no++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Find the next nonzero word in this elt. */
|
||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||
{
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
if (bi->bits)
|
||||
goto next_bit;
|
||||
*bit_no += BITMAP_WORD_BITS;
|
||||
bi->word_no++;
|
||||
}
|
||||
|
||||
/* Advance to the next element. */
|
||||
bi->elt1 = bi->elt1->next;
|
||||
if (!bi->elt1)
|
||||
return false;
|
||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
bi->word_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to the next nonzero bit of an intersecting pair of
|
||||
bitmaps. We will have already advanced past the just iterated bit.
|
||||
Return true if there is a bit to iterate. */
|
||||
|
||||
static inline bool
|
||||
bmp_iter_and (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
/* If our current word is nonzero, it contains the bit we want. */
|
||||
if (bi->bits)
|
||||
{
|
||||
next_bit:
|
||||
bmp_iter_next_bit (bi, bit_no);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Round up to the word boundary. We might have just iterated past
|
||||
the end of the last word, hence the -1. It is not possible for
|
||||
bit_no to point at the beginning of the now last word. */
|
||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||
bi->word_no++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Find the next nonzero word in this elt. */
|
||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||
{
|
||||
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
||||
if (bi->bits)
|
||||
goto next_bit;
|
||||
*bit_no += BITMAP_WORD_BITS;
|
||||
bi->word_no++;
|
||||
}
|
||||
|
||||
/* Advance to the next identical element. */
|
||||
do
|
||||
{
|
||||
/* Advance elt1 while it is less than elt2. We always want
|
||||
to advance one elt. */
|
||||
do
|
||||
{
|
||||
bi->elt1 = bi->elt1->next;
|
||||
if (!bi->elt1)
|
||||
return false;
|
||||
}
|
||||
while (bi->elt1->indx < bi->elt2->indx);
|
||||
|
||||
/* Advance elt2 to be no less than elt1. This might not
|
||||
advance. */
|
||||
while (bi->elt2->indx < bi->elt1->indx)
|
||||
{
|
||||
bi->elt2 = bi->elt2->next;
|
||||
if (!bi->elt2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (bi->elt1->indx != bi->elt2->indx);
|
||||
|
||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
bi->word_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to the next nonzero bit in the intersection of
|
||||
complemented bitmaps. We will have already advanced past the just
|
||||
iterated bit. */
|
||||
|
||||
static inline bool
|
||||
bmp_iter_and_compl (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
/* If our current word is nonzero, it contains the bit we want. */
|
||||
if (bi->bits)
|
||||
{
|
||||
next_bit:
|
||||
bmp_iter_next_bit (bi, bit_no);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Round up to the word boundary. We might have just iterated past
|
||||
the end of the last word, hence the -1. It is not possible for
|
||||
bit_no to point at the beginning of the now last word. */
|
||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||
bi->word_no++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Find the next nonzero word in this elt. */
|
||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||
{
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
if (bi->elt2 && bi->elt2->indx == bi->elt1->indx)
|
||||
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
||||
if (bi->bits)
|
||||
goto next_bit;
|
||||
*bit_no += BITMAP_WORD_BITS;
|
||||
bi->word_no++;
|
||||
}
|
||||
|
||||
/* Advance to the next element of elt1. */
|
||||
bi->elt1 = bi->elt1->next;
|
||||
if (!bi->elt1)
|
||||
return false;
|
||||
|
||||
/* Advance elt2 until it is no less than elt1. */
|
||||
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
||||
bi->elt2 = bi->elt2->next;
|
||||
|
||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
bi->word_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over all bits set in BITMAP, starting with MIN and setting
|
||||
BITNUM to the bit number. ITER is a bitmap iterator. BITNUM
|
||||
should be treated as a read-only variable as it contains loop
|
||||
state. */
|
||||
|
||||
#ifndef EXECUTE_IF_SET_IN_BITMAP
|
||||
/* See sbitmap.h for the other definition of EXECUTE_IF_SET_IN_BITMAP. */
|
||||
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER) \
|
||||
for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM)); \
|
||||
bmp_iter_set (&(ITER), &(BITNUM)); \
|
||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||
#endif
|
||||
|
||||
/* Loop over all the bits set in BITMAP1 & BITMAP2, starting with MIN
|
||||
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
||||
BITNUM should be treated as a read-only variable as it contains
|
||||
loop state. */
|
||||
|
||||
#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
||||
for (bmp_iter_and_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
||||
&(BITNUM)); \
|
||||
bmp_iter_and (&(ITER), &(BITNUM)); \
|
||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||
|
||||
/* Loop over all the bits set in BITMAP1 & ~BITMAP2, starting with MIN
|
||||
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
||||
BITNUM should be treated as a read-only variable as it contains
|
||||
loop state. */
|
||||
|
||||
#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
||||
for (bmp_iter_and_compl_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
||||
&(BITNUM)); \
|
||||
bmp_iter_and_compl (&(ITER), &(BITNUM)); \
|
||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||
|
||||
#endif /* GCC_BITMAP_H */
|
||||
|
|
@ -0,0 +1,839 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
builtins used in the GNU compiler.
|
||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Before including this file, you should define a macro:
|
||||
|
||||
DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
|
||||
FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND)
|
||||
|
||||
This macro will be called once for each builtin function. The
|
||||
ENUM will be of type `enum built_in_function', and will indicate
|
||||
which builtin function is being processed. The NAME of the builtin
|
||||
function (which will always start with `__builtin_') is a string
|
||||
literal. The CLASS is of type `enum built_in_class' and indicates
|
||||
what kind of builtin is being processed.
|
||||
|
||||
Some builtins are actually two separate functions. For example,
|
||||
for `strcmp' there are two builtin functions; `__builtin_strcmp'
|
||||
and `strcmp' itself. Both behave identically. Other builtins
|
||||
define only the `__builtin' variant. If BOTH_P is TRUE, then this
|
||||
builtin has both variants; otherwise, it is has only the first
|
||||
variant.
|
||||
|
||||
TYPE indicates the type of the function. The symbols correspond to
|
||||
enumerals from builtin-types.def. If BOTH_P is true, then LIBTYPE
|
||||
is the type of the non-`__builtin_' variant. Otherwise, LIBTYPE
|
||||
should be ignored.
|
||||
|
||||
If FALLBACK_P is true then, if for some reason, the compiler cannot
|
||||
expand the builtin function directly, it will call the
|
||||
corresponding library function (which does not have the
|
||||
`__builtin_' prefix.
|
||||
|
||||
If NONANSI_P is true, then the non-`__builtin_' variant is not an
|
||||
ANSI/ISO library function, and so we should pretend it does not
|
||||
exist when compiling in ANSI conformant mode.
|
||||
|
||||
ATTRs is an attribute list as defined in builtin-attrs.def that
|
||||
describes the attributes of this builtin function.
|
||||
|
||||
IMPLICIT specifies condition when the builtin can be produced by
|
||||
compiler. For instance C90 reserves floorf function, but does not
|
||||
define it's meaning. When user uses floorf we may assume that the
|
||||
floorf has the meaning we expect, but we can't produce floorf by
|
||||
simplifying floor((double)float) since the runtime need not implement
|
||||
it.
|
||||
|
||||
The builtins is registered only if COND is true. */
|
||||
|
||||
/* A GCC builtin (like __builtin_saveregs) is provided by the
|
||||
compiler, but does not correspond to a function in the standard
|
||||
library. */
|
||||
#undef DEF_GCC_BUILTIN
|
||||
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||
false, false, false, ATTRS, true, true)
|
||||
|
||||
/* Like DEF_GCC_BUILTIN, except we don't prepend "__builtin_". */
|
||||
#undef DEF_SYNC_BUILTIN
|
||||
#define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||
false, false, false, ATTRS, true, true)
|
||||
|
||||
/* A library builtin (like __builtin_strchr) is a builtin equivalent
|
||||
of an ANSI/ISO standard library function. In addition to the
|
||||
`__builtin' version, we will create an ordinary version (e.g,
|
||||
`strchr') as well. If we cannot compute the answer using the
|
||||
builtin function, we will fall back to the standard library
|
||||
version. */
|
||||
#undef DEF_LIB_BUILTIN
|
||||
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, false, ATTRS, true, true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is not one that is
|
||||
specified by ANSI/ISO C. So, when we're being fully conformant we
|
||||
ignore the version of these builtins that does not begin with
|
||||
__builtin. */
|
||||
#undef DEF_EXT_LIB_BUILTIN
|
||||
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true, ATTRS, false, true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C94 or above. */
|
||||
#undef DEF_C94_BUILTIN
|
||||
#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C99 or above. */
|
||||
#undef DEF_C99_BUILTIN
|
||||
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||
|
||||
/* Builtin that is specified by C99 and C90 reserve the name for future use.
|
||||
We can still recognize the builtin in C90 mode but we can't produce it
|
||||
implicitly. */
|
||||
#undef DEF_C99_C90RES_BUILTIN
|
||||
#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||
|
||||
/* Builtin that C99 reserve the name for future use. We can still recognize
|
||||
the builtin in C99 mode but we can't produce it implicitly. */
|
||||
#undef DEF_EXT_C99RES_BUILTIN
|
||||
#define DEF_EXT_C99RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true, ATTRS, false, true)
|
||||
|
||||
/* Allocate the enum and the name for a builtin, but do not actually
|
||||
define it here at all. */
|
||||
#undef DEF_BUILTIN_STUB
|
||||
#define DEF_BUILTIN_STUB(ENUM, NAME) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_LAST, BT_LAST, false, false, \
|
||||
false, ATTR_LAST, false, false)
|
||||
|
||||
/* Builtin used by the implementation of GNU OpenMP. None of these are
|
||||
actually implemented in the compiler; they're all in libgomp. */
|
||||
#undef DEF_GOMP_BUILTIN
|
||||
#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, \
|
||||
(flag_openmp || flag_tree_parallelize_loops))
|
||||
|
||||
/* Builtin used by the implementation of GNU TM. These
|
||||
functions are mapped to the actual implementation of the STM library. */
|
||||
#undef DEF_TM_BUILTIN
|
||||
#define DEF_TM_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true, ATTRS, false, flag_tm)
|
||||
|
||||
/* Builtin used by the implementation of libsanitizer. These
|
||||
functions are mapped to the actual implementation of the
|
||||
libtsan library. */
|
||||
#undef DEF_SANITIZER_BUILTIN
|
||||
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true, ATTRS, true, \
|
||||
(flag_asan || flag_tsan))
|
||||
|
||||
/* Define an attribute list for math functions that are normally
|
||||
"impure" because some of them may write into global memory for
|
||||
`errno'. If !flag_errno_math they are instead "const". */
|
||||
#undef ATTR_MATHFN_ERRNO
|
||||
#define ATTR_MATHFN_ERRNO (flag_errno_math ? \
|
||||
ATTR_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
|
||||
/* Define an attribute list for math functions that are normally
|
||||
"const" but if flag_rounding_math is set they are instead "pure".
|
||||
This distinction accounts for the fact that some math functions
|
||||
check the rounding mode which is akin to examining global
|
||||
memory. */
|
||||
#undef ATTR_MATHFN_FPROUNDING
|
||||
#define ATTR_MATHFN_FPROUNDING (flag_rounding_math ? \
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
|
||||
/* Define an attribute list for math functions that are normally
|
||||
"impure" because some of them may write into global memory for
|
||||
`errno'. If !flag_errno_math, we can possibly use "pure" or
|
||||
"const" depending on whether we care about FP rounding. */
|
||||
#undef ATTR_MATHFN_FPROUNDING_ERRNO
|
||||
#define ATTR_MATHFN_FPROUNDING_ERRNO (flag_errno_math ? \
|
||||
ATTR_NOTHROW_LEAF_LIST : ATTR_MATHFN_FPROUNDING)
|
||||
|
||||
/* Define an attribute list for math functions that need to mind FP
|
||||
rounding, but because they store into memory they are never "const"
|
||||
or "pure". Use of this macro is mainly for documentation and
|
||||
maintenance purposes. */
|
||||
#undef ATTR_MATHFN_FPROUNDING_STORE
|
||||
#define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LEAF_LIST
|
||||
|
||||
/* Make sure 0 is not a legitimate builtin. */
|
||||
DEF_BUILTIN_STUB(BUILT_IN_NONE, (const char *)0)
|
||||
|
||||
/* Category: math builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ACOS, "acos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSF, "acosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ACOSH, "acosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ACOSHF, "acoshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ACOSHL, "acoshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSL, "acosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ASIN, "asin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINF, "asinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ASINH, "asinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ASINHF, "asinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ASINHL, "asinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINL, "asinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ATAN, "atan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ATAN2, "atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2F, "atan2f", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2L, "atan2l", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANF, "atanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ATANH, "atanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ATANHF, "atanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ATANHL, "atanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANL, "atanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CBRT, "cbrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CBRTF, "cbrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CBRTL, "cbrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_CEIL, "ceil", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILF, "ceilf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_COPYSIGN, "copysign", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHF, "coshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHL, "coshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREM, "drem", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREMF, "dremf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREML, "dreml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ERF, "erf", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ERFC, "erfc", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ERFCF, "erfcf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ERFCL, "erfcl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ERFF, "erff", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ERFL, "erfl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_EXP, "exp", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10, "exp10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10F, "exp10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10L, "exp10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_EXP2, "exp2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_EXP2F, "exp2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_EXP2L, "exp2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPF, "expf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPL, "expl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_EXPM1, "expm1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_EXPM1F, "expm1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_EXPM1L, "expm1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FLOOR, "floor", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORF, "floorf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL, "floorl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FREXP, "frexp", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPF, "frexpf", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPL, "frexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA_R, "gamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF_R, "gammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL_R, "gammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_HYPOTL, "hypotl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ICEIL, "iceil", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ICEILF, "iceilf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ICEILL, "iceill", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IFLOOR, "ifloor", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IFLOORF, "ifloorf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IFLOORL, "ifloorl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ILOGB, "ilogb", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ILOGBF, "ilogbf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IRINT, "irint", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IRINTF, "irintf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IRINTL, "irintl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IROUND, "iround", BT_FN_INT_DOUBLE, ATTR_MATHFN_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IROUNDF, "iroundf", BT_FN_INT_FLOAT, ATTR_MATHFN_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_IROUNDL, "iroundl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1, "j1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1F, "j1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1L, "j1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMA_R, "lgamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAF_R, "lgammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAL_R, "lgammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLROUND, "llround", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLROUNDF, "llroundf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLROUNDL, "llroundl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_LOG, "log", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_LOG10, "log10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10F, "log10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10L, "log10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOG1P, "log1p", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOG1PF, "log1pf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOG1PL, "log1pl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOG2, "log2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOG2F, "log2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOG2L, "log2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOGB, "logb", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOGBF, "logbf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LOGBL, "logbl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGF, "logf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGL, "logl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LRINT, "lrint", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LRINTF, "lrintf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LRINTL, "lrintl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LROUND, "lround", BT_FN_LONG_DOUBLE, ATTR_MATHFN_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LROUNDF, "lroundf", BT_FN_LONG_FLOAT, ATTR_MATHFN_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LROUNDL, "lroundl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MODF, "modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFF, "modff", BT_FN_FLOAT_FLOAT_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTER, "nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERF, "nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERL, "nextafterl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARD, "nexttoward", BT_FN_DOUBLE_DOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDF, "nexttowardf", BT_FN_FLOAT_FLOAT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDL, "nexttowardl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_POW, "pow", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWF, "powf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POWI, "powi", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POWIF, "powif", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POWIL, "powil", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWL, "powl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDER, "remainder", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDERF, "remainderf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDERL, "remainderl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMQUO, "remquo", BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMQUOF, "remquof", BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMQUOL, "remquol", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_RINT, "rint", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_RINTF, "rintf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBLN, "scalbln", BT_FN_DOUBLE_DOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBLNF, "scalblnf", BT_FN_FLOAT_FLOAT_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITF, "signbitf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITL, "signbitl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD32, "signbitd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD64, "signbitd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD128, "signbitd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SINH, "sinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHF, "sinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHL, "sinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHF, "tanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHL, "tanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANL, "tanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_TGAMMA, "tgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_TGAMMAF, "tgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_TGAMMAL, "tgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_TRUNC, "trunc", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_TRUNCF, "truncf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_TRUNCL, "truncl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0, "y0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0F, "y0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0L, "y0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1, "y1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1F, "y1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1L, "y1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YN, "yn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
|
||||
/* Category: _Complex math builtins. */
|
||||
DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
|
||||
/* Category: string/memory builtins. */
|
||||
/* bcmp, bcopy and bzero have traditionally accepted NULL pointers
|
||||
when the length parameter is zero, so don't apply attribute "nonnull". */
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||
|
||||
/* Category: stdio builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTC, "putc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTC_UNLOCKED, "putc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_3_4)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_NOTHROW_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_3_0)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_2_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_NOTHROW_2_0)
|
||||
|
||||
/* Category: ctype builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISALNUM, "isalnum", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISALPHA, "isalpha", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISASCII, "isascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ISBLANK, "isblank", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISCNTRL, "iscntrl", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISGRAPH, "isgraph", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISLOWER, "islower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISPRINT, "isprint", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISPUNCT, "ispunct", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISSPACE, "isspace", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISUPPER, "isupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_TOASCII, "toascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_TOLOWER, "tolower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_TOUPPER, "toupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
/* Category: wctype builtins. */
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWALNUM, "iswalnum", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWALPHA, "iswalpha", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ISWBLANK, "iswblank", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWCNTRL, "iswcntrl", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWDIGIT, "iswdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWGRAPH, "iswgraph", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWLOWER, "iswlower", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWPRINT, "iswprint", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWPUNCT, "iswpunct", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWSPACE, "iswspace", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWUPPER, "iswupper", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWXDIGIT, "iswxdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
/* Category: miscellaneous builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ABS, "abs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_AGGREGATE_INCOMING_ADDRESS, "aggregate_incoming_address", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ALLOCA, "alloca", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_BSWAP16, "bswap16", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
/* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSB, "clrsb", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSBIMAX, "clrsbimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSBL, "clrsbl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSBLL, "clrsbll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UINT, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLP, "execlp", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLE, "execle", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_SENTINEL_1)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECV, "execv", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ASSUME_ALIGNED, "assume_aligned", BT_FN_PTR_CONST_PTR_SIZE_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_UNWINDWORD_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
|
||||
/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
|
||||
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISNORMAL, "isnormal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
/* [trans-mem]: Adjust BUILT_IN_TM_MALLOC if BUILT_IN_MALLOC is changed. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MALLOC, "malloc", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NEXT_ARG, "next_arg", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYIMAX, "parityimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||
|
||||
/* Implementing nested functions. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_INIT_HEAP_TRAMPOLINE, "__builtin_init_heap_trampoline")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto")
|
||||
|
||||
/* Implementing __builtin_setjmp. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_DISPATCHER, "__builtin_setjmp_dispatcher")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_RECEIVER, "__builtin_setjmp_receiver")
|
||||
|
||||
/* Implementing variable sized local variables. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_STACK_SAVE, "__builtin_stack_save")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_STACK_RESTORE, "__builtin_stack_restore")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN, "__builtin_alloca_with_align")
|
||||
|
||||
/* Object size checking builtins. */
|
||||
DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_4_0)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_CHK, "__fprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_CHK, "__printf_chk", BT_FN_INT_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VPRINTF_CHK, "__vprintf_chk", BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||
|
||||
/* Profiling hooks. */
|
||||
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
|
||||
false, false, false, ATTR_NULL, true, true)
|
||||
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
|
||||
false, false, false, ATTR_NULL, true, true)
|
||||
|
||||
/* TLS thread pointer related builtins. */
|
||||
DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer",
|
||||
BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST,
|
||||
false, false, true, ATTR_CONST_NOTHROW_LIST, true,
|
||||
targetm.have_tls)
|
||||
|
||||
DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer",
|
||||
BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST,
|
||||
false, false, true, ATTR_NOTHROW_LIST, true,
|
||||
targetm.have_tls)
|
||||
|
||||
/* TLS emulation. */
|
||||
DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address,
|
||||
BUILT_IN_NORMAL,
|
||||
BT_FN_PTR_PTR, BT_FN_PTR_PTR,
|
||||
true, true, true, ATTR_CONST_NOTHROW_NONNULL_LEAF, false,
|
||||
!targetm.have_tls)
|
||||
DEF_BUILTIN (BUILT_IN_EMUTLS_REGISTER_COMMON,
|
||||
targetm.emutls.register_common, BUILT_IN_NORMAL,
|
||||
BT_FN_VOID_PTR_WORD_WORD_PTR, BT_FN_VOID_PTR_WORD_WORD_PTR,
|
||||
true, true, true, ATTR_NOTHROW_LEAF_LIST, false,
|
||||
!targetm.have_tls)
|
||||
|
||||
/* Exception support. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_UNWIND_RESUME, "__builtin_unwind_resume")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_CXA_END_CLEANUP, "__builtin_cxa_end_cleanup")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_EH_POINTER, "__builtin_eh_pointer")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values")
|
||||
|
||||
/* __FILE__, __LINE__, __FUNCTION__ as builtins. */
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
/* Synchronization Primitives. */
|
||||
#include "sync-builtins.def"
|
||||
|
||||
/* OpenMP builtins. */
|
||||
#include "omp-builtins.def"
|
||||
|
||||
/* GTM builtins. */
|
||||
#include "gtm-builtins.def"
|
||||
|
||||
/* Sanitizer builtins. */
|
||||
#include "sanitizer.def"
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#define BUILDING_GCC_MAJOR 4
|
||||
#define BUILDING_GCC_MINOR 8
|
||||
#define BUILDING_GCC_PATCHLEVEL 3
|
||||
#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
additional tree codes used in the GNU C compiler (see tree.def
|
||||
for the standard codes).
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
Written by Benjamin Chelf <chelf@codesourcery.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Tree nodes used in the C frontend. These are also shared with the
|
||||
C++ and Objective C frontends. */
|
||||
|
||||
/* A C_MAYBE_CONST_EXPR, currently only used for C and Objective C,
|
||||
tracks information about constancy of an expression and VLA type
|
||||
sizes or VM expressions from typeof that need to be evaluated
|
||||
before the main expression. It is used during parsing and removed
|
||||
in c_fully_fold. C_MAYBE_CONST_EXPR_PRE is the expression to
|
||||
evaluate first, if not NULL; C_MAYBE_CONST_EXPR_EXPR is the main
|
||||
expression. If C_MAYBE_CONST_EXPR_INT_OPERANDS is set then the
|
||||
expression may be used in an unevaluated part of an integer
|
||||
constant expression, but not in an evaluated part. If
|
||||
C_MAYBE_CONST_EXPR_NON_CONST is set then the expression contains
|
||||
something that cannot occur in an evaluated part of a constant
|
||||
expression (or outside of sizeof in C90 mode); otherwise it does
|
||||
not. */
|
||||
DEFTREECODE (C_MAYBE_CONST_EXPR, "c_maybe_const_expr", tcc_expression, 2)
|
||||
|
||||
/* An EXCESS_PRECISION_EXPR, currently only used for C and Objective
|
||||
C, represents an expression evaluated in greater range or precision
|
||||
than its type. The type of the EXCESS_PRECISION_EXPR is the
|
||||
semantic type while the operand represents what is actually being
|
||||
evaluated. */
|
||||
DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1)
|
||||
|
||||
/* Used to represent a user-defined literal.
|
||||
The operands are an IDENTIFIER for the suffix, the VALUE of the literal,
|
||||
and for numeric literals the original string representation of the
|
||||
number. */
|
||||
DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
|
||||
|
||||
/* Represents a 'sizeof' expression during C++ template expansion,
|
||||
or for the purpose of -Wsizeof-pointer-memaccess warning. */
|
||||
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
End:
|
||||
*/
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,114 @@
|
|||
/* Definitions of Objective-C front-end entry points used for C and C++.
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_C_COMMON_OBJC_H
|
||||
#define GCC_C_COMMON_OBJC_H
|
||||
|
||||
/* ObjC ivar visibility types. */
|
||||
typedef enum objc_ivar_visibility_kind {
|
||||
OBJC_IVAR_VIS_PROTECTED = 0,
|
||||
OBJC_IVAR_VIS_PUBLIC = 1,
|
||||
OBJC_IVAR_VIS_PRIVATE = 2,
|
||||
OBJC_IVAR_VIS_PACKAGE = 3
|
||||
} objc_ivar_visibility_kind;
|
||||
|
||||
/* Objective-C / Objective-C++ entry points. */
|
||||
|
||||
/* The following ObjC/ObjC++ functions are called by the C and/or C++
|
||||
front-ends; they all must have corresponding stubs in stub-objc.c. */
|
||||
extern void objc_write_global_declarations (void);
|
||||
extern tree objc_is_class_name (tree);
|
||||
extern tree objc_is_object_ptr (tree);
|
||||
extern void objc_check_decl (tree);
|
||||
extern void objc_check_global_decl (tree);
|
||||
extern tree objc_common_type (tree, tree);
|
||||
extern bool objc_compare_types (tree, tree, int, tree);
|
||||
extern bool objc_have_common_type (tree, tree, int, tree);
|
||||
extern bool objc_diagnose_private_ivar (tree);
|
||||
extern void objc_volatilize_decl (tree);
|
||||
extern tree objc_rewrite_function_call (tree, tree);
|
||||
extern tree objc_message_selector (void);
|
||||
extern tree objc_lookup_ivar (tree, tree);
|
||||
extern void objc_clear_super_receiver (void);
|
||||
extern int objc_is_public (tree, tree);
|
||||
extern tree objc_is_id (tree);
|
||||
extern void objc_declare_alias (tree, tree);
|
||||
extern void objc_declare_class (tree);
|
||||
extern void objc_declare_protocol (tree, tree);
|
||||
extern tree objc_build_message_expr (tree, tree);
|
||||
extern tree objc_finish_message_expr (tree, tree, tree, tree*);
|
||||
extern tree objc_build_selector_expr (location_t, tree);
|
||||
extern tree objc_build_protocol_expr (tree);
|
||||
extern tree objc_build_encode_expr (tree);
|
||||
extern tree objc_build_string_object (tree);
|
||||
extern tree objc_get_protocol_qualified_type (tree, tree);
|
||||
extern tree objc_get_class_reference (tree);
|
||||
extern tree objc_get_class_ivars (tree);
|
||||
extern bool objc_detect_field_duplicates (bool);
|
||||
extern void objc_start_class_interface (tree, tree, tree, tree);
|
||||
extern void objc_start_category_interface (tree, tree, tree, tree);
|
||||
extern void objc_start_protocol (tree, tree, tree);
|
||||
extern void objc_continue_interface (void);
|
||||
extern void objc_finish_interface (void);
|
||||
extern void objc_start_class_implementation (tree, tree);
|
||||
extern void objc_start_category_implementation (tree, tree);
|
||||
extern void objc_continue_implementation (void);
|
||||
extern void objc_finish_implementation (void);
|
||||
extern void objc_set_visibility (objc_ivar_visibility_kind);
|
||||
extern tree objc_build_method_signature (bool, tree, tree, tree, bool);
|
||||
extern void objc_add_method_declaration (bool, tree, tree);
|
||||
extern bool objc_start_method_definition (bool, tree, tree, tree);
|
||||
extern void objc_finish_method_definition (tree);
|
||||
extern void objc_add_instance_variable (tree);
|
||||
extern tree objc_build_keyword_decl (tree, tree, tree, tree);
|
||||
extern tree objc_build_throw_stmt (location_t, tree);
|
||||
extern void objc_begin_try_stmt (location_t, tree);
|
||||
extern tree objc_finish_try_stmt (void);
|
||||
extern void objc_begin_catch_clause (tree);
|
||||
extern void objc_finish_catch_clause (void);
|
||||
extern void objc_build_finally_clause (location_t, tree);
|
||||
extern tree objc_build_synchronized (location_t, tree, tree);
|
||||
extern int objc_static_init_needed_p (void);
|
||||
extern tree objc_generate_static_init_call (tree);
|
||||
extern tree objc_generate_write_barrier (tree, enum tree_code, tree);
|
||||
extern void objc_set_method_opt (bool);
|
||||
extern void objc_finish_foreach_loop (location_t, tree, tree, tree, tree, tree);
|
||||
extern bool objc_method_decl (enum tree_code);
|
||||
extern void objc_add_property_declaration (location_t, tree, bool, bool, bool,
|
||||
bool, bool, bool, tree, tree);
|
||||
extern tree objc_maybe_build_component_ref (tree, tree);
|
||||
extern tree objc_build_class_component_ref (tree, tree);
|
||||
extern tree objc_maybe_build_modify_expr (tree, tree);
|
||||
extern tree objc_build_incr_expr_for_property_ref (location_t, enum tree_code,
|
||||
tree, tree);
|
||||
extern void objc_add_synthesize_declaration (location_t, tree);
|
||||
extern void objc_add_dynamic_declaration (location_t, tree);
|
||||
extern const char * objc_maybe_printable_name (tree, int);
|
||||
extern bool objc_is_property_ref (tree);
|
||||
extern bool objc_string_ref_type_p (tree);
|
||||
extern void objc_check_format_arg (tree, tree);
|
||||
extern void objc_finish_function (void);
|
||||
extern void objc_maybe_warn_exceptions (location_t);
|
||||
|
||||
/* The following are provided by the C and C++ front-ends, and called by
|
||||
ObjC/ObjC++. */
|
||||
extern void *objc_get_current_scope (void);
|
||||
extern void objc_mark_locals_volatile (void *);
|
||||
|
||||
#endif /* ! GCC_C_COMMON_OBJC_H */
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* Pragma related interfaces.
|
||||
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_C_PRAGMA_H
|
||||
#define GCC_C_PRAGMA_H
|
||||
|
||||
#include "cpplib.h" /* For enum cpp_ttype. */
|
||||
|
||||
/* Pragma identifiers built in to the front end parsers. Identifiers
|
||||
for ancillary handlers will follow these. */
|
||||
typedef enum pragma_kind {
|
||||
PRAGMA_NONE = 0,
|
||||
|
||||
PRAGMA_OMP_ATOMIC,
|
||||
PRAGMA_OMP_BARRIER,
|
||||
PRAGMA_OMP_CRITICAL,
|
||||
PRAGMA_OMP_FLUSH,
|
||||
PRAGMA_OMP_FOR,
|
||||
PRAGMA_OMP_MASTER,
|
||||
PRAGMA_OMP_ORDERED,
|
||||
PRAGMA_OMP_PARALLEL,
|
||||
PRAGMA_OMP_PARALLEL_FOR,
|
||||
PRAGMA_OMP_PARALLEL_SECTIONS,
|
||||
PRAGMA_OMP_SECTION,
|
||||
PRAGMA_OMP_SECTIONS,
|
||||
PRAGMA_OMP_SINGLE,
|
||||
PRAGMA_OMP_TASK,
|
||||
PRAGMA_OMP_TASKWAIT,
|
||||
PRAGMA_OMP_TASKYIELD,
|
||||
PRAGMA_OMP_THREADPRIVATE,
|
||||
|
||||
PRAGMA_GCC_PCH_PREPROCESS,
|
||||
|
||||
PRAGMA_FIRST_EXTERNAL
|
||||
} pragma_kind;
|
||||
|
||||
|
||||
/* All clauses defined by OpenMP 2.5 and 3.0.
|
||||
Used internally by both C and C++ parsers. */
|
||||
typedef enum pragma_omp_clause {
|
||||
PRAGMA_OMP_CLAUSE_NONE = 0,
|
||||
|
||||
PRAGMA_OMP_CLAUSE_COLLAPSE,
|
||||
PRAGMA_OMP_CLAUSE_COPYIN,
|
||||
PRAGMA_OMP_CLAUSE_COPYPRIVATE,
|
||||
PRAGMA_OMP_CLAUSE_DEFAULT,
|
||||
PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
|
||||
PRAGMA_OMP_CLAUSE_IF,
|
||||
PRAGMA_OMP_CLAUSE_LASTPRIVATE,
|
||||
PRAGMA_OMP_CLAUSE_NOWAIT,
|
||||
PRAGMA_OMP_CLAUSE_NUM_THREADS,
|
||||
PRAGMA_OMP_CLAUSE_ORDERED,
|
||||
PRAGMA_OMP_CLAUSE_PRIVATE,
|
||||
PRAGMA_OMP_CLAUSE_REDUCTION,
|
||||
PRAGMA_OMP_CLAUSE_SCHEDULE,
|
||||
PRAGMA_OMP_CLAUSE_SHARED,
|
||||
PRAGMA_OMP_CLAUSE_UNTIED,
|
||||
PRAGMA_OMP_CLAUSE_FINAL,
|
||||
PRAGMA_OMP_CLAUSE_MERGEABLE
|
||||
} pragma_omp_clause;
|
||||
|
||||
extern struct cpp_reader* parse_in;
|
||||
|
||||
/* It's safe to always leave visibility pragma enabled as if
|
||||
visibility is not supported on the host OS platform the
|
||||
statements are ignored. */
|
||||
extern void push_visibility (const char *, int);
|
||||
extern bool pop_visibility (int);
|
||||
|
||||
extern void init_pragma (void);
|
||||
|
||||
/* Front-end wrappers for pragma registration. */
|
||||
typedef void (*pragma_handler_1arg)(struct cpp_reader *);
|
||||
/* A second pragma handler, which adds a void * argument allowing to pass extra
|
||||
data to the handler. */
|
||||
typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
|
||||
|
||||
/* This union allows to abstract the different handlers. */
|
||||
union gen_pragma_handler {
|
||||
pragma_handler_1arg handler_1arg;
|
||||
pragma_handler_2arg handler_2arg;
|
||||
};
|
||||
/* Internally used to keep the data of the handler. */
|
||||
struct internal_pragma_handler_d {
|
||||
union gen_pragma_handler handler;
|
||||
/* Permits to know if handler is a pragma_handler_1arg (extra_data is false)
|
||||
or a pragma_handler_2arg (extra_data is true). */
|
||||
bool extra_data;
|
||||
/* A data field which can be used when extra_data is true. */
|
||||
void * data;
|
||||
};
|
||||
typedef struct internal_pragma_handler_d internal_pragma_handler;
|
||||
|
||||
extern void c_register_pragma (const char *space, const char *name,
|
||||
pragma_handler_1arg handler);
|
||||
extern void c_register_pragma_with_data (const char *space, const char *name,
|
||||
pragma_handler_2arg handler,
|
||||
void *data);
|
||||
|
||||
extern void c_register_pragma_with_expansion (const char *space,
|
||||
const char *name,
|
||||
pragma_handler_1arg handler);
|
||||
extern void c_register_pragma_with_expansion_and_data (const char *space,
|
||||
const char *name,
|
||||
pragma_handler_2arg handler,
|
||||
void *data);
|
||||
extern void c_invoke_pragma_handler (unsigned int);
|
||||
|
||||
extern void maybe_apply_pragma_weak (tree);
|
||||
extern void maybe_apply_pending_pragma_weaks (void);
|
||||
extern tree maybe_apply_renaming_pragma (tree, tree);
|
||||
extern void add_to_renaming_pragma_list (tree, tree);
|
||||
|
||||
extern enum cpp_ttype pragma_lex (tree *);
|
||||
|
||||
/* Flags for use with c_lex_with_flags. The values here were picked
|
||||
so that 0 means to translate and join strings. */
|
||||
#define C_LEX_STRING_NO_TRANSLATE 1 /* Do not lex strings into
|
||||
execution character set. */
|
||||
#define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings
|
||||
nor translate them into execution
|
||||
character set. */
|
||||
|
||||
/* This is not actually available to pragma parsers. It's merely a
|
||||
convenient location to declare this function for c-lex, after
|
||||
having enum cpp_ttype declared. */
|
||||
extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *,
|
||||
int);
|
||||
|
||||
extern void c_pp_lookup_pragma (unsigned int, const char **, const char **);
|
||||
|
||||
extern GTY(()) tree pragma_extern_prefix;
|
||||
|
||||
#endif /* GCC_C_PRAGMA_H */
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
/* Various declarations for the C and C++ pretty-printers.
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_C_PRETTY_PRINTER
|
||||
#define GCC_C_PRETTY_PRINTER
|
||||
|
||||
#include "tree.h"
|
||||
#include "c-family/c-common.h"
|
||||
#include "pretty-print.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
pp_c_flag_abstract = 1 << 1,
|
||||
pp_c_flag_gnu_v3 = 1 << 2,
|
||||
pp_c_flag_last_bit = 3
|
||||
} pp_c_pretty_print_flags;
|
||||
|
||||
|
||||
/* The data type used to bundle information necessary for pretty-printing
|
||||
a C or C++ entity. */
|
||||
typedef struct c_pretty_print_info c_pretty_printer;
|
||||
|
||||
/* The type of a C pretty-printer 'member' function. */
|
||||
typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
|
||||
|
||||
/* The datatype that contains information necessary for pretty-printing
|
||||
a tree that represents a C construct. Any pretty-printer for a
|
||||
language using C/c++ syntax can derive from this datatype and reuse
|
||||
facilities provided here. It can do so by having a subobject of type
|
||||
c_pretty_printer and override the macro pp_c_base to return a pointer
|
||||
to that subobject. Such a pretty-printer has the responsibility to
|
||||
initialize the pp_base() part, then call pp_c_pretty_printer_init
|
||||
to set up the components that are specific to the C pretty-printer.
|
||||
A derived pretty-printer can override any function listed in the
|
||||
vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c
|
||||
for an example of derivation. */
|
||||
struct c_pretty_print_info
|
||||
{
|
||||
pretty_printer base;
|
||||
/* Points to the first element of an array of offset-list.
|
||||
Not used yet. */
|
||||
int *offset_list;
|
||||
|
||||
pp_flags flags;
|
||||
|
||||
/* These must be overridden by each of the C and C++ front-end to
|
||||
reflect their understanding of syntactic productions when they differ. */
|
||||
c_pretty_print_fn declaration;
|
||||
c_pretty_print_fn declaration_specifiers;
|
||||
c_pretty_print_fn declarator;
|
||||
c_pretty_print_fn abstract_declarator;
|
||||
c_pretty_print_fn direct_abstract_declarator;
|
||||
c_pretty_print_fn type_specifier_seq;
|
||||
c_pretty_print_fn direct_declarator;
|
||||
c_pretty_print_fn ptr_operator;
|
||||
c_pretty_print_fn parameter_list;
|
||||
c_pretty_print_fn type_id;
|
||||
c_pretty_print_fn simple_type_specifier;
|
||||
c_pretty_print_fn function_specifier;
|
||||
c_pretty_print_fn storage_class_specifier;
|
||||
c_pretty_print_fn initializer;
|
||||
|
||||
c_pretty_print_fn statement;
|
||||
|
||||
c_pretty_print_fn constant;
|
||||
c_pretty_print_fn id_expression;
|
||||
c_pretty_print_fn primary_expression;
|
||||
c_pretty_print_fn postfix_expression;
|
||||
c_pretty_print_fn unary_expression;
|
||||
c_pretty_print_fn multiplicative_expression;
|
||||
c_pretty_print_fn conditional_expression;
|
||||
c_pretty_print_fn assignment_expression;
|
||||
c_pretty_print_fn expression;
|
||||
};
|
||||
|
||||
/* Override the pp_base macro. Derived pretty-printers should not
|
||||
touch this macro. Instead they should override pp_c_base instead. */
|
||||
#undef pp_base
|
||||
#define pp_base(PP) (&pp_c_base (PP)->base)
|
||||
|
||||
|
||||
#define pp_c_tree_identifier(PPI, ID) \
|
||||
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
|
||||
|
||||
#define pp_declaration(PPI, T) \
|
||||
pp_c_base (PPI)->declaration (pp_c_base (PPI), T)
|
||||
#define pp_declaration_specifiers(PPI, D) \
|
||||
pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D)
|
||||
#define pp_abstract_declarator(PP, D) \
|
||||
pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D)
|
||||
#define pp_type_specifier_seq(PPI, D) \
|
||||
pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D)
|
||||
#define pp_declarator(PPI, D) \
|
||||
pp_c_base (PPI)->declarator (pp_c_base (PPI), D)
|
||||
#define pp_direct_declarator(PPI, D) \
|
||||
pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D)
|
||||
#define pp_direct_abstract_declarator(PP, D) \
|
||||
pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D)
|
||||
#define pp_ptr_operator(PP, D) \
|
||||
pp_c_base (PP)->ptr_operator (pp_c_base (PP), D)
|
||||
#define pp_parameter_list(PPI, T) \
|
||||
pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T)
|
||||
#define pp_type_id(PPI, D) \
|
||||
pp_c_base (PPI)->type_id (pp_c_base (PPI), D)
|
||||
#define pp_simple_type_specifier(PP, T) \
|
||||
pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T)
|
||||
#define pp_function_specifier(PP, D) \
|
||||
pp_c_base (PP)->function_specifier (pp_c_base (PP), D)
|
||||
#define pp_storage_class_specifier(PP, D) \
|
||||
pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D);
|
||||
|
||||
#define pp_statement(PPI, S) \
|
||||
pp_c_base (PPI)->statement (pp_c_base (PPI), S)
|
||||
|
||||
#define pp_constant(PP, E) \
|
||||
pp_c_base (PP)->constant (pp_c_base (PP), E)
|
||||
#define pp_id_expression(PP, E) \
|
||||
pp_c_base (PP)->id_expression (pp_c_base (PP), E)
|
||||
#define pp_primary_expression(PPI, E) \
|
||||
pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E)
|
||||
#define pp_postfix_expression(PPI, E) \
|
||||
pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E)
|
||||
#define pp_unary_expression(PPI, E) \
|
||||
pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E)
|
||||
#define pp_initializer(PPI, E) \
|
||||
pp_c_base (PPI)->initializer (pp_c_base (PPI), E)
|
||||
#define pp_multiplicative_expression(PPI, E) \
|
||||
pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E)
|
||||
#define pp_conditional_expression(PPI, E) \
|
||||
pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E)
|
||||
#define pp_assignment_expression(PPI, E) \
|
||||
pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E)
|
||||
#define pp_expression(PP, E) \
|
||||
pp_c_base (PP)->expression (pp_c_base (PP), E)
|
||||
|
||||
|
||||
/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
|
||||
macro must be overridden by any subclass of c_pretty_print_info. */
|
||||
#define pp_c_base(PP) (PP)
|
||||
|
||||
extern void pp_c_pretty_printer_init (c_pretty_printer *);
|
||||
void pp_c_whitespace (c_pretty_printer *);
|
||||
void pp_c_left_paren (c_pretty_printer *);
|
||||
void pp_c_right_paren (c_pretty_printer *);
|
||||
void pp_c_left_brace (c_pretty_printer *);
|
||||
void pp_c_right_brace (c_pretty_printer *);
|
||||
void pp_c_left_bracket (c_pretty_printer *);
|
||||
void pp_c_right_bracket (c_pretty_printer *);
|
||||
void pp_c_dot (c_pretty_printer *);
|
||||
void pp_c_ampersand (c_pretty_printer *);
|
||||
void pp_c_star (c_pretty_printer *);
|
||||
void pp_c_arrow (c_pretty_printer *);
|
||||
void pp_c_semicolon (c_pretty_printer *);
|
||||
void pp_c_complement (c_pretty_printer *);
|
||||
void pp_c_exclamation (c_pretty_printer *);
|
||||
void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
|
||||
|
||||
/* Declarations. */
|
||||
void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
|
||||
void pp_c_function_definition (c_pretty_printer *, tree);
|
||||
void pp_c_attributes (c_pretty_printer *, tree);
|
||||
void pp_c_attributes_display (c_pretty_printer *, tree);
|
||||
void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type);
|
||||
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
|
||||
void pp_c_parameter_type_list (c_pretty_printer *, tree);
|
||||
void pp_c_declaration (c_pretty_printer *, tree);
|
||||
void pp_c_declaration_specifiers (c_pretty_printer *, tree);
|
||||
void pp_c_declarator (c_pretty_printer *, tree);
|
||||
void pp_c_direct_declarator (c_pretty_printer *, tree);
|
||||
void pp_c_specifier_qualifier_list (c_pretty_printer *, tree);
|
||||
void pp_c_function_specifier (c_pretty_printer *, tree);
|
||||
void pp_c_type_id (c_pretty_printer *, tree);
|
||||
void pp_c_direct_abstract_declarator (c_pretty_printer *, tree);
|
||||
void pp_c_type_specifier (c_pretty_printer *, tree);
|
||||
void pp_c_storage_class_specifier (c_pretty_printer *, tree);
|
||||
/* Statements. */
|
||||
void pp_c_statement (c_pretty_printer *, tree);
|
||||
/* Expressions. */
|
||||
void pp_c_expression (c_pretty_printer *, tree);
|
||||
void pp_c_logical_or_expression (c_pretty_printer *, tree);
|
||||
void pp_c_expression_list (c_pretty_printer *, tree);
|
||||
void pp_c_constructor_elts (c_pretty_printer *, vec<constructor_elt, va_gc> *);
|
||||
void pp_c_call_argument_list (c_pretty_printer *, tree);
|
||||
void pp_c_unary_expression (c_pretty_printer *, tree);
|
||||
void pp_c_cast_expression (c_pretty_printer *, tree);
|
||||
void pp_c_postfix_expression (c_pretty_printer *, tree);
|
||||
void pp_c_primary_expression (c_pretty_printer *, tree);
|
||||
void pp_c_init_declarator (c_pretty_printer *, tree);
|
||||
void pp_c_constant (c_pretty_printer *, tree);
|
||||
void pp_c_id_expression (c_pretty_printer *, tree);
|
||||
void pp_c_ws_string (c_pretty_printer *, const char *);
|
||||
void pp_c_identifier (c_pretty_printer *, const char *);
|
||||
void pp_c_string_literal (c_pretty_printer *, tree);
|
||||
|
||||
void print_c_tree (FILE *file, tree t);
|
||||
|
||||
#endif /* GCC_C_PRETTY_PRINTER */
|
||||
|
|
@ -0,0 +1,671 @@
|
|||
/* Definitions for C parsing and type checking.
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_C_TREE_H
|
||||
#define GCC_C_TREE_H
|
||||
|
||||
#include "c-family/c-common.h"
|
||||
#include "diagnostic.h"
|
||||
|
||||
/* struct lang_identifier is private to c-decl.c, but langhooks.c needs to
|
||||
know how big it is. This is sanity-checked in c-decl.c. */
|
||||
#define C_SIZEOF_STRUCT_LANG_IDENTIFIER \
|
||||
(sizeof (struct c_common_identifier) + 3 * sizeof (void *))
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
|
||||
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1 (TYPE)
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */
|
||||
#define C_TYPE_FIELDS_VOLATILE(TYPE) TREE_LANG_FLAG_2 (TYPE)
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE
|
||||
nonzero if the definition of the type has already started. */
|
||||
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
|
||||
|
||||
/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
|
||||
declarations whose type would be completed by completing that type. */
|
||||
#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
|
||||
|
||||
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
|
||||
keyword. C_RID_CODE (node) is then the RID_* value of the keyword,
|
||||
and C_RID_YYCODE is the token number wanted by Yacc. */
|
||||
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID)
|
||||
|
||||
/* Record whether a type or decl was written with nonconstant size.
|
||||
Note that TYPE_SIZE may have simplified to a constant. */
|
||||
#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
|
||||
#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
|
||||
|
||||
/* Record whether a type is defined inside a struct or union type.
|
||||
This is used for -Wc++-compat. */
|
||||
#define C_TYPE_DEFINED_IN_STRUCT(TYPE) TYPE_LANG_FLAG_2 (TYPE)
|
||||
|
||||
/* Record whether a typedef for type `int' was actually `signed int'. */
|
||||
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||
|
||||
/* For a FUNCTION_DECL, nonzero if it was defined without an explicit
|
||||
return type. */
|
||||
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||
|
||||
/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */
|
||||
#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
|
||||
|
||||
/* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
|
||||
been declared. */
|
||||
#define C_DECL_DECLARED_BUILTIN(EXP) \
|
||||
DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (EXP))
|
||||
|
||||
/* For FUNCTION_DECLs, evaluates true if the decl is built-in, has a
|
||||
built-in prototype and does not have a non-built-in prototype. */
|
||||
#define C_DECL_BUILTIN_PROTOTYPE(EXP) \
|
||||
DECL_LANG_FLAG_6 (FUNCTION_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a decl was declared register. This is strictly a
|
||||
front-end flag, whereas DECL_REGISTER is used for code generation;
|
||||
they may differ for structures with volatile fields. */
|
||||
#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4 (EXP)
|
||||
|
||||
/* Record whether a decl was used in an expression anywhere except an
|
||||
unevaluated operand of sizeof / typeof / alignof. This is only
|
||||
used for functions declared static but not defined, though outside
|
||||
sizeof and typeof it is set for other function decls as well. */
|
||||
#define C_DECL_USED(EXP) DECL_LANG_FLAG_5 (FUNCTION_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a variable has been declared threadprivate by
|
||||
#pragma omp threadprivate. */
|
||||
#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
|
||||
|
||||
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
|
||||
N.B. Could be simplified if all built-in decls had complete prototypes
|
||||
(but this is presently difficult because some of them need FILE*). */
|
||||
#define C_DECL_ISNT_PROTOTYPE(EXP) \
|
||||
(EXP == 0 \
|
||||
|| (!prototype_p (TREE_TYPE (EXP)) \
|
||||
&& !DECL_BUILT_IN (EXP)))
|
||||
|
||||
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
|
||||
TYPE_ARG_TYPES for functions with prototypes, but created for functions
|
||||
without prototypes. */
|
||||
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE)
|
||||
|
||||
/* For a CONSTRUCTOR, whether some initializer contains a
|
||||
subexpression meaning it is not a constant expression. */
|
||||
#define CONSTRUCTOR_NON_CONST(EXPR) TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (EXPR))
|
||||
|
||||
/* Record parser information about an expression that is irrelevant
|
||||
for code generation alongside a tree representing its value. */
|
||||
struct c_expr
|
||||
{
|
||||
/* The value of the expression. */
|
||||
tree value;
|
||||
/* Record the original unary/binary operator of an expression, which may
|
||||
have been changed by fold, STRING_CST for unparenthesized string
|
||||
constants, C_MAYBE_CONST_EXPR for __builtin_constant_p calls
|
||||
(even if parenthesized), for subexpressions, and for non-constant
|
||||
initializers, or ERROR_MARK for other expressions (including
|
||||
parenthesized expressions). */
|
||||
enum tree_code original_code;
|
||||
/* If not NULL, the original type of an expression. This will
|
||||
differ from the type of the value field for an enum constant.
|
||||
The type of an enum constant is a plain integer type, but this
|
||||
field will be the enum type. */
|
||||
tree original_type;
|
||||
};
|
||||
|
||||
/* Type alias for struct c_expr. This allows to use the structure
|
||||
inside the VEC types. */
|
||||
typedef struct c_expr c_expr_t;
|
||||
|
||||
/* A varray of c_expr_t. */
|
||||
|
||||
/* Append a new c_expr_t element to V. */
|
||||
#define C_EXPR_APPEND(V, ELEM) \
|
||||
do { \
|
||||
c_expr_t __elem = (ELEM); \
|
||||
vec_safe_push (V, __elem); \
|
||||
} while (0)
|
||||
|
||||
/* A kind of type specifier. Note that this information is currently
|
||||
only used to distinguish tag definitions, tag references and typeof
|
||||
uses. */
|
||||
enum c_typespec_kind {
|
||||
/* No typespec. This appears only in struct c_declspec. */
|
||||
ctsk_none,
|
||||
/* A reserved keyword type specifier. */
|
||||
ctsk_resword,
|
||||
/* A reference to a tag, previously declared, such as "struct foo".
|
||||
This includes where the previous declaration was as a different
|
||||
kind of tag, in which case this is only valid if shadowing that
|
||||
tag in an inner scope. */
|
||||
ctsk_tagref,
|
||||
/* A reference to a tag, not previously declared in a visible
|
||||
scope. */
|
||||
ctsk_tagfirstref,
|
||||
/* A definition of a tag such as "struct foo { int a; }". */
|
||||
ctsk_tagdef,
|
||||
/* A typedef name. */
|
||||
ctsk_typedef,
|
||||
/* An ObjC-specific kind of type specifier. */
|
||||
ctsk_objc,
|
||||
/* A typeof specifier. */
|
||||
ctsk_typeof
|
||||
};
|
||||
|
||||
/* A type specifier: this structure is created in the parser and
|
||||
passed to declspecs_add_type only. */
|
||||
struct c_typespec {
|
||||
/* What kind of type specifier this is. */
|
||||
enum c_typespec_kind kind;
|
||||
/* Whether the expression has operands suitable for use in constant
|
||||
expressions. */
|
||||
bool expr_const_operands;
|
||||
/* The specifier itself. */
|
||||
tree spec;
|
||||
/* An expression to be evaluated before the type specifier, in the
|
||||
case of typeof specifiers, or NULL otherwise or if no such
|
||||
expression is required for a particular typeof specifier. In
|
||||
particular, when typeof is applied to an expression of variably
|
||||
modified type, that expression must be evaluated in order to
|
||||
determine array sizes that form part of the type, but the
|
||||
expression itself (as opposed to the array sizes) forms no part
|
||||
of the type and so needs to be recorded separately. */
|
||||
tree expr;
|
||||
};
|
||||
|
||||
/* A storage class specifier. */
|
||||
enum c_storage_class {
|
||||
csc_none,
|
||||
csc_auto,
|
||||
csc_extern,
|
||||
csc_register,
|
||||
csc_static,
|
||||
csc_typedef
|
||||
};
|
||||
|
||||
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
|
||||
"double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
|
||||
or none of these. */
|
||||
enum c_typespec_keyword {
|
||||
cts_none,
|
||||
cts_void,
|
||||
cts_bool,
|
||||
cts_char,
|
||||
cts_int,
|
||||
cts_float,
|
||||
cts_int128,
|
||||
cts_double,
|
||||
cts_dfloat32,
|
||||
cts_dfloat64,
|
||||
cts_dfloat128,
|
||||
cts_fract,
|
||||
cts_accum
|
||||
};
|
||||
|
||||
/* This enum lists all the possible declarator specifiers, storage
|
||||
class or attribute that a user can write. There is at least one
|
||||
enumerator per possible declarator specifier in the struct
|
||||
c_declspecs below.
|
||||
|
||||
It is used to index the array of declspec locations in struct
|
||||
c_declspecs. */
|
||||
enum c_declspec_word {
|
||||
cdw_typespec /* A catch-all for a typespec. */,
|
||||
cdw_storage_class /* A catch-all for a storage class */,
|
||||
cdw_attributes,
|
||||
cdw_typedef,
|
||||
cdw_explicit_signed,
|
||||
cdw_deprecated,
|
||||
cdw_default_int,
|
||||
cdw_long,
|
||||
cdw_long_long,
|
||||
cdw_short,
|
||||
cdw_signed,
|
||||
cdw_unsigned,
|
||||
cdw_complex,
|
||||
cdw_inline,
|
||||
cdw_noreturn,
|
||||
cdw_thread,
|
||||
cdw_const,
|
||||
cdw_volatile,
|
||||
cdw_restrict,
|
||||
cdw_saturating,
|
||||
cdw_alignas,
|
||||
cdw_address_space,
|
||||
cdw_number_of_elements /* This one must always be the last
|
||||
enumerator. */
|
||||
};
|
||||
|
||||
/* A sequence of declaration specifiers in C. When a new declaration
|
||||
specifier is added, please update the enum c_declspec_word above
|
||||
accordingly. */
|
||||
struct c_declspecs {
|
||||
source_location locations[cdw_number_of_elements];
|
||||
/* The type specified, if a single type specifier such as a struct,
|
||||
union or enum specifier, typedef name or typeof specifies the
|
||||
whole type, or NULL_TREE if none or a keyword such as "void" or
|
||||
"char" is used. Does not include qualifiers. */
|
||||
tree type;
|
||||
/* Any expression to be evaluated before the type, from a typeof
|
||||
specifier. */
|
||||
tree expr;
|
||||
/* The attributes from a typedef decl. */
|
||||
tree decl_attr;
|
||||
/* When parsing, the attributes. Outside the parser, this will be
|
||||
NULL; attributes (possibly from multiple lists) will be passed
|
||||
separately. */
|
||||
tree attrs;
|
||||
/* The base-2 log of the greatest alignment required by an _Alignas
|
||||
specifier, in bytes, or -1 if no such specifiers with nonzero
|
||||
alignment. */
|
||||
int align_log;
|
||||
/* The storage class specifier, or csc_none if none. */
|
||||
enum c_storage_class storage_class;
|
||||
/* Any type specifier keyword used such as "int", not reflecting
|
||||
modifiers such as "short", or cts_none if none. */
|
||||
ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8;
|
||||
/* The kind of type specifier if one has been seen, ctsk_none
|
||||
otherwise. */
|
||||
ENUM_BITFIELD (c_typespec_kind) typespec_kind : 3;
|
||||
/* Whether any expressions in typeof specifiers may appear in
|
||||
constant expressions. */
|
||||
BOOL_BITFIELD expr_const_operands : 1;
|
||||
/* Whether any declaration specifiers have been seen at all. */
|
||||
BOOL_BITFIELD declspecs_seen_p : 1;
|
||||
/* Whether something other than a storage class specifier or
|
||||
attribute has been seen. This is used to warn for the
|
||||
obsolescent usage of storage class specifiers other than at the
|
||||
start of the list. (Doing this properly would require function
|
||||
specifiers to be handled separately from storage class
|
||||
specifiers.) */
|
||||
BOOL_BITFIELD non_sc_seen_p : 1;
|
||||
/* Whether the type is specified by a typedef or typeof name. */
|
||||
BOOL_BITFIELD typedef_p : 1;
|
||||
/* Whether the type is explicitly "signed" or specified by a typedef
|
||||
whose type is explicitly "signed". */
|
||||
BOOL_BITFIELD explicit_signed_p : 1;
|
||||
/* Whether the specifiers include a deprecated typedef. */
|
||||
BOOL_BITFIELD deprecated_p : 1;
|
||||
/* Whether the type defaulted to "int" because there were no type
|
||||
specifiers. */
|
||||
BOOL_BITFIELD default_int_p : 1;
|
||||
/* Whether "long" was specified. */
|
||||
BOOL_BITFIELD long_p : 1;
|
||||
/* Whether "long" was specified more than once. */
|
||||
BOOL_BITFIELD long_long_p : 1;
|
||||
/* Whether "short" was specified. */
|
||||
BOOL_BITFIELD short_p : 1;
|
||||
/* Whether "signed" was specified. */
|
||||
BOOL_BITFIELD signed_p : 1;
|
||||
/* Whether "unsigned" was specified. */
|
||||
BOOL_BITFIELD unsigned_p : 1;
|
||||
/* Whether "complex" was specified. */
|
||||
BOOL_BITFIELD complex_p : 1;
|
||||
/* Whether "inline" was specified. */
|
||||
BOOL_BITFIELD inline_p : 1;
|
||||
/* Whether "_Noreturn" was speciied. */
|
||||
BOOL_BITFIELD noreturn_p : 1;
|
||||
/* Whether "__thread" was specified. */
|
||||
BOOL_BITFIELD thread_p : 1;
|
||||
/* Whether "const" was specified. */
|
||||
BOOL_BITFIELD const_p : 1;
|
||||
/* Whether "volatile" was specified. */
|
||||
BOOL_BITFIELD volatile_p : 1;
|
||||
/* Whether "restrict" was specified. */
|
||||
BOOL_BITFIELD restrict_p : 1;
|
||||
/* Whether "_Sat" was specified. */
|
||||
BOOL_BITFIELD saturating_p : 1;
|
||||
/* Whether any alignment specifier (even with zero alignment) was
|
||||
specified. */
|
||||
BOOL_BITFIELD alignas_p : 1;
|
||||
/* The address space that the declaration belongs to. */
|
||||
addr_space_t address_space;
|
||||
};
|
||||
|
||||
/* The various kinds of declarators in C. */
|
||||
enum c_declarator_kind {
|
||||
/* An identifier. */
|
||||
cdk_id,
|
||||
/* A function. */
|
||||
cdk_function,
|
||||
/* An array. */
|
||||
cdk_array,
|
||||
/* A pointer. */
|
||||
cdk_pointer,
|
||||
/* Parenthesized declarator with nested attributes. */
|
||||
cdk_attrs
|
||||
};
|
||||
|
||||
typedef struct c_arg_tag_d {
|
||||
/* The argument name. */
|
||||
tree id;
|
||||
/* The type of the argument. */
|
||||
tree type;
|
||||
} c_arg_tag;
|
||||
|
||||
|
||||
/* Information about the parameters in a function declarator. */
|
||||
struct c_arg_info {
|
||||
/* A list of parameter decls. */
|
||||
tree parms;
|
||||
/* A list of structure, union and enum tags defined. */
|
||||
vec<c_arg_tag, va_gc> *tags;
|
||||
/* A list of argument types to go in the FUNCTION_TYPE. */
|
||||
tree types;
|
||||
/* A list of non-parameter decls (notably enumeration constants)
|
||||
defined with the parameters. */
|
||||
tree others;
|
||||
/* A compound expression of VLA sizes from the parameters, or NULL.
|
||||
In a function definition, these are used to ensure that
|
||||
side-effects in sizes of arrays converted to pointers (such as a
|
||||
parameter int i[n++]) take place; otherwise, they are
|
||||
ignored. */
|
||||
tree pending_sizes;
|
||||
/* True when these arguments had [*]. */
|
||||
BOOL_BITFIELD had_vla_unspec : 1;
|
||||
};
|
||||
|
||||
/* A declarator. */
|
||||
struct c_declarator {
|
||||
/* The kind of declarator. */
|
||||
enum c_declarator_kind kind;
|
||||
location_t id_loc; /* Currently only set for cdk_id, cdk_array. */
|
||||
/* Except for cdk_id, the contained declarator. For cdk_id, NULL. */
|
||||
struct c_declarator *declarator;
|
||||
union {
|
||||
/* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
|
||||
declarator. */
|
||||
tree id;
|
||||
/* For functions. */
|
||||
struct c_arg_info *arg_info;
|
||||
/* For arrays. */
|
||||
struct {
|
||||
/* The array dimension, or NULL for [] and [*]. */
|
||||
tree dimen;
|
||||
/* The qualifiers inside []. */
|
||||
int quals;
|
||||
/* The attributes (currently ignored) inside []. */
|
||||
tree attrs;
|
||||
/* Whether [static] was used. */
|
||||
BOOL_BITFIELD static_p : 1;
|
||||
/* Whether [*] was used. */
|
||||
BOOL_BITFIELD vla_unspec_p : 1;
|
||||
} array;
|
||||
/* For pointers, the qualifiers on the pointer type. */
|
||||
int pointer_quals;
|
||||
/* For attributes. */
|
||||
tree attrs;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* A type name. */
|
||||
struct c_type_name {
|
||||
/* The declaration specifiers. */
|
||||
struct c_declspecs *specs;
|
||||
/* The declarator. */
|
||||
struct c_declarator *declarator;
|
||||
};
|
||||
|
||||
/* A parameter. */
|
||||
struct c_parm {
|
||||
/* The declaration specifiers, minus any prefix attributes. */
|
||||
struct c_declspecs *specs;
|
||||
/* The attributes. */
|
||||
tree attrs;
|
||||
/* The declarator. */
|
||||
struct c_declarator *declarator;
|
||||
};
|
||||
|
||||
/* Used when parsing an enum. Initialized by start_enum. */
|
||||
struct c_enum_contents
|
||||
{
|
||||
/* While defining an enum type, this is 1 plus the last enumerator
|
||||
constant value. */
|
||||
tree enum_next_value;
|
||||
|
||||
/* Nonzero means that there was overflow computing enum_next_value. */
|
||||
int enum_overflow;
|
||||
};
|
||||
|
||||
/* A type of reference to a static identifier in an inline
|
||||
function. */
|
||||
enum c_inline_static_type {
|
||||
/* Identifier with internal linkage used in function that may be an
|
||||
inline definition (i.e., file-scope static). */
|
||||
csi_internal,
|
||||
/* Modifiable object with static storage duration defined in
|
||||
function that may be an inline definition (i.e., local
|
||||
static). */
|
||||
csi_modifiable
|
||||
};
|
||||
|
||||
|
||||
/* in c-parser.c */
|
||||
extern void c_parse_init (void);
|
||||
|
||||
/* in c-aux-info.c */
|
||||
extern void gen_aux_info_record (tree, int, int, int);
|
||||
|
||||
/* in c-decl.c */
|
||||
struct c_spot_bindings;
|
||||
struct c_struct_parse_info;
|
||||
extern struct obstack parser_obstack;
|
||||
extern tree c_break_label;
|
||||
extern tree c_cont_label;
|
||||
|
||||
extern bool global_bindings_p (void);
|
||||
extern void push_scope (void);
|
||||
extern tree pop_scope (void);
|
||||
extern void c_bindings_start_stmt_expr (struct c_spot_bindings *);
|
||||
extern void c_bindings_end_stmt_expr (struct c_spot_bindings *);
|
||||
|
||||
extern void record_inline_static (location_t, tree, tree,
|
||||
enum c_inline_static_type);
|
||||
extern void c_init_decl_processing (void);
|
||||
extern void c_print_identifier (FILE *, tree, int);
|
||||
extern int quals_from_declspecs (const struct c_declspecs *);
|
||||
extern struct c_declarator *build_array_declarator (location_t, tree,
|
||||
struct c_declspecs *,
|
||||
bool, bool);
|
||||
extern tree build_enumerator (location_t, location_t, struct c_enum_contents *,
|
||||
tree, tree);
|
||||
extern tree check_for_loop_decls (location_t, bool);
|
||||
extern void mark_forward_parm_decls (void);
|
||||
extern void declare_parm_level (void);
|
||||
extern void undeclared_variable (location_t, tree);
|
||||
extern tree lookup_label_for_goto (location_t, tree);
|
||||
extern tree declare_label (tree);
|
||||
extern tree define_label (location_t, tree);
|
||||
extern struct c_spot_bindings *c_get_switch_bindings (void);
|
||||
extern void c_release_switch_bindings (struct c_spot_bindings *);
|
||||
extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
|
||||
location_t, location_t);
|
||||
extern void finish_decl (tree, location_t, tree, tree, tree);
|
||||
extern tree finish_enum (tree, tree, tree);
|
||||
extern void finish_function (void);
|
||||
extern tree finish_struct (location_t, tree, tree, tree,
|
||||
struct c_struct_parse_info *);
|
||||
extern struct c_arg_info *build_arg_info (void);
|
||||
extern struct c_arg_info *get_parm_info (bool, tree);
|
||||
extern tree grokfield (location_t, struct c_declarator *,
|
||||
struct c_declspecs *, tree, tree *);
|
||||
extern tree groktypename (struct c_type_name *, tree *, bool *);
|
||||
extern tree grokparm (const struct c_parm *, tree *);
|
||||
extern tree implicitly_declare (location_t, tree);
|
||||
extern void keep_next_level (void);
|
||||
extern void pending_xref_error (void);
|
||||
extern void c_push_function_context (void);
|
||||
extern void c_pop_function_context (void);
|
||||
extern void push_parm_decl (const struct c_parm *, tree *);
|
||||
extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
|
||||
struct c_declarator *);
|
||||
extern tree c_builtin_function (tree);
|
||||
extern tree c_builtin_function_ext_scope (tree);
|
||||
extern void shadow_tag (const struct c_declspecs *);
|
||||
extern void shadow_tag_warned (const struct c_declspecs *, int);
|
||||
extern tree start_enum (location_t, struct c_enum_contents *, tree);
|
||||
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
|
||||
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
|
||||
tree);
|
||||
extern tree start_struct (location_t, enum tree_code, tree,
|
||||
struct c_struct_parse_info **);
|
||||
extern void store_parm_decls (void);
|
||||
extern void store_parm_decls_from (struct c_arg_info *);
|
||||
extern tree xref_tag (enum tree_code, tree);
|
||||
extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
|
||||
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
|
||||
struct c_declarator *);
|
||||
extern struct c_declarator *build_attrs_declarator (tree,
|
||||
struct c_declarator *);
|
||||
extern struct c_declarator *build_function_declarator (struct c_arg_info *,
|
||||
struct c_declarator *);
|
||||
extern struct c_declarator *build_id_declarator (tree);
|
||||
extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
|
||||
struct c_declarator *);
|
||||
extern struct c_declspecs *build_null_declspecs (void);
|
||||
extern struct c_declspecs *declspecs_add_qual (source_location,
|
||||
struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *declspecs_add_type (location_t,
|
||||
struct c_declspecs *,
|
||||
struct c_typespec);
|
||||
extern struct c_declspecs *declspecs_add_scspec (source_location,
|
||||
struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *declspecs_add_attrs (source_location,
|
||||
struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *declspecs_add_addrspace (source_location,
|
||||
struct c_declspecs *,
|
||||
addr_space_t);
|
||||
extern struct c_declspecs *declspecs_add_alignas (source_location,
|
||||
struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
|
||||
|
||||
/* in c-objc-common.c */
|
||||
extern bool c_objc_common_init (void);
|
||||
extern bool c_missing_noreturn_ok_p (tree);
|
||||
extern bool c_warn_unused_global_decl (const_tree);
|
||||
extern void c_initialize_diagnostics (diagnostic_context *);
|
||||
extern bool c_vla_unspec_p (tree x, tree fn);
|
||||
|
||||
/* in c-typeck.c */
|
||||
extern int in_alignof;
|
||||
extern int in_sizeof;
|
||||
extern int in_typeof;
|
||||
|
||||
extern tree c_last_sizeof_arg;
|
||||
|
||||
extern struct c_switch *c_switch_stack;
|
||||
|
||||
extern tree c_objc_common_truthvalue_conversion (location_t, tree);
|
||||
extern tree require_complete_type (tree);
|
||||
extern int same_translation_unit_p (const_tree, const_tree);
|
||||
extern int comptypes (tree, tree);
|
||||
extern int comptypes_check_different_types (tree, tree, bool *);
|
||||
extern bool c_vla_type_p (const_tree);
|
||||
extern bool c_mark_addressable (tree);
|
||||
extern void c_incomplete_type_error (const_tree, const_tree);
|
||||
extern tree c_type_promotes_to (tree);
|
||||
extern struct c_expr default_function_array_conversion (location_t,
|
||||
struct c_expr);
|
||||
extern struct c_expr default_function_array_read_conversion (location_t,
|
||||
struct c_expr);
|
||||
extern void mark_exp_read (tree);
|
||||
extern tree composite_type (tree, tree);
|
||||
extern tree build_component_ref (location_t, tree, tree);
|
||||
extern tree build_array_ref (location_t, tree, tree);
|
||||
extern tree build_external_ref (location_t, tree, int, tree *);
|
||||
extern void pop_maybe_used (bool);
|
||||
extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr);
|
||||
extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *);
|
||||
extern struct c_expr parser_build_unary_op (location_t, enum tree_code,
|
||||
struct c_expr);
|
||||
extern struct c_expr parser_build_binary_op (location_t,
|
||||
enum tree_code, struct c_expr,
|
||||
struct c_expr);
|
||||
extern tree build_conditional_expr (location_t, tree, bool, tree, tree,
|
||||
tree, tree);
|
||||
extern tree build_compound_expr (location_t, tree, tree);
|
||||
extern tree c_cast_expr (location_t, struct c_type_name *, tree);
|
||||
extern tree build_c_cast (location_t, tree, tree);
|
||||
extern void store_init_value (location_t, tree, tree, tree);
|
||||
extern void error_init (const char *);
|
||||
extern void pedwarn_init (location_t, int opt, const char *);
|
||||
extern void maybe_warn_string_init (tree, struct c_expr);
|
||||
extern void start_init (tree, tree, int);
|
||||
extern void finish_init (void);
|
||||
extern void really_start_incremental_init (tree);
|
||||
extern void push_init_level (int, struct obstack *);
|
||||
extern struct c_expr pop_init_level (int, struct obstack *);
|
||||
extern void set_init_index (tree, tree, struct obstack *);
|
||||
extern void set_init_label (tree, struct obstack *);
|
||||
extern void process_init_element (struct c_expr, bool, struct obstack *);
|
||||
extern tree build_compound_literal (location_t, tree, tree, bool);
|
||||
extern void check_compound_literal_type (location_t, struct c_type_name *);
|
||||
extern tree c_start_case (location_t, location_t, tree);
|
||||
extern void c_finish_case (tree);
|
||||
extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool);
|
||||
extern tree build_asm_stmt (tree, tree);
|
||||
extern int c_types_compatible_p (tree, tree);
|
||||
extern tree c_begin_compound_stmt (bool);
|
||||
extern tree c_end_compound_stmt (location_t, tree, bool);
|
||||
extern void c_finish_if_stmt (location_t, tree, tree, tree, bool);
|
||||
extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
|
||||
extern tree c_begin_stmt_expr (void);
|
||||
extern tree c_finish_stmt_expr (location_t, tree);
|
||||
extern tree c_process_expr_stmt (location_t, tree);
|
||||
extern tree c_finish_expr_stmt (location_t, tree);
|
||||
extern tree c_finish_return (location_t, tree, tree);
|
||||
extern tree c_finish_bc_stmt (location_t, tree *, bool);
|
||||
extern tree c_finish_goto_label (location_t, tree);
|
||||
extern tree c_finish_goto_ptr (location_t, tree);
|
||||
extern tree c_expr_to_decl (tree, bool *, bool *);
|
||||
extern tree c_begin_omp_parallel (void);
|
||||
extern tree c_finish_omp_parallel (location_t, tree, tree);
|
||||
extern tree c_begin_omp_task (void);
|
||||
extern tree c_finish_omp_task (location_t, tree, tree);
|
||||
extern tree c_finish_omp_clauses (tree);
|
||||
extern tree c_build_va_arg (location_t, tree, tree);
|
||||
extern tree c_finish_transaction (location_t, tree, int);
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement that specifies a return value is seen. */
|
||||
|
||||
extern int current_function_returns_value;
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement with no argument is seen. */
|
||||
|
||||
extern int current_function_returns_null;
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a call to a noreturn function is seen. */
|
||||
|
||||
extern int current_function_returns_abnormally;
|
||||
|
||||
/* Mode used to build pointers (VOIDmode means ptr_mode). */
|
||||
|
||||
extern enum machine_mode c_default_pointer_mode;
|
||||
|
||||
/* In c-decl.c */
|
||||
extern void c_finish_incomplete_decl (tree);
|
||||
extern void c_write_global_declarations (void);
|
||||
|
||||
/* In c-errors.c */
|
||||
extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
||||
extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
||||
|
||||
#endif /* ! GCC_C_TREE_H */
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/* Flags on basic blocks and edges.
|
||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This file defines flags that may appear on basic blocks or on
|
||||
edges. Source files define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG
|
||||
appropriately before including this file. */
|
||||
|
||||
#if !defined(DEF_BASIC_BLOCK_FLAG) && !defined(DEF_EDGE_FLAG)
|
||||
#error "You must define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG"
|
||||
#endif
|
||||
|
||||
#ifdef DEF_BASIC_BLOCK_FLAG
|
||||
|
||||
/* Masks for basic_block.flags.
|
||||
|
||||
The format of this file is: DEF_BASIC_BLOCK_FLAG(NAME, IDX).
|
||||
NAME is the name of the basic block flag. A flag BB_#NAME will be
|
||||
created and the name is used in dump_edge_info.
|
||||
IDX is a sequence number that is used to determine the value
|
||||
of the flag, which is 1 << IDX).
|
||||
|
||||
BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout
|
||||
the compilation, so they are never cleared.
|
||||
|
||||
All other flags may be cleared by clear_bb_flags(). It is generally
|
||||
a bad idea to rely on any flags being up-to-date. */
|
||||
|
||||
/* Only set on blocks that have just been created by create_bb. */
|
||||
DEF_BASIC_BLOCK_FLAG(NEW, 0)
|
||||
|
||||
/* Set by find_unreachable_blocks. Do not rely on this being set in any
|
||||
pass. */
|
||||
DEF_BASIC_BLOCK_FLAG(REACHABLE, 1)
|
||||
|
||||
/* Set for blocks in an irreducible loop by loop analysis. */
|
||||
DEF_BASIC_BLOCK_FLAG(IRREDUCIBLE_LOOP, 2)
|
||||
|
||||
/* Set on blocks that may actually not be single-entry single-exit block. */
|
||||
DEF_BASIC_BLOCK_FLAG(SUPERBLOCK, 3)
|
||||
|
||||
/* Set on basic blocks that the scheduler should not touch. This is used
|
||||
by SMS to prevent other schedulers from messing with the loop schedule. */
|
||||
DEF_BASIC_BLOCK_FLAG(DISABLE_SCHEDULE, 4)
|
||||
|
||||
/* Set on blocks that should be put in a hot section. */
|
||||
DEF_BASIC_BLOCK_FLAG(HOT_PARTITION, 5)
|
||||
|
||||
/* Set on blocks that should be put in a cold section. */
|
||||
DEF_BASIC_BLOCK_FLAG(COLD_PARTITION, 6)
|
||||
|
||||
/* Set on block that was duplicated. */
|
||||
DEF_BASIC_BLOCK_FLAG(DUPLICATED, 7)
|
||||
|
||||
/* Set if the label at the top of this block is the target of a non-local goto. */
|
||||
DEF_BASIC_BLOCK_FLAG(NON_LOCAL_GOTO_TARGET, 8)
|
||||
|
||||
/* Set on blocks that are in RTL format. */
|
||||
DEF_BASIC_BLOCK_FLAG(RTL, 9)
|
||||
|
||||
/* Set on blocks that are forwarder blocks.
|
||||
Only used in cfgcleanup.c. */
|
||||
DEF_BASIC_BLOCK_FLAG(FORWARDER_BLOCK, 10)
|
||||
|
||||
/* Set on blocks that cannot be threaded through.
|
||||
Only used in cfgcleanup.c. */
|
||||
DEF_BASIC_BLOCK_FLAG(NONTHREADABLE_BLOCK, 11)
|
||||
|
||||
/* Set on blocks that were modified in some way. This bit is set in
|
||||
df_set_bb_dirty, but not cleared by df_analyze, so it can be used
|
||||
to test whether a block has been modified prior to a df_analyze call. */
|
||||
DEF_BASIC_BLOCK_FLAG(MODIFIED, 12)
|
||||
|
||||
/* A general visited flag for passes to use. */
|
||||
DEF_BASIC_BLOCK_FLAG(VISITED, 13)
|
||||
|
||||
/* Set on blocks that are in a transaction. This is calculated on
|
||||
demand, and is available after calling compute_transaction_bits(). */
|
||||
DEF_BASIC_BLOCK_FLAG(IN_TRANSACTION, 14)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEF_EDGE_FLAG
|
||||
|
||||
/* Masks for edge.flags.
|
||||
|
||||
The format of this file is: DEF_EDGE_FLAG(NAME, IDX, STRING).
|
||||
NAME is the name of the edge flag. A flag EDGE_#NAME will be
|
||||
created and the name is used in dump_edge_info.
|
||||
IDX is a sequence number that is used to determine the value
|
||||
of the flag, which is 1 << IDX). */
|
||||
|
||||
/* 'Straight line' flow. In GIMPLE and in cfglayout mode, all normal
|
||||
edges are fallthru edges. In cfgrtl mode, this flag really means
|
||||
that control flow falls through to the next basic block in the line. */
|
||||
DEF_EDGE_FLAG(FALLTHRU, 0)
|
||||
|
||||
/* Strange flow, like a computed jump or exception handling. Usually
|
||||
this means that the edge cannot be split. */
|
||||
DEF_EDGE_FLAG(ABNORMAL, 1)
|
||||
|
||||
/* Edge out of a basic block that ends with a CALL_INSN with abnormal
|
||||
exit, like an exception or a non-local goto.
|
||||
ABNORMAL_CALL edges also have ABNORMAL set.
|
||||
This flag is only used for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(ABNORMAL_CALL, 2)
|
||||
|
||||
/* Exception edge. Exception handling edges represent possible control
|
||||
transfers from a trapping instruction to an exception handler.
|
||||
EH edges also have ABNORMAL set for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(EH, 3)
|
||||
|
||||
/* Never merge blocks via this edge. This is used for exception handling,
|
||||
to prevent merging away edges to the post-landing-pad basic block.
|
||||
This flag is only used for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(PRESERVE, 4)
|
||||
|
||||
/* Not a real edge. This is used to connect parts of the CFG that do
|
||||
not halt, such as infinite loops and noreturn functions, to the
|
||||
EXIT_BLOCK, so that traversing of the reverse CFG is possible. */
|
||||
DEF_EDGE_FLAG(FAKE, 5)
|
||||
|
||||
/* A back edge, marked in a depth-first search of the CFG. Back edges
|
||||
are hints that this edge may be part of a loop in the CFG. */
|
||||
DEF_EDGE_FLAG(DFS_BACK, 6)
|
||||
|
||||
/* Edge in a part of the CFG that is an irreducible loop. */
|
||||
DEF_EDGE_FLAG(IRREDUCIBLE_LOOP, 7)
|
||||
|
||||
/* Edge taken when controlling predicate is nonzero.
|
||||
This is only used for the GIMPLE CFG. */
|
||||
DEF_EDGE_FLAG(TRUE_VALUE, 8)
|
||||
|
||||
/* Edge taken when controlling predicate is zero.
|
||||
This is only used for the GIMPLE CFG. */
|
||||
DEF_EDGE_FLAG(FALSE_VALUE, 9)
|
||||
|
||||
/* Edge is executable. This is only used in GIMPLE SSA-CCP and VRP.
|
||||
This is only used for the GIMPLE CFG. */
|
||||
DEF_EDGE_FLAG(EXECUTABLE, 10)
|
||||
|
||||
/* Edge crosses between hot and cold sections, when we do partitioning.
|
||||
This flag is only used for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(CROSSING, 11)
|
||||
|
||||
/* Edge from a sibcall CALL_INSN to exit.
|
||||
SIBCALL edges also have ABNORMAL set.
|
||||
This flag is only used for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(SIBCALL, 12)
|
||||
|
||||
/* Candidate for straight line flow. Only used in bb-reorder.c.
|
||||
This flag is only used for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(CAN_FALLTHRU, 13)
|
||||
|
||||
/* Exit of a loop. This is only used in ifcvt.c.
|
||||
This flag is only used for the RTL CFG. */
|
||||
DEF_EDGE_FLAG(LOOP_EXIT, 14)
|
||||
|
||||
/* Uninstrumented edge out of a GIMPLE_TRANSACTION statement. */
|
||||
DEF_EDGE_FLAG(TM_UNINSTRUMENTED, 15)
|
||||
|
||||
/* Abort (over) edge out of a GIMPLE_TRANSACTION statement. */
|
||||
DEF_EDGE_FLAG(TM_ABORT, 16)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
End:
|
||||
*/
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/* Hooks for cfg representation specific functions.
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
Contributed by Sebastian Pop <s.pop@laposte.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Only basic-block.h includes this. */
|
||||
|
||||
struct cfg_hooks
|
||||
{
|
||||
/* Name of the corresponding ir. */
|
||||
const char *name;
|
||||
|
||||
/* Debugging. */
|
||||
int (*verify_flow_info) (void);
|
||||
void (*dump_bb) (FILE *, basic_block, int, int);
|
||||
void (*dump_bb_for_graph) (pretty_printer *, basic_block);
|
||||
|
||||
/* Basic CFG manipulation. */
|
||||
|
||||
/* Return new basic block. */
|
||||
basic_block (*create_basic_block) (void *head, void *end, basic_block after);
|
||||
|
||||
/* Redirect edge E to the given basic block B and update underlying program
|
||||
representation. Returns edge representing redirected branch (that may not
|
||||
be equivalent to E in the case of duplicate edges being removed) or NULL
|
||||
if edge is not easily redirectable for whatever reason. */
|
||||
edge (*redirect_edge_and_branch) (edge e, basic_block b);
|
||||
|
||||
/* Same as the above but allows redirecting of fallthru edges. In that case
|
||||
newly created forwarder basic block is returned. The edge must
|
||||
not be abnormal. */
|
||||
basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
|
||||
|
||||
/* Returns true if it is possible to remove the edge by redirecting it
|
||||
to the destination of the other edge going from its source. */
|
||||
bool (*can_remove_branch_p) (const_edge);
|
||||
|
||||
/* Remove statements corresponding to a given basic block. */
|
||||
void (*delete_basic_block) (basic_block);
|
||||
|
||||
/* Creates a new basic block just after basic block B by splitting
|
||||
everything after specified instruction I. */
|
||||
basic_block (*split_block) (basic_block b, void * i);
|
||||
|
||||
/* Move block B immediately after block A. */
|
||||
bool (*move_block_after) (basic_block b, basic_block a);
|
||||
|
||||
/* Return true when blocks A and B can be merged into single basic block. */
|
||||
bool (*can_merge_blocks_p) (basic_block a, basic_block b);
|
||||
|
||||
/* Merge blocks A and B. */
|
||||
void (*merge_blocks) (basic_block a, basic_block b);
|
||||
|
||||
/* Predict edge E using PREDICTOR to given PROBABILITY. */
|
||||
void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
|
||||
|
||||
/* Return true if the one of outgoing edges is already predicted by
|
||||
PREDICTOR. */
|
||||
bool (*predicted_by_p) (const_basic_block bb, enum br_predictor predictor);
|
||||
|
||||
/* Return true when block A can be duplicated. */
|
||||
bool (*can_duplicate_block_p) (const_basic_block a);
|
||||
|
||||
/* Duplicate block A. */
|
||||
basic_block (*duplicate_block) (basic_block a);
|
||||
|
||||
/* Higher level functions representable by primitive operations above if
|
||||
we didn't have some oddities in RTL and Tree representations. */
|
||||
basic_block (*split_edge) (edge);
|
||||
void (*make_forwarder_block) (edge);
|
||||
|
||||
/* Try to make the edge fallthru. */
|
||||
void (*tidy_fallthru_edge) (edge);
|
||||
|
||||
/* Make the edge non-fallthru. */
|
||||
basic_block (*force_nonfallthru) (edge);
|
||||
|
||||
/* Say whether a block ends with a call, possibly followed by some
|
||||
other code that must stay with the call. */
|
||||
bool (*block_ends_with_call_p) (basic_block);
|
||||
|
||||
/* Say whether a block ends with a conditional branch. Switches
|
||||
and unconditional branches do not qualify. */
|
||||
bool (*block_ends_with_condjump_p) (const_basic_block);
|
||||
|
||||
/* Add fake edges to the function exit for any non constant and non noreturn
|
||||
calls, volatile inline assembly in the bitmap of blocks specified by
|
||||
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
|
||||
that were split.
|
||||
|
||||
The goal is to expose cases in which entering a basic block does not imply
|
||||
that all subsequent instructions must be executed. */
|
||||
int (*flow_call_edges_add) (sbitmap);
|
||||
|
||||
/* This function is called immediately after edge E is added to the
|
||||
edge vector E->dest->preds. */
|
||||
void (*execute_on_growing_pred) (edge);
|
||||
|
||||
/* This function is called immediately before edge E is removed from
|
||||
the edge vector E->dest->preds. */
|
||||
void (*execute_on_shrinking_pred) (edge);
|
||||
|
||||
/* A hook for duplicating loop in CFG, currently this is used
|
||||
in loop versioning. */
|
||||
bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *, edge,
|
||||
unsigned, sbitmap,
|
||||
edge, vec<edge> *,
|
||||
int);
|
||||
|
||||
/* Add condition to new basic block and update CFG used in loop
|
||||
versioning. */
|
||||
void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block,
|
||||
void *);
|
||||
/* Update the PHI nodes in case of loop versioning. */
|
||||
void (*lv_adjust_loop_header_phi) (basic_block, basic_block,
|
||||
basic_block, edge);
|
||||
|
||||
/* Given a condition BB extract the true/false taken/not taken edges
|
||||
(depending if we are on tree's or RTL). */
|
||||
void (*extract_cond_bb_edges) (basic_block, edge *, edge *);
|
||||
|
||||
|
||||
/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
|
||||
E->dest (only in tree-ssa loop versioning. */
|
||||
void (*flush_pending_stmts) (edge);
|
||||
|
||||
/* True if a block contains no executable instructions. */
|
||||
bool (*empty_block_p) (basic_block);
|
||||
|
||||
/* Split a basic block if it ends with a conditional branch and if
|
||||
the other part of the block is not empty. */
|
||||
basic_block (*split_block_before_cond_jump) (basic_block);
|
||||
|
||||
/* Do book-keeping of a basic block for the profile consistency checker. */
|
||||
void (*account_profile_record) (basic_block, int, struct profile_record *);
|
||||
};
|
||||
|
||||
extern void verify_flow_info (void);
|
||||
extern void dump_bb (FILE *, basic_block, int, int);
|
||||
extern void dump_bb_for_graph (pretty_printer *, basic_block);
|
||||
|
||||
extern edge redirect_edge_and_branch (edge, basic_block);
|
||||
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
|
||||
extern bool can_remove_branch_p (const_edge);
|
||||
extern void remove_branch (edge);
|
||||
extern void remove_edge (edge);
|
||||
extern edge split_block (basic_block, void *);
|
||||
extern edge split_block_after_labels (basic_block);
|
||||
extern bool move_block_after (basic_block, basic_block);
|
||||
extern void delete_basic_block (basic_block);
|
||||
extern basic_block split_edge (edge);
|
||||
extern basic_block create_basic_block (void *, void *, basic_block);
|
||||
extern basic_block create_empty_bb (basic_block);
|
||||
extern bool can_merge_blocks_p (basic_block, basic_block);
|
||||
extern void merge_blocks (basic_block, basic_block);
|
||||
extern edge make_forwarder_block (basic_block, bool (*)(edge),
|
||||
void (*) (basic_block));
|
||||
extern basic_block force_nonfallthru (edge);
|
||||
extern void tidy_fallthru_edge (edge);
|
||||
extern void tidy_fallthru_edges (void);
|
||||
extern void predict_edge (edge e, enum br_predictor predictor, int probability);
|
||||
extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
|
||||
extern bool can_duplicate_block_p (const_basic_block);
|
||||
extern basic_block duplicate_block (basic_block, edge, basic_block);
|
||||
extern bool block_ends_with_call_p (basic_block bb);
|
||||
extern bool empty_block_p (basic_block);
|
||||
extern basic_block split_block_before_cond_jump (basic_block);
|
||||
extern bool block_ends_with_condjump_p (const_basic_block bb);
|
||||
extern int flow_call_edges_add (sbitmap);
|
||||
extern void execute_on_growing_pred (edge);
|
||||
extern void execute_on_shrinking_pred (edge);
|
||||
extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
|
||||
unsigned int ndupl,
|
||||
sbitmap wont_exit,
|
||||
edge orig,
|
||||
vec<edge> *to_remove,
|
||||
int flags);
|
||||
|
||||
extern void lv_flush_pending_stmts (edge);
|
||||
extern void extract_cond_bb_edges (basic_block, edge *, edge*);
|
||||
extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block,
|
||||
edge);
|
||||
extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
|
||||
void *);
|
||||
|
||||
extern bool can_copy_bbs_p (basic_block *, unsigned);
|
||||
extern void copy_bbs (basic_block *, unsigned, basic_block *,
|
||||
edge *, unsigned, edge *, struct loop *,
|
||||
basic_block, bool);
|
||||
|
||||
void account_profile_record (struct profile_record *, int);
|
||||
|
||||
extern void cfg_layout_initialize (unsigned int);
|
||||
extern void cfg_layout_finalize (void);
|
||||
|
||||
/* Hooks containers. */
|
||||
extern struct cfg_hooks gimple_cfg_hooks;
|
||||
extern struct cfg_hooks rtl_cfg_hooks;
|
||||
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
|
||||
|
||||
/* Declarations. */
|
||||
extern enum ir_type current_ir_type (void);
|
||||
extern void rtl_register_cfg_hooks (void);
|
||||
extern void cfg_layout_rtl_register_cfg_hooks (void);
|
||||
extern void gimple_register_cfg_hooks (void);
|
||||
extern struct cfg_hooks get_cfg_hooks (void);
|
||||
extern void set_cfg_hooks (struct cfg_hooks);
|
||||
|
||||
|
|
@ -0,0 +1,733 @@
|
|||
/* Natural loop functions
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_CFGLOOP_H
|
||||
#define GCC_CFGLOOP_H
|
||||
|
||||
#include "basic-block.h"
|
||||
#include "double-int.h"
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "sbitmap.h"
|
||||
|
||||
/* Structure to hold decision about unrolling/peeling. */
|
||||
enum lpt_dec
|
||||
{
|
||||
LPT_NONE,
|
||||
LPT_PEEL_COMPLETELY,
|
||||
LPT_PEEL_SIMPLE,
|
||||
LPT_UNROLL_CONSTANT,
|
||||
LPT_UNROLL_RUNTIME,
|
||||
LPT_UNROLL_STUPID
|
||||
};
|
||||
|
||||
struct GTY (()) lpt_decision {
|
||||
enum lpt_dec decision;
|
||||
unsigned times;
|
||||
};
|
||||
|
||||
/* The type of extend applied to an IV. */
|
||||
enum iv_extend_code
|
||||
{
|
||||
IV_SIGN_EXTEND,
|
||||
IV_ZERO_EXTEND,
|
||||
IV_UNKNOWN_EXTEND
|
||||
};
|
||||
|
||||
/* The structure describing a bound on number of iterations of a loop. */
|
||||
|
||||
struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
|
||||
/* The statement STMT is executed at most ... */
|
||||
gimple stmt;
|
||||
|
||||
/* ... BOUND + 1 times (BOUND must be an unsigned constant).
|
||||
The + 1 is added for the following reasons:
|
||||
|
||||
a) 0 would otherwise be unused, while we would need to care more about
|
||||
overflows (as MAX + 1 is sometimes produced as the estimate on number
|
||||
of executions of STMT).
|
||||
b) it is consistent with the result of number_of_iterations_exit. */
|
||||
double_int bound;
|
||||
|
||||
/* True if the statement will cause the loop to be leaved the (at most)
|
||||
BOUND + 1-st time it is executed, that is, all the statements after it
|
||||
are executed at most BOUND times. */
|
||||
bool is_exit;
|
||||
|
||||
/* The next bound in the list. */
|
||||
struct nb_iter_bound *next;
|
||||
};
|
||||
|
||||
/* Description of the loop exit. */
|
||||
|
||||
struct GTY (()) loop_exit {
|
||||
/* The exit edge. */
|
||||
edge e;
|
||||
|
||||
/* Previous and next exit in the list of the exits of the loop. */
|
||||
struct loop_exit *prev;
|
||||
struct loop_exit *next;
|
||||
|
||||
/* Next element in the list of loops from that E exits. */
|
||||
struct loop_exit *next_e;
|
||||
};
|
||||
|
||||
typedef struct loop *loop_p;
|
||||
|
||||
/* An integer estimation of the number of iterations. Estimate_state
|
||||
describes what is the state of the estimation. */
|
||||
enum loop_estimation
|
||||
{
|
||||
/* Estimate was not computed yet. */
|
||||
EST_NOT_COMPUTED,
|
||||
/* Estimate is ready. */
|
||||
EST_AVAILABLE
|
||||
};
|
||||
|
||||
/* Structure to hold information for each natural loop. */
|
||||
struct GTY ((chain_next ("%h.next"))) loop {
|
||||
/* Index into loops array. */
|
||||
int num;
|
||||
|
||||
/* Number of loop insns. */
|
||||
unsigned ninsns;
|
||||
|
||||
/* Basic block of loop header. */
|
||||
basic_block header;
|
||||
|
||||
/* Basic block of loop latch. */
|
||||
basic_block latch;
|
||||
|
||||
/* For loop unrolling/peeling decision. */
|
||||
struct lpt_decision lpt_decision;
|
||||
|
||||
/* Average number of executed insns per iteration. */
|
||||
unsigned av_ninsns;
|
||||
|
||||
/* Number of blocks contained within the loop. */
|
||||
unsigned num_nodes;
|
||||
|
||||
/* Superloops of the loop, starting with the outermost loop. */
|
||||
vec<loop_p, va_gc> *superloops;
|
||||
|
||||
/* The first inner (child) loop or NULL if innermost loop. */
|
||||
struct loop *inner;
|
||||
|
||||
/* Link to the next (sibling) loop. */
|
||||
struct loop *next;
|
||||
|
||||
/* Auxiliary info specific to a pass. */
|
||||
PTR GTY ((skip (""))) aux;
|
||||
|
||||
/* The number of times the latch of the loop is executed. This can be an
|
||||
INTEGER_CST, or a symbolic expression representing the number of
|
||||
iterations like "N - 1", or a COND_EXPR containing the runtime
|
||||
conditions under which the number of iterations is non zero.
|
||||
|
||||
Don't access this field directly: number_of_latch_executions
|
||||
computes and caches the computed information in this field. */
|
||||
tree nb_iterations;
|
||||
|
||||
/* An integer guaranteed to be greater or equal to nb_iterations. Only
|
||||
valid if any_upper_bound is true. */
|
||||
double_int nb_iterations_upper_bound;
|
||||
|
||||
/* An integer giving an estimate on nb_iterations. Unlike
|
||||
nb_iterations_upper_bound, there is no guarantee that it is at least
|
||||
nb_iterations. */
|
||||
double_int nb_iterations_estimate;
|
||||
|
||||
bool any_upper_bound;
|
||||
bool any_estimate;
|
||||
|
||||
/* True if the loop can be parallel. */
|
||||
bool can_be_parallel;
|
||||
|
||||
/* True if -Waggressive-loop-optimizations warned about this loop
|
||||
already. */
|
||||
bool warned_aggressive_loop_optimizations;
|
||||
|
||||
/* An integer estimation of the number of iterations. Estimate_state
|
||||
describes what is the state of the estimation. */
|
||||
enum loop_estimation estimate_state;
|
||||
|
||||
/* Upper bound on number of iterations of a loop. */
|
||||
struct nb_iter_bound *bounds;
|
||||
|
||||
/* Head of the cyclic list of the exits of the loop. */
|
||||
struct loop_exit *exits;
|
||||
};
|
||||
|
||||
/* Flags for state of loop structure. */
|
||||
enum
|
||||
{
|
||||
LOOPS_HAVE_PREHEADERS = 1,
|
||||
LOOPS_HAVE_SIMPLE_LATCHES = 2,
|
||||
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
|
||||
LOOPS_HAVE_RECORDED_EXITS = 8,
|
||||
LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
|
||||
LOOP_CLOSED_SSA = 32,
|
||||
LOOPS_NEED_FIXUP = 64,
|
||||
LOOPS_HAVE_FALLTHRU_PREHEADERS = 128
|
||||
};
|
||||
|
||||
#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
|
||||
| LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
|
||||
#define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
|
||||
|
||||
/* Structure to hold CFG information about natural loops within a function. */
|
||||
struct GTY (()) loops {
|
||||
/* State of loops. */
|
||||
int state;
|
||||
|
||||
/* Array of the loops. */
|
||||
vec<loop_p, va_gc> *larray;
|
||||
|
||||
/* Maps edges to the list of their descriptions as loop exits. Edges
|
||||
whose sources or destinations have loop_father == NULL (which may
|
||||
happen during the cfg manipulations) should not appear in EXITS. */
|
||||
htab_t GTY((param_is (struct loop_exit))) exits;
|
||||
|
||||
/* Pointer to root of loop hierarchy tree. */
|
||||
struct loop *tree_root;
|
||||
};
|
||||
|
||||
/* Loop recognition. */
|
||||
bool bb_loop_header_p (basic_block);
|
||||
extern struct loops *flow_loops_find (struct loops *);
|
||||
extern void disambiguate_loops_with_multiple_latches (void);
|
||||
extern void flow_loops_free (struct loops *);
|
||||
extern void flow_loops_dump (FILE *,
|
||||
void (*)(const struct loop *, FILE *, int), int);
|
||||
extern void flow_loop_dump (const struct loop *, FILE *,
|
||||
void (*)(const struct loop *, FILE *, int), int);
|
||||
struct loop *alloc_loop (void);
|
||||
extern void flow_loop_free (struct loop *);
|
||||
int flow_loop_nodes_find (basic_block, struct loop *);
|
||||
unsigned fix_loop_structure (bitmap changed_bbs);
|
||||
bool mark_irreducible_loops (void);
|
||||
void release_recorded_exits (void);
|
||||
void record_loop_exits (void);
|
||||
void rescan_loop_exit (edge, bool, bool);
|
||||
|
||||
/* Loop data structure manipulation/querying. */
|
||||
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
|
||||
extern void flow_loop_tree_node_remove (struct loop *);
|
||||
extern void add_loop (struct loop *, struct loop *);
|
||||
extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
|
||||
extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
|
||||
extern struct loop * find_common_loop (struct loop *, struct loop *);
|
||||
struct loop *superloop_at_depth (struct loop *, unsigned);
|
||||
struct eni_weights_d;
|
||||
extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
|
||||
extern int num_loop_insns (const struct loop *);
|
||||
extern int average_num_loop_insns (const struct loop *);
|
||||
extern unsigned get_loop_level (const struct loop *);
|
||||
extern bool loop_exit_edge_p (const struct loop *, const_edge);
|
||||
extern bool loop_exits_to_bb_p (struct loop *, basic_block);
|
||||
extern bool loop_exits_from_bb_p (struct loop *, basic_block);
|
||||
extern void mark_loop_exit_edges (void);
|
||||
extern location_t get_loop_location (struct loop *loop);
|
||||
|
||||
/* Loops & cfg manipulation. */
|
||||
extern basic_block *get_loop_body (const struct loop *);
|
||||
extern unsigned get_loop_body_with_size (const struct loop *, basic_block *,
|
||||
unsigned);
|
||||
extern basic_block *get_loop_body_in_dom_order (const struct loop *);
|
||||
extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
|
||||
extern basic_block *get_loop_body_in_custom_order (const struct loop *,
|
||||
int (*) (const void *, const void *));
|
||||
|
||||
extern vec<edge> get_loop_exit_edges (const struct loop *);
|
||||
extern edge single_exit (const struct loop *);
|
||||
extern edge single_likely_exit (struct loop *loop);
|
||||
extern unsigned num_loop_branches (const struct loop *);
|
||||
|
||||
extern edge loop_preheader_edge (const struct loop *);
|
||||
extern edge loop_latch_edge (const struct loop *);
|
||||
|
||||
extern void add_bb_to_loop (basic_block, struct loop *);
|
||||
extern void remove_bb_from_loops (basic_block);
|
||||
|
||||
extern void cancel_loop_tree (struct loop *);
|
||||
extern void delete_loop (struct loop *);
|
||||
|
||||
enum
|
||||
{
|
||||
CP_SIMPLE_PREHEADERS = 1,
|
||||
CP_FALLTHRU_PREHEADERS = 2
|
||||
};
|
||||
|
||||
basic_block create_preheader (struct loop *, int);
|
||||
extern void create_preheaders (int);
|
||||
extern void force_single_succ_latches (void);
|
||||
|
||||
extern void verify_loop_structure (void);
|
||||
|
||||
/* Loop analysis. */
|
||||
extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
|
||||
gcov_type expected_loop_iterations_unbounded (const struct loop *);
|
||||
extern unsigned expected_loop_iterations (const struct loop *);
|
||||
extern rtx doloop_condition_get (rtx);
|
||||
|
||||
void estimate_numbers_of_iterations_loop (struct loop *);
|
||||
void record_niter_bound (struct loop *, double_int, bool, bool);
|
||||
bool estimated_loop_iterations (struct loop *, double_int *);
|
||||
bool max_loop_iterations (struct loop *, double_int *);
|
||||
HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
|
||||
HOST_WIDE_INT max_loop_iterations_int (struct loop *);
|
||||
bool max_stmt_executions (struct loop *, double_int *);
|
||||
bool estimated_stmt_executions (struct loop *, double_int *);
|
||||
HOST_WIDE_INT max_stmt_executions_int (struct loop *);
|
||||
HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
|
||||
|
||||
/* Loop manipulation. */
|
||||
extern bool can_duplicate_loop_p (const struct loop *loop);
|
||||
|
||||
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
|
||||
duplicate_loop_to_header_edge. */
|
||||
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
|
||||
field of newly create BB. */
|
||||
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
|
||||
a complete peeling. */
|
||||
|
||||
extern edge create_empty_if_region_on_edge (edge, tree);
|
||||
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
|
||||
tree *, tree *, struct loop *);
|
||||
extern struct loop * duplicate_loop (struct loop *, struct loop *);
|
||||
extern void copy_loop_info (struct loop *loop, struct loop *target);
|
||||
extern void duplicate_subloops (struct loop *, struct loop *);
|
||||
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
|
||||
unsigned, sbitmap, edge,
|
||||
vec<edge> *, int);
|
||||
extern struct loop *loopify (edge, edge,
|
||||
basic_block, edge, edge, bool,
|
||||
unsigned, unsigned);
|
||||
struct loop * loop_version (struct loop *, void *,
|
||||
basic_block *, unsigned, unsigned, unsigned, bool);
|
||||
extern bool remove_path (edge);
|
||||
extern void unloop (struct loop *, bool *, bitmap);
|
||||
extern void scale_loop_frequencies (struct loop *, int, int);
|
||||
|
||||
/* Induction variable analysis. */
|
||||
|
||||
/* The description of induction variable. The things are a bit complicated
|
||||
due to need to handle subregs and extends. The value of the object described
|
||||
by it can be obtained as follows (all computations are done in extend_mode):
|
||||
|
||||
Value in i-th iteration is
|
||||
delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)).
|
||||
|
||||
If first_special is true, the value in the first iteration is
|
||||
delta + mult * base
|
||||
|
||||
If extend = UNKNOWN, first_special must be false, delta 0, mult 1 and value is
|
||||
subreg_{mode} (base + i * step)
|
||||
|
||||
The get_iv_value function can be used to obtain these expressions.
|
||||
|
||||
??? Add a third mode field that would specify the mode in that inner
|
||||
computation is done, which would enable it to be different from the
|
||||
outer one? */
|
||||
|
||||
struct rtx_iv
|
||||
{
|
||||
/* Its base and step (mode of base and step is supposed to be extend_mode,
|
||||
see the description above). */
|
||||
rtx base, step;
|
||||
|
||||
/* The type of extend applied to it (IV_SIGN_EXTEND, IV_ZERO_EXTEND,
|
||||
or IV_UNKNOWN_EXTEND). */
|
||||
enum iv_extend_code extend;
|
||||
|
||||
/* Operations applied in the extended mode. */
|
||||
rtx delta, mult;
|
||||
|
||||
/* The mode it is extended to. */
|
||||
enum machine_mode extend_mode;
|
||||
|
||||
/* The mode the variable iterates in. */
|
||||
enum machine_mode mode;
|
||||
|
||||
/* Whether the first iteration needs to be handled specially. */
|
||||
unsigned first_special : 1;
|
||||
};
|
||||
|
||||
/* The description of an exit from the loop and of the number of iterations
|
||||
till we take the exit. */
|
||||
|
||||
struct niter_desc
|
||||
{
|
||||
/* The edge out of the loop. */
|
||||
edge out_edge;
|
||||
|
||||
/* The other edge leading from the condition. */
|
||||
edge in_edge;
|
||||
|
||||
/* True if we are able to say anything about number of iterations of the
|
||||
loop. */
|
||||
bool simple_p;
|
||||
|
||||
/* True if the loop iterates the constant number of times. */
|
||||
bool const_iter;
|
||||
|
||||
/* Number of iterations if constant. */
|
||||
unsigned HOST_WIDEST_INT niter;
|
||||
|
||||
/* Assumptions under that the rest of the information is valid. */
|
||||
rtx assumptions;
|
||||
|
||||
/* Assumptions under that the loop ends before reaching the latch,
|
||||
even if value of niter_expr says otherwise. */
|
||||
rtx noloop_assumptions;
|
||||
|
||||
/* Condition under that the loop is infinite. */
|
||||
rtx infinite;
|
||||
|
||||
/* Whether the comparison is signed. */
|
||||
bool signed_p;
|
||||
|
||||
/* The mode in that niter_expr should be computed. */
|
||||
enum machine_mode mode;
|
||||
|
||||
/* The number of iterations of the loop. */
|
||||
rtx niter_expr;
|
||||
};
|
||||
|
||||
extern void iv_analysis_loop_init (struct loop *);
|
||||
extern bool iv_analyze (rtx, rtx, struct rtx_iv *);
|
||||
extern bool iv_analyze_result (rtx, rtx, struct rtx_iv *);
|
||||
extern bool iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *);
|
||||
extern rtx get_iv_value (struct rtx_iv *, rtx);
|
||||
extern bool biv_p (rtx, rtx);
|
||||
extern void find_simple_exit (struct loop *, struct niter_desc *);
|
||||
extern void iv_analysis_done (void);
|
||||
|
||||
extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
|
||||
extern void free_simple_loop_desc (struct loop *loop);
|
||||
|
||||
static inline struct niter_desc *
|
||||
simple_loop_desc (struct loop *loop)
|
||||
{
|
||||
return (struct niter_desc *) loop->aux;
|
||||
}
|
||||
|
||||
/* Accessors for the loop structures. */
|
||||
|
||||
/* Returns the loop with index NUM from current_loops. */
|
||||
|
||||
static inline struct loop *
|
||||
get_loop (unsigned num)
|
||||
{
|
||||
return (*current_loops->larray)[num];
|
||||
}
|
||||
|
||||
/* Returns the number of superloops of LOOP. */
|
||||
|
||||
static inline unsigned
|
||||
loop_depth (const struct loop *loop)
|
||||
{
|
||||
return vec_safe_length (loop->superloops);
|
||||
}
|
||||
|
||||
/* Returns the loop depth of the loop BB belongs to. */
|
||||
|
||||
static inline int
|
||||
bb_loop_depth (const_basic_block bb)
|
||||
{
|
||||
return bb->loop_father ? loop_depth (bb->loop_father) : 0;
|
||||
}
|
||||
|
||||
/* Returns the immediate superloop of LOOP, or NULL if LOOP is the outermost
|
||||
loop. */
|
||||
|
||||
static inline struct loop *
|
||||
loop_outer (const struct loop *loop)
|
||||
{
|
||||
unsigned n = vec_safe_length (loop->superloops);
|
||||
|
||||
if (n == 0)
|
||||
return NULL;
|
||||
|
||||
return (*loop->superloops)[n - 1];
|
||||
}
|
||||
|
||||
/* Returns true if LOOP has at least one exit edge. */
|
||||
|
||||
static inline bool
|
||||
loop_has_exit_edges (const struct loop *loop)
|
||||
{
|
||||
return loop->exits->next->e != NULL;
|
||||
}
|
||||
|
||||
/* Returns the list of loops in current_loops. */
|
||||
|
||||
static inline vec<loop_p, va_gc> *
|
||||
get_loops (void)
|
||||
{
|
||||
if (!current_loops)
|
||||
return NULL;
|
||||
|
||||
return current_loops->larray;
|
||||
}
|
||||
|
||||
/* Returns the number of loops in current_loops (including the removed
|
||||
ones and the fake loop that forms the root of the loop tree). */
|
||||
|
||||
static inline unsigned
|
||||
number_of_loops (void)
|
||||
{
|
||||
if (!current_loops)
|
||||
return 0;
|
||||
|
||||
return vec_safe_length (current_loops->larray);
|
||||
}
|
||||
|
||||
/* Returns true if state of the loops satisfies all properties
|
||||
described by FLAGS. */
|
||||
|
||||
static inline bool
|
||||
loops_state_satisfies_p (unsigned flags)
|
||||
{
|
||||
return (current_loops->state & flags) == flags;
|
||||
}
|
||||
|
||||
/* Sets FLAGS to the loops state. */
|
||||
|
||||
static inline void
|
||||
loops_state_set (unsigned flags)
|
||||
{
|
||||
current_loops->state |= flags;
|
||||
}
|
||||
|
||||
/* Clears FLAGS from the loops state. */
|
||||
|
||||
static inline void
|
||||
loops_state_clear (unsigned flags)
|
||||
{
|
||||
if (!current_loops)
|
||||
return;
|
||||
current_loops->state &= ~flags;
|
||||
}
|
||||
|
||||
/* Loop iterators. */
|
||||
|
||||
/* Flags for loop iteration. */
|
||||
|
||||
enum li_flags
|
||||
{
|
||||
LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */
|
||||
LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order,
|
||||
starting from innermost ones. */
|
||||
LI_ONLY_INNERMOST = 4 /* Iterate only over innermost loops. */
|
||||
};
|
||||
|
||||
/* The iterator for loops. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* The list of loops to visit. */
|
||||
vec<int> to_visit;
|
||||
|
||||
/* The index of the actual loop. */
|
||||
unsigned idx;
|
||||
} loop_iterator;
|
||||
|
||||
static inline void
|
||||
fel_next (loop_iterator *li, loop_p *loop)
|
||||
{
|
||||
int anum;
|
||||
|
||||
while (li->to_visit.iterate (li->idx, &anum))
|
||||
{
|
||||
li->idx++;
|
||||
*loop = get_loop (anum);
|
||||
if (*loop)
|
||||
return;
|
||||
}
|
||||
|
||||
li->to_visit.release ();
|
||||
*loop = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
|
||||
{
|
||||
struct loop *aloop;
|
||||
unsigned i;
|
||||
int mn;
|
||||
|
||||
li->idx = 0;
|
||||
if (!current_loops)
|
||||
{
|
||||
li->to_visit.create (0);
|
||||
*loop = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
li->to_visit.create (number_of_loops ());
|
||||
mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
|
||||
|
||||
if (flags & LI_ONLY_INNERMOST)
|
||||
{
|
||||
for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++)
|
||||
if (aloop != NULL
|
||||
&& aloop->inner == NULL
|
||||
&& aloop->num >= mn)
|
||||
li->to_visit.quick_push (aloop->num);
|
||||
}
|
||||
else if (flags & LI_FROM_INNERMOST)
|
||||
{
|
||||
/* Push the loops to LI->TO_VISIT in postorder. */
|
||||
for (aloop = current_loops->tree_root;
|
||||
aloop->inner != NULL;
|
||||
aloop = aloop->inner)
|
||||
continue;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (aloop->num >= mn)
|
||||
li->to_visit.quick_push (aloop->num);
|
||||
|
||||
if (aloop->next)
|
||||
{
|
||||
for (aloop = aloop->next;
|
||||
aloop->inner != NULL;
|
||||
aloop = aloop->inner)
|
||||
continue;
|
||||
}
|
||||
else if (!loop_outer (aloop))
|
||||
break;
|
||||
else
|
||||
aloop = loop_outer (aloop);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push the loops to LI->TO_VISIT in preorder. */
|
||||
aloop = current_loops->tree_root;
|
||||
while (1)
|
||||
{
|
||||
if (aloop->num >= mn)
|
||||
li->to_visit.quick_push (aloop->num);
|
||||
|
||||
if (aloop->inner != NULL)
|
||||
aloop = aloop->inner;
|
||||
else
|
||||
{
|
||||
while (aloop != NULL && aloop->next == NULL)
|
||||
aloop = loop_outer (aloop);
|
||||
if (aloop == NULL)
|
||||
break;
|
||||
aloop = aloop->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fel_next (li, loop);
|
||||
}
|
||||
|
||||
#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
|
||||
for (fel_init (&(LI), &(LOOP), FLAGS); \
|
||||
(LOOP); \
|
||||
fel_next (&(LI), &(LOOP)))
|
||||
|
||||
#define FOR_EACH_LOOP_BREAK(LI) \
|
||||
{ \
|
||||
(LI).to_visit.release (); \
|
||||
break; \
|
||||
}
|
||||
|
||||
/* The properties of the target. */
|
||||
struct target_cfgloop {
|
||||
/* Number of available registers. */
|
||||
unsigned x_target_avail_regs;
|
||||
|
||||
/* Number of available registers that are call-clobbered. */
|
||||
unsigned x_target_clobbered_regs;
|
||||
|
||||
/* Number of registers reserved for temporary expressions. */
|
||||
unsigned x_target_res_regs;
|
||||
|
||||
/* The cost for register when there still is some reserve, but we are
|
||||
approaching the number of available registers. */
|
||||
unsigned x_target_reg_cost[2];
|
||||
|
||||
/* The cost for register when we need to spill. */
|
||||
unsigned x_target_spill_cost[2];
|
||||
};
|
||||
|
||||
extern struct target_cfgloop default_target_cfgloop;
|
||||
#if SWITCHABLE_TARGET
|
||||
extern struct target_cfgloop *this_target_cfgloop;
|
||||
#else
|
||||
#define this_target_cfgloop (&default_target_cfgloop)
|
||||
#endif
|
||||
|
||||
#define target_avail_regs \
|
||||
(this_target_cfgloop->x_target_avail_regs)
|
||||
#define target_clobbered_regs \
|
||||
(this_target_cfgloop->x_target_clobbered_regs)
|
||||
#define target_res_regs \
|
||||
(this_target_cfgloop->x_target_res_regs)
|
||||
#define target_reg_cost \
|
||||
(this_target_cfgloop->x_target_reg_cost)
|
||||
#define target_spill_cost \
|
||||
(this_target_cfgloop->x_target_spill_cost)
|
||||
|
||||
/* Register pressure estimation for induction variable optimizations & loop
|
||||
invariant motion. */
|
||||
extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool);
|
||||
extern void init_set_costs (void);
|
||||
|
||||
/* Loop optimizer initialization. */
|
||||
extern void loop_optimizer_init (unsigned);
|
||||
extern void loop_optimizer_finalize (void);
|
||||
|
||||
/* Optimization passes. */
|
||||
extern void unswitch_loops (void);
|
||||
|
||||
enum
|
||||
{
|
||||
UAP_PEEL = 1, /* Enables loop peeling. */
|
||||
UAP_UNROLL = 2, /* Enables unrolling of loops if it seems profitable. */
|
||||
UAP_UNROLL_ALL = 4 /* Enables unrolling of all loops. */
|
||||
};
|
||||
|
||||
extern void unroll_and_peel_loops (int);
|
||||
extern void doloop_optimize_loops (void);
|
||||
extern void move_loop_invariants (void);
|
||||
extern bool finite_loop_p (struct loop *);
|
||||
extern void scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound);
|
||||
extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
|
||||
|
||||
/* Returns the outermost loop of the loop nest that contains LOOP.*/
|
||||
static inline struct loop *
|
||||
loop_outermost (struct loop *loop)
|
||||
{
|
||||
unsigned n = vec_safe_length (loop->superloops);
|
||||
|
||||
if (n <= 1)
|
||||
return loop;
|
||||
|
||||
return (*loop->superloops)[1];
|
||||
}
|
||||
|
||||
|
||||
#endif /* GCC_CFGLOOP_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,105 @@
|
|||
/* This file contains the definitions of the cgraph_inline_failed_t
|
||||
enums used in GCC.
|
||||
|
||||
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||
Contributed by Doug Kwan <dougkwan@google.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The format of this file is
|
||||
DEFCIFCODE(code, string).
|
||||
|
||||
Where symbol is the enumeration name without the ``''.
|
||||
The argument STRING is a explain the failure. Except for OK,
|
||||
which is a NULL pointer. */
|
||||
|
||||
/* Inlining successful. This must be the first code. */
|
||||
DEFCIFCODE(OK , NULL)
|
||||
|
||||
/* Inlining failed for an unspecified reason. */
|
||||
DEFCIFCODE(UNSPECIFIED , "")
|
||||
|
||||
/* Function has not be considered for inlining. This is the code for
|
||||
functions that have not been rejected for inlining yet. */
|
||||
DEFCIFCODE(FUNCTION_NOT_CONSIDERED, N_("function not considered for inlining"))
|
||||
|
||||
/* Inlining failed owing to unavailable function body. */
|
||||
DEFCIFCODE(BODY_NOT_AVAILABLE, N_("function body not available"))
|
||||
|
||||
/* Extern inline function that has been redefined. */
|
||||
DEFCIFCODE(REDEFINED_EXTERN_INLINE,
|
||||
N_("redefined extern inline functions are not considered for "
|
||||
"inlining"))
|
||||
|
||||
/* Function is not inlinable. */
|
||||
DEFCIFCODE(FUNCTION_NOT_INLINABLE, N_("function not inlinable"))
|
||||
|
||||
/* Function is not overwritable. */
|
||||
DEFCIFCODE(OVERWRITABLE, N_("function body can be overwritten at link time"))
|
||||
|
||||
/* Function is not an inlining candidate. */
|
||||
DEFCIFCODE(FUNCTION_NOT_INLINE_CANDIDATE, N_("function not inline candidate"))
|
||||
|
||||
/* Inlining failed because of various limit parameters. */
|
||||
DEFCIFCODE(LARGE_FUNCTION_GROWTH_LIMIT,
|
||||
N_("--param large-function-growth limit reached"))
|
||||
DEFCIFCODE(LARGE_STACK_FRAME_GROWTH_LIMIT,
|
||||
N_("--param large-stack-frame-growth limit reached"))
|
||||
DEFCIFCODE(MAX_INLINE_INSNS_SINGLE_LIMIT,
|
||||
N_("--param max-inline-insns-single limit reached"))
|
||||
DEFCIFCODE(MAX_INLINE_INSNS_AUTO_LIMIT,
|
||||
N_("--param max-inline-insns-auto limit reached"))
|
||||
DEFCIFCODE(INLINE_UNIT_GROWTH_LIMIT,
|
||||
N_("--param inline-unit-growth limit reached"))
|
||||
|
||||
/* Recursive inlining. */
|
||||
DEFCIFCODE(RECURSIVE_INLINING, N_("recursive inlining"))
|
||||
|
||||
/* Call is unlikely. */
|
||||
DEFCIFCODE(UNLIKELY_CALL, N_("call is unlikely and code size would grow"))
|
||||
|
||||
/* Function is not declared as inline. */
|
||||
DEFCIFCODE(NOT_DECLARED_INLINED,
|
||||
N_("function not declared inline and code size would grow"))
|
||||
|
||||
/* Inlining suppressed due to size optimization. */
|
||||
DEFCIFCODE(OPTIMIZING_FOR_SIZE,
|
||||
N_("optimizing for size and code size would grow"))
|
||||
|
||||
/* Caller and callee disagree on the arguments. */
|
||||
DEFCIFCODE(MISMATCHED_ARGUMENTS, N_("mismatched arguments"))
|
||||
|
||||
/* Call was originally indirect. */
|
||||
DEFCIFCODE(ORIGINALLY_INDIRECT_CALL,
|
||||
N_("originally indirect function call not considered for inlining"))
|
||||
|
||||
/* Ths edge represents an indirect edge with a yet-undetermined callee . */
|
||||
DEFCIFCODE(INDIRECT_UNKNOWN_CALL,
|
||||
N_("indirect function call with a yet undetermined callee"))
|
||||
|
||||
/* We can't inline different EH personalities together. */
|
||||
DEFCIFCODE(EH_PERSONALITY, N_("exception handling personality mismatch"))
|
||||
|
||||
/* We can't inline if the callee can throw non-call exceptions but the
|
||||
caller cannot. */
|
||||
DEFCIFCODE(NON_CALL_EXCEPTIONS, N_("non-call exception handling mismatch"))
|
||||
|
||||
/* We can't inline because of mismatched target specific options. */
|
||||
DEFCIFCODE(TARGET_OPTION_MISMATCH, N_("target specific option mismatch"))
|
||||
|
||||
/* We can't inline because of mismatched optimization levels. */
|
||||
DEFCIFCODE(OPTIMIZATION_MISMATCH, N_("optimization level attribute mismatch"))
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef GCC_CONFIG_H
|
||||
#define GCC_CONFIG_H
|
||||
#ifdef GENERATOR_FILE
|
||||
#error config.h is for the host, not build, machine.
|
||||
#endif
|
||||
#include "auto-host.h"
|
||||
#ifdef IN_GCC
|
||||
# include "ansidecl.h"
|
||||
#endif
|
||||
#endif /* GCC_CONFIG_H */
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/* Functions and structures shared between arm and aarch64.
|
||||
|
||||
Copyright (C) 1991-2013 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#ifndef GCC_AARCH_COMMON_PROTOS_H
|
||||
#define GCC_AARCH_COMMON_PROTOS_H
|
||||
|
||||
extern int arm_early_load_addr_dep (rtx, rtx);
|
||||
extern int arm_early_store_addr_dep (rtx, rtx);
|
||||
extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
|
||||
extern int arm_mac_accumulator_is_result (rtx, rtx);
|
||||
extern int arm_no_early_alu_shift_dep (rtx, rtx);
|
||||
extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
|
||||
extern int arm_no_early_mul_dep (rtx, rtx);
|
||||
extern int arm_no_early_store_addr_dep (rtx, rtx);
|
||||
extern bool arm_rtx_shift_left_p (rtx);
|
||||
|
||||
/* RTX cost table definitions. These are used when tuning for speed rather
|
||||
than for size and should reflect the _additional_ cost over the cost
|
||||
of the fastest instruction in the machine, which is COSTS_N_INSNS (1).
|
||||
Therefore it's okay for some costs to be 0.
|
||||
Costs may not have a negative value. */
|
||||
struct alu_cost_table
|
||||
{
|
||||
const int arith; /* ADD/SUB. */
|
||||
const int logical; /* AND/ORR/EOR/BIC, etc. */
|
||||
const int shift; /* Simple shift. */
|
||||
const int shift_reg; /* Simple shift by reg. */
|
||||
const int arith_shift; /* Additional when arith also shifts... */
|
||||
const int arith_shift_reg; /* ... and when the shift is by a reg. */
|
||||
const int log_shift; /* Additional when logic also shifts... */
|
||||
const int log_shift_reg; /* ... and when the shift is by a reg. */
|
||||
const int extnd; /* Zero/sign extension. */
|
||||
const int extnd_arith; /* Extend and arith. */
|
||||
const int bfi; /* Bit-field insert. */
|
||||
const int bfx; /* Bit-field extraction. */
|
||||
const int clz; /* Count Leading Zeros. */
|
||||
const int non_exec; /* Extra cost when not executing insn. */
|
||||
const bool non_exec_costs_exec; /* True if non-execution must add the exec
|
||||
cost. */
|
||||
};
|
||||
|
||||
struct mult_cost_table
|
||||
{
|
||||
const int simple;
|
||||
const int flag_setting; /* Additional cost if multiply sets flags. */
|
||||
const int extend;
|
||||
const int add;
|
||||
const int extend_add;
|
||||
const int idiv;
|
||||
};
|
||||
|
||||
/* Calculations of LDM costs are complex. We assume an initial cost
|
||||
(ldm_1st) which will load the number of registers mentioned in
|
||||
ldm_regs_per_insn_1st registers; then each additional
|
||||
ldm_regs_per_insn_subsequent registers cost one more insn.
|
||||
Similarly for STM operations.
|
||||
Therefore the ldm_regs_per_insn_1st/stm_regs_per_insn_1st and
|
||||
ldm_regs_per_insn_subsequent/stm_regs_per_insn_subsequent fields indicate
|
||||
the number of registers loaded/stored and are expressed by a simple integer
|
||||
and not by a COSTS_N_INSNS (N) expression.
|
||||
*/
|
||||
struct mem_cost_table
|
||||
{
|
||||
const int load;
|
||||
const int load_sign_extend; /* Additional to load cost. */
|
||||
const int ldrd; /* Cost of LDRD. */
|
||||
const int ldm_1st;
|
||||
const int ldm_regs_per_insn_1st;
|
||||
const int ldm_regs_per_insn_subsequent;
|
||||
const int loadf; /* SFmode. */
|
||||
const int loadd; /* DFmode. */
|
||||
const int load_unaligned; /* Extra for unaligned loads. */
|
||||
const int store;
|
||||
const int strd;
|
||||
const int stm_1st;
|
||||
const int stm_regs_per_insn_1st;
|
||||
const int stm_regs_per_insn_subsequent;
|
||||
const int storef; /* SFmode. */
|
||||
const int stored; /* DFmode. */
|
||||
const int store_unaligned; /* Extra for unaligned stores. */
|
||||
};
|
||||
|
||||
struct fp_cost_table
|
||||
{
|
||||
const int div;
|
||||
const int mult;
|
||||
const int mult_addsub; /* Non-fused. */
|
||||
const int fma; /* Fused. */
|
||||
const int addsub;
|
||||
const int fpconst; /* Immediate. */
|
||||
const int neg; /* NEG and ABS. */
|
||||
const int compare;
|
||||
const int widen; /* Widen to this size. */
|
||||
const int narrow; /* Narrow from this size. */
|
||||
const int toint;
|
||||
const int fromint;
|
||||
const int roundint; /* V8 round to integral, remains FP format. */
|
||||
};
|
||||
|
||||
struct vector_cost_table
|
||||
{
|
||||
const int alu;
|
||||
};
|
||||
|
||||
struct cpu_cost_table
|
||||
{
|
||||
const struct alu_cost_table alu;
|
||||
const struct mult_cost_table mult[2]; /* SImode and DImode. */
|
||||
const struct mem_cost_table ldst;
|
||||
const struct fp_cost_table fp[2]; /* SFmode and DFmode. */
|
||||
const struct vector_cost_table vect;
|
||||
};
|
||||
|
||||
|
||||
#endif /* GCC_AARCH_COMMON_PROTOS_H */
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
/* Definitions of target machine for GNU compiler, for ARM with a.out
|
||||
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk).
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ASM_APP_ON
|
||||
#define ASM_APP_ON ""
|
||||
#endif
|
||||
#ifndef ASM_APP_OFF
|
||||
#define ASM_APP_OFF ""
|
||||
#endif
|
||||
|
||||
/* Switch to the text or data segment. */
|
||||
#define TEXT_SECTION_ASM_OP "\t.text"
|
||||
#define DATA_SECTION_ASM_OP "\t.data"
|
||||
#define BSS_SECTION_ASM_OP "\t.bss"
|
||||
|
||||
/* Note: If USER_LABEL_PREFIX or LOCAL_LABEL_PREFIX are changed,
|
||||
make sure that this change is reflected in the function
|
||||
coff_arm_is_local_label_name() in bfd/coff-arm.c. */
|
||||
#ifndef REGISTER_PREFIX
|
||||
#define REGISTER_PREFIX ""
|
||||
#endif
|
||||
|
||||
#ifndef USER_LABEL_PREFIX
|
||||
#define USER_LABEL_PREFIX "_"
|
||||
#endif
|
||||
|
||||
#ifndef LOCAL_LABEL_PREFIX
|
||||
#define LOCAL_LABEL_PREFIX ""
|
||||
#endif
|
||||
|
||||
/* The assembler's names for the registers. Note that the ?xx registers are
|
||||
there so that VFPv3/NEON registers D16-D31 have the same spacing as D0-D15
|
||||
(each of which is overlaid on two S registers), although there are no
|
||||
actual single-precision registers which correspond to D16-D31. */
|
||||
#ifndef REGISTER_NAMES
|
||||
#define REGISTER_NAMES \
|
||||
{ \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
|
||||
"r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc", \
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
|
||||
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", \
|
||||
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", \
|
||||
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", \
|
||||
"d16", "?16", "d17", "?17", "d18", "?18", "d19", "?19", \
|
||||
"d20", "?20", "d21", "?21", "d22", "?22", "d23", "?23", \
|
||||
"d24", "?24", "d25", "?25", "d26", "?26", "d27", "?27", \
|
||||
"d28", "?28", "d29", "?29", "d30", "?30", "d31", "?31", \
|
||||
"wr0", "wr1", "wr2", "wr3", \
|
||||
"wr4", "wr5", "wr6", "wr7", \
|
||||
"wr8", "wr9", "wr10", "wr11", \
|
||||
"wr12", "wr13", "wr14", "wr15", \
|
||||
"wcgr0", "wcgr1", "wcgr2", "wcgr3", \
|
||||
"cc", "vfpcc", "sfp", "afp" \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ADDITIONAL_REGISTER_NAMES
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
{ \
|
||||
{"a1", 0}, \
|
||||
{"a2", 1}, \
|
||||
{"a3", 2}, \
|
||||
{"a4", 3}, \
|
||||
{"v1", 4}, \
|
||||
{"v2", 5}, \
|
||||
{"v3", 6}, \
|
||||
{"v4", 7}, \
|
||||
{"v5", 8}, \
|
||||
{"v6", 9}, \
|
||||
{"rfp", 9}, /* Historical. */ \
|
||||
{"sb", 9}, /* Historical. */ \
|
||||
{"v7", 10}, \
|
||||
{"sl", 10}, /* Historical. */ \
|
||||
{"r11", 11}, /* fp */ \
|
||||
{"r12", 12}, /* ip */ \
|
||||
{"r13", 13}, /* sp */ \
|
||||
{"r14", 14}, /* lr */ \
|
||||
{"r15", 15} /* pc */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERLAPPING_REGISTER_NAMES
|
||||
#define OVERLAPPING_REGISTER_NAMES \
|
||||
{ \
|
||||
{"d0", FIRST_VFP_REGNUM + 0, 2}, \
|
||||
{"d1", FIRST_VFP_REGNUM + 2, 2}, \
|
||||
{"d2", FIRST_VFP_REGNUM + 4, 2}, \
|
||||
{"d3", FIRST_VFP_REGNUM + 6, 2}, \
|
||||
{"d4", FIRST_VFP_REGNUM + 8, 2}, \
|
||||
{"d5", FIRST_VFP_REGNUM + 10, 2}, \
|
||||
{"d6", FIRST_VFP_REGNUM + 12, 2}, \
|
||||
{"d7", FIRST_VFP_REGNUM + 14, 2}, \
|
||||
{"d8", FIRST_VFP_REGNUM + 16, 2}, \
|
||||
{"d9", FIRST_VFP_REGNUM + 18, 2}, \
|
||||
{"d10", FIRST_VFP_REGNUM + 20, 2}, \
|
||||
{"d11", FIRST_VFP_REGNUM + 22, 2}, \
|
||||
{"d12", FIRST_VFP_REGNUM + 24, 2}, \
|
||||
{"d13", FIRST_VFP_REGNUM + 26, 2}, \
|
||||
{"d14", FIRST_VFP_REGNUM + 28, 2}, \
|
||||
{"d15", FIRST_VFP_REGNUM + 30, 2}, \
|
||||
{"q0", FIRST_VFP_REGNUM + 0, 4}, \
|
||||
{"q1", FIRST_VFP_REGNUM + 4, 4}, \
|
||||
{"q2", FIRST_VFP_REGNUM + 8, 4}, \
|
||||
{"q3", FIRST_VFP_REGNUM + 12, 4}, \
|
||||
{"q4", FIRST_VFP_REGNUM + 16, 4}, \
|
||||
{"q5", FIRST_VFP_REGNUM + 20, 4}, \
|
||||
{"q6", FIRST_VFP_REGNUM + 24, 4}, \
|
||||
{"q7", FIRST_VFP_REGNUM + 28, 4}, \
|
||||
{"q8", FIRST_VFP_REGNUM + 32, 4}, \
|
||||
{"q9", FIRST_VFP_REGNUM + 36, 4}, \
|
||||
{"q10", FIRST_VFP_REGNUM + 40, 4}, \
|
||||
{"q11", FIRST_VFP_REGNUM + 44, 4}, \
|
||||
{"q12", FIRST_VFP_REGNUM + 48, 4}, \
|
||||
{"q13", FIRST_VFP_REGNUM + 52, 4}, \
|
||||
{"q14", FIRST_VFP_REGNUM + 56, 4}, \
|
||||
{"q15", FIRST_VFP_REGNUM + 60, 4} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_DOLLAR_IN_LABEL
|
||||
#define NO_DOLLAR_IN_LABEL 1
|
||||
#endif
|
||||
|
||||
/* Generate DBX debugging information. riscix.h will undefine this because
|
||||
the native assembler does not support stabs. */
|
||||
#define DBX_DEBUGGING_INFO 1
|
||||
|
||||
/* Acorn dbx moans about continuation chars, so don't use any. */
|
||||
#ifndef DBX_CONTIN_LENGTH
|
||||
#define DBX_CONTIN_LENGTH 0
|
||||
#endif
|
||||
|
||||
/* Output a function label definition. */
|
||||
#ifndef ASM_DECLARE_FUNCTION_NAME
|
||||
#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ARM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Globalizing directive for a label. */
|
||||
#define GLOBAL_ASM_OP "\t.global\t"
|
||||
|
||||
/* Make an internal label into a string. */
|
||||
#ifndef ASM_GENERATE_INTERNAL_LABEL
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
|
||||
sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM))
|
||||
#endif
|
||||
|
||||
/* Output an element of a dispatch table. */
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
|
||||
do \
|
||||
{ \
|
||||
gcc_assert (!TARGET_THUMB2); \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/* Thumb-2 always uses addr_diff_elf so that the Table Branch instructions
|
||||
can be used. For non-pic code where the offsets do not suitable for
|
||||
TBB/TBH the elements are output as absolute labels. */
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_ARM) \
|
||||
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE); \
|
||||
else if (TARGET_THUMB1) \
|
||||
{ \
|
||||
if (flag_pic || optimize_size) \
|
||||
{ \
|
||||
switch (GET_MODE(body)) \
|
||||
{ \
|
||||
case QImode: \
|
||||
asm_fprintf (STREAM, "\t.byte\t(%LL%d-%LL%d)/2\n", \
|
||||
VALUE, REL); \
|
||||
break; \
|
||||
case HImode: /* TBH */ \
|
||||
asm_fprintf (STREAM, "\t.2byte\t(%LL%d-%LL%d)/2\n", \
|
||||
VALUE, REL); \
|
||||
break; \
|
||||
case SImode: \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d-%LL%d\n", \
|
||||
VALUE, REL); \
|
||||
break; \
|
||||
default: \
|
||||
gcc_unreachable(); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d+1\n", VALUE); \
|
||||
} \
|
||||
else /* Thumb-2 */ \
|
||||
{ \
|
||||
switch (GET_MODE(body)) \
|
||||
{ \
|
||||
case QImode: /* TBB */ \
|
||||
asm_fprintf (STREAM, "\t.byte\t(%LL%d-%LL%d)/2\n", \
|
||||
VALUE, REL); \
|
||||
break; \
|
||||
case HImode: /* TBH */ \
|
||||
asm_fprintf (STREAM, "\t.2byte\t(%LL%d-%LL%d)/2\n", \
|
||||
VALUE, REL); \
|
||||
break; \
|
||||
case SImode: \
|
||||
if (flag_pic) \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d+1-%LL%d\n", VALUE, REL); \
|
||||
else \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d+1\n", VALUE); \
|
||||
break; \
|
||||
default: \
|
||||
gcc_unreachable(); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
#undef ASM_OUTPUT_ASCII
|
||||
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
|
||||
output_ascii_pseudo_op (STREAM, (const unsigned char *) (PTR), LEN)
|
||||
|
||||
/* Output a gap. In fact we fill it with nulls. */
|
||||
#undef ASM_OUTPUT_SKIP
|
||||
#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
|
||||
fprintf (STREAM, "\t.space\t%d\n", (int) (NBYTES))
|
||||
|
||||
/* Align output to a power of two. Horrible /bin/as. */
|
||||
#ifndef ASM_OUTPUT_ALIGN
|
||||
#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
|
||||
do \
|
||||
{ \
|
||||
register int amount = 1 << (POWER); \
|
||||
\
|
||||
if (amount == 2) \
|
||||
fprintf (STREAM, "\t.even\n"); \
|
||||
else if (amount != 1) \
|
||||
fprintf (STREAM, "\t.align\t%d\n", amount - 4); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a common block. */
|
||||
#ifndef ASM_OUTPUT_COMMON
|
||||
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.comm\t"); \
|
||||
assemble_name (STREAM, NAME); \
|
||||
asm_fprintf (STREAM, ", %d\t%@ %d\n", \
|
||||
(int)(ROUNDED), (int)(SIZE)); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a local common block. /bin/as can't do this, so hack a
|
||||
`.space' into the bss segment. Note that this is *bad* practice,
|
||||
which is guaranteed NOT to work since it doesn't define STATIC
|
||||
COMMON space but merely STATIC BSS space. */
|
||||
#ifndef ASM_OUTPUT_ALIGNED_LOCAL
|
||||
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
switch_to_section (bss_section); \
|
||||
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE)); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a zero-initialized block. */
|
||||
#ifndef ASM_OUTPUT_ALIGNED_BSS
|
||||
#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGN) \
|
||||
asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGN)
|
||||
#endif
|
||||
|
||||
#ifndef ASM_COMMENT_START
|
||||
#define ASM_COMMENT_START "@"
|
||||
#endif
|
||||
|
||||
/* This works for GAS and some other assemblers. */
|
||||
#define SET_ASM_OP "\t.set\t"
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/* ARM CPU Cores
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
Written by CodeSourcery, LLC
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Before using #include to read this file, define a macro:
|
||||
|
||||
ARM_CORE(CORE_NAME, CORE_IDENT, ARCH, FLAGS, COSTS)
|
||||
|
||||
The CORE_NAME is the name of the core, represented as a string constant.
|
||||
The CORE_IDENT is the name of the core, represented as an identifier.
|
||||
ARCH is the architecture revision implemented by the chip.
|
||||
FLAGS are the bitwise-or of the traits that apply to that core.
|
||||
This need not include flags implied by the architecture.
|
||||
COSTS is the name of the rtx_costs routine to use.
|
||||
|
||||
If you update this table, you must update the "tune" attribute in
|
||||
arm.md.
|
||||
|
||||
Some tools assume no whitespace up to the first "," in each entry. */
|
||||
|
||||
/* V2/V2A Architecture Processors */
|
||||
ARM_CORE("arm2", arm2, 2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm250", arm250, 2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm3", arm3, 2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
|
||||
/* V3 Architecture Processors */
|
||||
ARM_CORE("arm6", arm6, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm60", arm60, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm600", arm600, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm610", arm610, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm620", arm620, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm7", arm7, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm7d", arm7d, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm7di", arm7di, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm70", arm70, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm700", arm700, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm700i", arm700i, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm710", arm710, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm720", arm720, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm710c", arm710c, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm7100", arm7100, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm7500", arm7500, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
/* Doesn't have an external co-proc, but does have embedded fpa. */
|
||||
ARM_CORE("arm7500fe", arm7500fe, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
|
||||
/* V3M Architecture Processors */
|
||||
/* arm7m doesn't exist on its own, but only with D, ("and", and I), but
|
||||
those don't alter the code, so arm7m is sometimes used. */
|
||||
ARM_CORE("arm7m", arm7m, 3M, FL_CO_PROC | FL_MODE26, fastmul)
|
||||
ARM_CORE("arm7dm", arm7dm, 3M, FL_CO_PROC | FL_MODE26, fastmul)
|
||||
ARM_CORE("arm7dmi", arm7dmi, 3M, FL_CO_PROC | FL_MODE26, fastmul)
|
||||
|
||||
/* V4 Architecture Processors */
|
||||
ARM_CORE("arm8", arm8, 4, FL_MODE26 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm810", arm810, 4, FL_MODE26 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE("strongarm", strongarm, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, strongarm)
|
||||
ARM_CORE("strongarm110", strongarm110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, strongarm)
|
||||
ARM_CORE("strongarm1100", strongarm1100, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, strongarm)
|
||||
ARM_CORE("strongarm1110", strongarm1110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, strongarm)
|
||||
ARM_CORE("fa526", fa526, 4, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("fa626", fa626, 4, FL_LDSCHED, fastmul)
|
||||
|
||||
/* V4T Architecture Processors */
|
||||
ARM_CORE("arm7tdmi", arm7tdmi, 4T, FL_CO_PROC , fastmul)
|
||||
ARM_CORE("arm7tdmi-s", arm7tdmis, 4T, FL_CO_PROC , fastmul)
|
||||
ARM_CORE("arm710t", arm710t, 4T, FL_WBUF, fastmul)
|
||||
ARM_CORE("arm720t", arm720t, 4T, FL_WBUF, fastmul)
|
||||
ARM_CORE("arm740t", arm740t, 4T, FL_WBUF, fastmul)
|
||||
ARM_CORE("arm9", arm9, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm9tdmi", arm9tdmi, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm920", arm920, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm920t", arm920t, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm922t", arm922t, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm940t", arm940t, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("ep9312", ep9312, 4T, FL_LDSCHED, fastmul)
|
||||
|
||||
/* V5T Architecture Processors */
|
||||
ARM_CORE("arm10tdmi", arm10tdmi, 5T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm1020t", arm1020t, 5T, FL_LDSCHED, fastmul)
|
||||
|
||||
/* V5TE Architecture Processors */
|
||||
ARM_CORE("arm9e", arm9e, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm946e-s", arm946es, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm966e-s", arm966es, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm968e-s", arm968es, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm10e", arm10e, 5TE, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm1020e", arm1020e, 5TE, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm1022e", arm1022e, 5TE, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("xscale", xscale, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale)
|
||||
ARM_CORE("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
|
||||
ARM_CORE("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2, xscale)
|
||||
ARM_CORE("fa606te", fa606te, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("fa626te", fa626te, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("fmp626", fmp626, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("fa726te", fa726te, 5TE, FL_LDSCHED, fa726te)
|
||||
|
||||
/* V5TEJ Architecture Processors */
|
||||
ARM_CORE("arm926ej-s", arm926ejs, 5TEJ, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm1026ej-s", arm1026ejs, 5TEJ, FL_LDSCHED, 9e)
|
||||
|
||||
/* V6 Architecture Processors */
|
||||
ARM_CORE("arm1136j-s", arm1136js, 6J, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm1136jf-s", arm1136jfs, 6J, FL_LDSCHED | FL_VFPV2, 9e)
|
||||
ARM_CORE("arm1176jz-s", arm1176jzs, 6ZK, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm1176jzf-s", arm1176jzfs, 6ZK, FL_LDSCHED | FL_VFPV2, 9e)
|
||||
ARM_CORE("mpcorenovfp", mpcorenovfp, 6K, FL_LDSCHED, 9e)
|
||||
ARM_CORE("mpcore", mpcore, 6K, FL_LDSCHED | FL_VFPV2, 9e)
|
||||
ARM_CORE("arm1156t2-s", arm1156t2s, 6T2, FL_LDSCHED, v6t2)
|
||||
ARM_CORE("arm1156t2f-s", arm1156t2fs, 6T2, FL_LDSCHED | FL_VFPV2, v6t2)
|
||||
ARM_CORE("generic-armv7-a", genericv7a, 7A, FL_LDSCHED, cortex)
|
||||
ARM_CORE("cortex-a5", cortexa5, 7A, FL_LDSCHED, cortex_a5)
|
||||
ARM_CORE("cortex-a7", cortexa7, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex)
|
||||
ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, cortex)
|
||||
ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, cortex_a9)
|
||||
ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
|
||||
ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, cortex)
|
||||
ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, cortex)
|
||||
ARM_CORE("cortex-r5", cortexr5, 7R, FL_LDSCHED | FL_ARM_DIV, cortex)
|
||||
ARM_CORE("cortex-r7", cortexr7, 7R, FL_LDSCHED | FL_ARM_DIV, cortex)
|
||||
ARM_CORE("cortex-m4", cortexm4, 7EM, FL_LDSCHED, v7m)
|
||||
ARM_CORE("cortex-m3", cortexm3, 7M, FL_LDSCHED, v7m)
|
||||
ARM_CORE("cortex-m1", cortexm1, 6M, FL_LDSCHED, v6m)
|
||||
ARM_CORE("cortex-m0", cortexm0, 6M, FL_LDSCHED, v6m)
|
||||
ARM_CORE("cortex-m0plus", cortexm0plus, 6M, FL_LDSCHED, v6m)
|
||||
ARM_CORE("marvell-pj4", marvell_pj4, 7A, FL_LDSCHED, 9e)
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/* Definitions for option handling for ARM.
|
||||
Copyright (C) 1991-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ARM_OPTS_H
|
||||
#define ARM_OPTS_H
|
||||
|
||||
/* The various ARM cores. */
|
||||
enum processor_type
|
||||
{
|
||||
#define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \
|
||||
IDENT,
|
||||
#include "arm-cores.def"
|
||||
#undef ARM_CORE
|
||||
/* Used to indicate that no processor has been specified. */
|
||||
arm_none
|
||||
};
|
||||
|
||||
/* Which __fp16 format to use.
|
||||
The enumeration values correspond to the numbering for the
|
||||
Tag_ABI_FP_16bit_format attribute.
|
||||
*/
|
||||
enum arm_fp16_format_type
|
||||
{
|
||||
ARM_FP16_FORMAT_NONE = 0,
|
||||
ARM_FP16_FORMAT_IEEE = 1,
|
||||
ARM_FP16_FORMAT_ALTERNATIVE = 2
|
||||
};
|
||||
|
||||
/* Which ABI to use. */
|
||||
enum arm_abi_type
|
||||
{
|
||||
ARM_ABI_APCS,
|
||||
ARM_ABI_ATPCS,
|
||||
ARM_ABI_AAPCS,
|
||||
ARM_ABI_IWMMXT,
|
||||
ARM_ABI_AAPCS_LINUX
|
||||
};
|
||||
|
||||
enum float_abi_type
|
||||
{
|
||||
ARM_FLOAT_ABI_SOFT,
|
||||
ARM_FLOAT_ABI_SOFTFP,
|
||||
ARM_FLOAT_ABI_HARD
|
||||
};
|
||||
|
||||
/* Which thread pointer access sequence to use. */
|
||||
enum arm_tp_type {
|
||||
TP_AUTO,
|
||||
TP_SOFT,
|
||||
TP_CP15
|
||||
};
|
||||
|
||||
/* Which TLS scheme to use. */
|
||||
enum arm_tls_type {
|
||||
TLS_GNU,
|
||||
TLS_GNU2
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/* Prototypes for exported functions defined in arm.c and pe.c
|
||||
Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@arm.com)
|
||||
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_ARM_PROTOS_H
|
||||
#define GCC_ARM_PROTOS_H
|
||||
|
||||
extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *);
|
||||
extern int use_return_insn (int, rtx);
|
||||
extern enum reg_class arm_regno_class (int);
|
||||
extern void arm_load_pic_register (unsigned long);
|
||||
extern int arm_volatile_func (void);
|
||||
extern void arm_expand_prologue (void);
|
||||
extern void arm_expand_epilogue (bool);
|
||||
extern void thumb2_expand_return (void);
|
||||
extern const char *arm_strip_name_encoding (const char *);
|
||||
extern void arm_asm_output_labelref (FILE *, const char *);
|
||||
extern void thumb2_asm_output_opcode (FILE *);
|
||||
extern unsigned long arm_current_func_type (void);
|
||||
extern HOST_WIDE_INT arm_compute_initial_elimination_offset (unsigned int,
|
||||
unsigned int);
|
||||
extern HOST_WIDE_INT thumb_compute_initial_elimination_offset (unsigned int,
|
||||
unsigned int);
|
||||
extern unsigned int arm_dbx_register_number (unsigned int);
|
||||
extern void arm_output_fn_unwind (FILE *, bool);
|
||||
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern bool arm_vector_mode_supported_p (enum machine_mode);
|
||||
extern bool arm_small_register_classes_for_mode_p (enum machine_mode);
|
||||
extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
|
||||
extern bool arm_modes_tieable_p (enum machine_mode, enum machine_mode);
|
||||
extern int const_ok_for_arm (HOST_WIDE_INT);
|
||||
extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
|
||||
extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
|
||||
extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
|
||||
HOST_WIDE_INT, rtx, rtx, int);
|
||||
extern int legitimate_pic_operand_p (rtx);
|
||||
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
||||
extern rtx legitimize_tls_address (rtx, rtx);
|
||||
extern int arm_legitimate_address_outer_p (enum machine_mode, rtx, RTX_CODE, int);
|
||||
extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
|
||||
extern bool arm_legitimize_reload_address (rtx *, enum machine_mode, int, int,
|
||||
int);
|
||||
extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int,
|
||||
int);
|
||||
extern int thumb1_legitimate_address_p (enum machine_mode, rtx, int);
|
||||
extern bool ldm_stm_operation_p (rtx, bool, enum machine_mode mode,
|
||||
bool, bool);
|
||||
extern int arm_const_double_rtx (rtx);
|
||||
extern int vfp3_const_double_rtx (rtx);
|
||||
extern int neon_immediate_valid_for_move (rtx, enum machine_mode, rtx *, int *);
|
||||
extern int neon_immediate_valid_for_logic (rtx, enum machine_mode, int, rtx *,
|
||||
int *);
|
||||
extern int neon_immediate_valid_for_shift (rtx, enum machine_mode, rtx *,
|
||||
int *, bool);
|
||||
extern char *neon_output_logic_immediate (const char *, rtx *,
|
||||
enum machine_mode, int, int);
|
||||
extern char *neon_output_shift_immediate (const char *, char, rtx *,
|
||||
enum machine_mode, int, bool);
|
||||
extern void neon_pairwise_reduce (rtx, rtx, enum machine_mode,
|
||||
rtx (*) (rtx, rtx, rtx));
|
||||
extern rtx neon_make_constant (rtx);
|
||||
extern void neon_expand_vector_init (rtx, rtx);
|
||||
extern void neon_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
|
||||
extern void neon_const_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
|
||||
extern HOST_WIDE_INT neon_element_bits (enum machine_mode);
|
||||
extern void neon_reinterpret (rtx, rtx);
|
||||
extern void neon_emit_pair_result_insn (enum machine_mode,
|
||||
rtx (*) (rtx, rtx, rtx, rtx),
|
||||
rtx, rtx, rtx);
|
||||
extern void neon_disambiguate_copy (rtx *, rtx *, rtx *, unsigned int);
|
||||
extern void neon_split_vcombine (rtx op[3]);
|
||||
extern enum reg_class coproc_secondary_reload_class (enum machine_mode, rtx,
|
||||
bool);
|
||||
extern bool arm_tls_referenced_p (rtx);
|
||||
|
||||
extern int arm_coproc_mem_operand (rtx, bool);
|
||||
extern int neon_vector_mem_operand (rtx, int);
|
||||
extern int neon_struct_mem_operand (rtx);
|
||||
extern int arm_no_early_store_addr_dep (rtx, rtx);
|
||||
extern int arm_early_store_addr_dep (rtx, rtx);
|
||||
extern int arm_early_load_addr_dep (rtx, rtx);
|
||||
extern int arm_no_early_alu_shift_dep (rtx, rtx);
|
||||
extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
|
||||
extern int arm_no_early_mul_dep (rtx, rtx);
|
||||
extern int arm_mac_accumulator_is_result (rtx, rtx);
|
||||
extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
|
||||
|
||||
extern int tls_mentioned_p (rtx);
|
||||
extern int symbol_mentioned_p (rtx);
|
||||
extern int label_mentioned_p (rtx);
|
||||
extern RTX_CODE minmax_code (rtx);
|
||||
extern bool arm_sat_operator_match (rtx, rtx, int *, bool *);
|
||||
extern int adjacent_mem_locations (rtx, rtx);
|
||||
extern bool gen_ldm_seq (rtx *, int, bool);
|
||||
extern bool gen_stm_seq (rtx *, int);
|
||||
extern bool gen_const_stm_seq (rtx *, int);
|
||||
extern rtx arm_gen_load_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);
|
||||
extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);
|
||||
extern bool offset_ok_for_ldrd_strd (HOST_WIDE_INT);
|
||||
extern bool operands_ok_ldrd_strd (rtx, rtx, rtx, HOST_WIDE_INT, bool, bool);
|
||||
extern int arm_gen_movmemqi (rtx *);
|
||||
extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
|
||||
extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,
|
||||
HOST_WIDE_INT);
|
||||
extern rtx arm_gen_compare_reg (RTX_CODE, rtx, rtx, rtx);
|
||||
extern rtx arm_gen_return_addr_mask (void);
|
||||
extern void arm_reload_in_hi (rtx *);
|
||||
extern void arm_reload_out_hi (rtx *);
|
||||
extern int arm_max_const_double_inline_cost (void);
|
||||
extern int arm_const_double_inline_cost (rtx);
|
||||
extern bool arm_const_double_by_parts (rtx);
|
||||
extern bool arm_const_double_by_immediates (rtx);
|
||||
extern const char *fp_immediate_constant (rtx);
|
||||
extern void arm_emit_call_insn (rtx, rtx);
|
||||
extern const char *output_call (rtx *);
|
||||
extern const char *output_call_mem (rtx *);
|
||||
void arm_emit_movpair (rtx, rtx);
|
||||
extern const char *output_mov_long_double_arm_from_arm (rtx *);
|
||||
extern const char *output_move_double (rtx *, bool, int *count);
|
||||
extern const char *output_move_quad (rtx *);
|
||||
extern int arm_count_output_move_double_insns (rtx *);
|
||||
extern const char *output_move_vfp (rtx *operands);
|
||||
extern const char *output_move_neon (rtx *operands);
|
||||
extern int arm_attr_length_move_neon (rtx);
|
||||
extern int arm_address_offset_is_imm (rtx);
|
||||
extern const char *output_add_immediate (rtx *);
|
||||
extern const char *arithmetic_instr (rtx, int);
|
||||
extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
|
||||
extern const char *output_return_instruction (rtx, bool, bool, bool);
|
||||
extern void arm_poke_function_name (FILE *, const char *);
|
||||
extern void arm_final_prescan_insn (rtx);
|
||||
extern int arm_debugger_arg_offset (int, rtx);
|
||||
extern bool arm_is_long_call_p (tree);
|
||||
extern int arm_emit_vector_const (FILE *, rtx);
|
||||
extern void arm_emit_fp16_const (rtx c);
|
||||
extern const char * arm_output_load_gr (rtx *);
|
||||
extern const char *vfp_output_fstmd (rtx *);
|
||||
extern void arm_output_multireg_pop (rtx *, bool, rtx, bool, bool);
|
||||
extern void arm_set_return_address (rtx, rtx);
|
||||
extern int arm_eliminable_register (rtx);
|
||||
extern const char *arm_output_shift(rtx *, int);
|
||||
extern const char *arm_output_iwmmxt_shift_immediate (const char *, rtx *, bool);
|
||||
extern const char *arm_output_iwmmxt_tinsr (rtx *);
|
||||
extern unsigned int arm_sync_loop_insns (rtx , rtx *);
|
||||
extern int arm_attr_length_push_multi(rtx, rtx);
|
||||
extern void arm_expand_compare_and_swap (rtx op[]);
|
||||
extern void arm_split_compare_and_swap (rtx op[]);
|
||||
extern void arm_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
|
||||
extern rtx arm_load_tp (rtx);
|
||||
|
||||
#if defined TREE_CODE
|
||||
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
|
||||
extern bool arm_pad_arg_upward (enum machine_mode, const_tree);
|
||||
extern bool arm_pad_reg_upward (enum machine_mode, tree, int);
|
||||
#endif
|
||||
extern int arm_apply_result_size (void);
|
||||
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
/* Thumb functions. */
|
||||
extern void arm_init_expanders (void);
|
||||
extern const char *thumb1_unexpanded_epilogue (void);
|
||||
extern void thumb1_expand_prologue (void);
|
||||
extern void thumb1_expand_epilogue (void);
|
||||
extern const char *thumb1_output_interwork (void);
|
||||
#ifdef TREE_CODE
|
||||
extern int is_called_in_ARM_mode (tree);
|
||||
#endif
|
||||
extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
|
||||
#ifdef RTX_CODE
|
||||
extern enum arm_cond_code maybe_get_arm_condition_code (rtx);
|
||||
extern void thumb1_final_prescan_insn (rtx);
|
||||
extern void thumb2_final_prescan_insn (rtx);
|
||||
extern const char *thumb_load_double_from_address (rtx *);
|
||||
extern const char *thumb_output_move_mem_multiple (int, rtx *);
|
||||
extern const char *thumb_call_via_reg (rtx);
|
||||
extern void thumb_expand_movmemqi (rtx *);
|
||||
extern rtx arm_return_addr (int, rtx);
|
||||
extern void thumb_reload_out_hi (rtx *);
|
||||
extern void thumb_reload_in_hi (rtx *);
|
||||
extern void thumb_set_return_address (rtx, rtx);
|
||||
extern const char *thumb1_output_casesi (rtx *);
|
||||
extern const char *thumb2_output_casesi (rtx *);
|
||||
#endif
|
||||
|
||||
/* Defined in pe.c. */
|
||||
extern int arm_dllexport_name_p (const char *);
|
||||
extern int arm_dllimport_name_p (const char *);
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern void arm_pe_unique_section (tree, int);
|
||||
extern void arm_pe_encode_section_info (tree, rtx, int);
|
||||
extern int arm_dllexport_p (tree);
|
||||
extern int arm_dllimport_p (tree);
|
||||
extern void arm_mark_dllexport (tree);
|
||||
extern void arm_mark_dllimport (tree);
|
||||
#endif
|
||||
|
||||
extern void arm_pr_long_calls (struct cpp_reader *);
|
||||
extern void arm_pr_no_long_calls (struct cpp_reader *);
|
||||
extern void arm_pr_long_calls_off (struct cpp_reader *);
|
||||
|
||||
extern void arm_lang_object_attributes_init(void);
|
||||
|
||||
extern const char *arm_mangle_type (const_tree);
|
||||
|
||||
extern void arm_order_regs_for_local_alloc (void);
|
||||
|
||||
/* Vectorizer cost model implementation. */
|
||||
struct cpu_vec_costs {
|
||||
const int scalar_stmt_cost; /* Cost of any scalar operation, excluding
|
||||
load and store. */
|
||||
const int scalar_load_cost; /* Cost of scalar load. */
|
||||
const int scalar_store_cost; /* Cost of scalar store. */
|
||||
const int vec_stmt_cost; /* Cost of any vector operation, excluding
|
||||
load, store, vector-to-scalar and
|
||||
scalar-to-vector operation. */
|
||||
const int vec_to_scalar_cost; /* Cost of vect-to-scalar operation. */
|
||||
const int scalar_to_vec_cost; /* Cost of scalar-to-vector operation. */
|
||||
const int vec_align_load_cost; /* Cost of aligned vector load. */
|
||||
const int vec_unalign_load_cost; /* Cost of unaligned vector load. */
|
||||
const int vec_unalign_store_cost; /* Cost of unaligned vector load. */
|
||||
const int vec_store_cost; /* Cost of vector store. */
|
||||
const int cond_taken_branch_cost; /* Cost of taken branch for vectorizer
|
||||
cost model. */
|
||||
const int cond_not_taken_branch_cost;/* Cost of not taken branch for
|
||||
vectorizer cost model. */
|
||||
};
|
||||
|
||||
#ifdef RTX_CODE
|
||||
/* This needs to be here because we need RTX_CODE and similar. */
|
||||
|
||||
struct cpu_cost_table;
|
||||
|
||||
struct tune_params
|
||||
{
|
||||
bool (*rtx_costs) (rtx, RTX_CODE, RTX_CODE, int *, bool);
|
||||
const struct cpu_cost_table *insn_extra_cost;
|
||||
bool (*sched_adjust_cost) (rtx, rtx, rtx, int *);
|
||||
int constant_limit;
|
||||
/* Maximum number of instructions to conditionalise in
|
||||
arm_final_prescan_insn. */
|
||||
int max_insns_skipped;
|
||||
int num_prefetch_slots;
|
||||
int l1_cache_size;
|
||||
int l1_cache_line_size;
|
||||
bool prefer_constant_pool;
|
||||
int (*branch_cost) (bool, bool);
|
||||
/* Prefer STRD/LDRD instructions over PUSH/POP/LDM/STM. */
|
||||
bool prefer_ldrd_strd;
|
||||
/* The preference for non short cirtcuit operation when optimizing for
|
||||
performance. The first element covers Thumb state and the second one
|
||||
is for ARM state. */
|
||||
bool logical_op_non_short_circuit[2];
|
||||
/* Vectorizer costs. */
|
||||
const struct cpu_vec_costs* vec_costs;
|
||||
};
|
||||
|
||||
extern const struct tune_params *current_tune;
|
||||
extern int vfp3_const_double_for_fract_bits (rtx);
|
||||
|
||||
extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx,
|
||||
rtx);
|
||||
extern bool arm_validize_comparison (rtx *, rtx *, rtx *);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
|
||||
extern bool arm_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
|
||||
|
||||
extern bool arm_autoinc_modes_ok_p (enum machine_mode, enum arm_auto_incmodes);
|
||||
|
||||
extern void arm_emit_eabi_attribute (const char *, int, int);
|
||||
|
||||
#endif /* ! GCC_ARM_PROTOS_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,147 @@
|
|||
/* Configuration file for ARM BPABI targets.
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
Contributed by CodeSourcery, LLC
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Use the AAPCS ABI by default. */
|
||||
#define ARM_DEFAULT_ABI ARM_ABI_AAPCS
|
||||
|
||||
/* Assume that AAPCS ABIs should adhere to the full BPABI. */
|
||||
#define TARGET_BPABI (TARGET_AAPCS_BASED)
|
||||
|
||||
/* BPABI targets use EABI frame unwinding tables. */
|
||||
#undef ARM_UNWIND_INFO
|
||||
#define ARM_UNWIND_INFO 1
|
||||
|
||||
/* Section 4.1 of the AAPCS requires the use of VFP format. */
|
||||
#undef FPUTYPE_DEFAULT
|
||||
#define FPUTYPE_DEFAULT "vfp"
|
||||
|
||||
/* TARGET_BIG_ENDIAN_DEFAULT is set in
|
||||
config.gcc for big endian configurations. */
|
||||
#if TARGET_BIG_ENDIAN_DEFAULT
|
||||
#define TARGET_ENDIAN_DEFAULT MASK_BIG_END
|
||||
#else
|
||||
#define TARGET_ENDIAN_DEFAULT 0
|
||||
#endif
|
||||
|
||||
/* EABI targets should enable interworking by default. */
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT (MASK_INTERWORK | TARGET_ENDIAN_DEFAULT)
|
||||
|
||||
/* The ARM BPABI functions return a boolean; they use no special
|
||||
calling convention. */
|
||||
#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) TARGET_BPABI
|
||||
|
||||
/* The BPABI integer comparison routines return { -1, 0, 1 }. */
|
||||
#define TARGET_LIB_INT_CMP_BIASED !TARGET_BPABI
|
||||
|
||||
#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*"\
|
||||
"|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}"
|
||||
|
||||
#if TARGET_BIG_ENDIAN_DEFAULT
|
||||
#define BE8_LINK_SPEC \
|
||||
" %{!mlittle-endian:%{march=armv7-a|mcpu=cortex-a5 \
|
||||
|mcpu=cortex-a7 \
|
||||
|mcpu=cortex-a8|mcpu=cortex-a9|mcpu=cortex-a15 \
|
||||
|mcpu=marvell-pj4 \
|
||||
|mcpu=generic-armv7-a \
|
||||
|march=armv7-m|mcpu=cortex-m3 \
|
||||
|march=armv7e-m|mcpu=cortex-m4 \
|
||||
|march=armv6-m|mcpu=cortex-m0 \
|
||||
|march=armv8-a \
|
||||
:%{!r:--be8}}}"
|
||||
#else
|
||||
#define BE8_LINK_SPEC \
|
||||
" %{mbig-endian:%{march=armv7-a|mcpu=cortex-a5 \
|
||||
|mcpu=cortex-a7 \
|
||||
|mcpu=cortex-a8|mcpu=cortex-a9|mcpu=cortex-a15 \
|
||||
|mcpu=marvell-pj4 \
|
||||
|mcpu=generic-armv7-a \
|
||||
|march=armv7-m|mcpu=cortex-m3 \
|
||||
|march=armv7e-m|mcpu=cortex-m4 \
|
||||
|march=armv6-m|mcpu=cortex-m0 \
|
||||
|march=armv8-a \
|
||||
:%{!r:--be8}}}"
|
||||
#endif
|
||||
|
||||
/* Tell the assembler to build BPABI binaries. */
|
||||
#undef SUBTARGET_EXTRA_ASM_SPEC
|
||||
#define SUBTARGET_EXTRA_ASM_SPEC \
|
||||
"%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC
|
||||
|
||||
#ifndef SUBTARGET_EXTRA_LINK_SPEC
|
||||
#define SUBTARGET_EXTRA_LINK_SPEC ""
|
||||
#endif
|
||||
|
||||
/* The generic link spec in elf.h does not support shared libraries. */
|
||||
#define BPABI_LINK_SPEC \
|
||||
"%{mbig-endian:-EB} %{mlittle-endian:-EL} " \
|
||||
"%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} " \
|
||||
"-X" SUBTARGET_EXTRA_LINK_SPEC TARGET_FIX_V4BX_SPEC BE8_LINK_SPEC
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC BPABI_LINK_SPEC
|
||||
|
||||
/* The BPABI requires that we always use an out-of-line implementation
|
||||
of RTTI comparison, even if the target supports weak symbols,
|
||||
because the same object file might be used on a target that does
|
||||
not support merging symbols across DLL boundaries. This macro is
|
||||
broken out separately so that it can be used within
|
||||
TARGET_OS_CPP_BUILTINS in configuration files for systems based on
|
||||
the BPABI. */
|
||||
#define TARGET_BPABI_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
builtin_define ("__GXX_TYPEINFO_EQUALITY_INLINE=0"); \
|
||||
} \
|
||||
while (false)
|
||||
|
||||
#undef TARGET_OS_CPP_BUILTINS
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
TARGET_BPABI_CPP_BUILTINS()
|
||||
|
||||
/* The BPABI specifies the use of .{init,fini}_array. Therefore, we
|
||||
do not want GCC to put anything into the .{init,fini} sections. */
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#undef FINI_SECTION_ASM_OP
|
||||
#define INIT_ARRAY_SECTION_ASM_OP ARM_EABI_CTORS_SECTION_OP
|
||||
#define FINI_ARRAY_SECTION_ASM_OP ARM_EABI_DTORS_SECTION_OP
|
||||
|
||||
/* The legacy _mcount implementation assumes r11 points to a
|
||||
4-word APCS frame. This is generally not true for EABI targets,
|
||||
particularly not in Thumb mode. We assume the mcount
|
||||
implementation does not require a counter variable (No Counter).
|
||||
Note that __gnu_mcount_nc will be entered with a misaligned stack.
|
||||
This is OK because it uses a special calling convention anyway. */
|
||||
|
||||
#undef NO_PROFILE_COUNTERS
|
||||
#define NO_PROFILE_COUNTERS 1
|
||||
#undef ARM_FUNCTION_PROFILER
|
||||
#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \
|
||||
{ \
|
||||
fprintf (STREAM, "\tpush\t{lr}\n"); \
|
||||
fprintf (STREAM, "\tbl\t__gnu_mcount_nc\n"); \
|
||||
}
|
||||
|
||||
#undef SUBTARGET_FRAME_POINTER_REQUIRED
|
||||
#define SUBTARGET_FRAME_POINTER_REQUIRED 0
|
||||
|
||||
/* __gnu_mcount_nc restores the original LR value before returning. Ensure
|
||||
that there is no unnecessary hook set up. */
|
||||
#undef PROFILE_HOOK
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/* Definitions of target machine for GNU compiler.
|
||||
For ARM with ELF obj format.
|
||||
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
||||
Contributed by Philip Blundell <philb@gnu.org> and
|
||||
Catherine Moore <clm@cygnus.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef OBJECT_FORMAT_ELF
|
||||
#error elf.h included before elfos.h
|
||||
#endif
|
||||
|
||||
#ifndef LOCAL_LABEL_PREFIX
|
||||
#define LOCAL_LABEL_PREFIX "."
|
||||
#endif
|
||||
|
||||
#ifndef SUBTARGET_CPP_SPEC
|
||||
#define SUBTARGET_CPP_SPEC "-D__ELF__"
|
||||
#endif
|
||||
|
||||
#ifndef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
|
||||
{ "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
|
||||
SUBSUBTARGET_EXTRA_SPECS
|
||||
#endif
|
||||
|
||||
#ifndef SUBTARGET_EXTRA_ASM_SPEC
|
||||
#define SUBTARGET_EXTRA_ASM_SPEC ""
|
||||
#endif
|
||||
|
||||
#ifndef SUBTARGET_ASM_FLOAT_SPEC
|
||||
#define SUBTARGET_ASM_FLOAT_SPEC "\
|
||||
%{mapcs-float:-mfloat}"
|
||||
#endif
|
||||
|
||||
#undef SUBSUBTARGET_EXTRA_SPECS
|
||||
#define SUBSUBTARGET_EXTRA_SPECS
|
||||
|
||||
#ifndef ASM_SPEC
|
||||
#define ASM_SPEC "\
|
||||
%{mbig-endian:-EB} \
|
||||
%{mlittle-endian:-EL} \
|
||||
%(asm_cpu_spec) \
|
||||
%{mapcs-*:-mapcs-%*} \
|
||||
%(subtarget_asm_float_spec) \
|
||||
%{mthumb-interwork:-mthumb-interwork} \
|
||||
%{mfloat-abi=*} %{mfpu=*} \
|
||||
%(subtarget_extra_asm_spec)"
|
||||
#endif
|
||||
|
||||
/* The ARM uses @ are a comment character so we need to redefine
|
||||
TYPE_OPERAND_FMT. */
|
||||
#undef TYPE_OPERAND_FMT
|
||||
#define TYPE_OPERAND_FMT "%%%s"
|
||||
|
||||
/* We might need a ARM specific header to function declarations. */
|
||||
#undef ASM_DECLARE_FUNCTION_NAME
|
||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ARM_DECLARE_FUNCTION_NAME (FILE, NAME, DECL); \
|
||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
|
||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
ARM_OUTPUT_FN_UNWIND (FILE, TRUE); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* We might need an ARM specific trailer for function declarations. */
|
||||
#undef ASM_DECLARE_FUNCTION_SIZE
|
||||
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ARM_OUTPUT_FN_UNWIND (FILE, FALSE); \
|
||||
if (!flag_inhibit_size_directive) \
|
||||
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Define this macro if jump tables (for `tablejump' insns) should be
|
||||
output in the text section, along with the assembler instructions.
|
||||
Otherwise, the readonly data section is used. */
|
||||
/* We put ARM and Thumb-2 jump tables in the text section, because it makes
|
||||
the code more efficient, but for Thumb-1 it's better to put them out of
|
||||
band unless we are generating compressed tables. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION \
|
||||
(TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
|
||||
|
||||
#ifndef LINK_SPEC
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
|
||||
#endif
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
#ifndef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT (MASK_APCS_FRAME)
|
||||
#endif
|
||||
|
||||
#ifndef MULTILIB_DEFAULTS
|
||||
#define MULTILIB_DEFAULTS \
|
||||
{ "marm", "mlittle-endian", "mfloat-abi=soft", "mno-thumb-interwork", "fno-leading-underscore" }
|
||||
#endif
|
||||
|
||||
#define TARGET_ASM_FILE_START_APP_OFF true
|
||||
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
||||
|
||||
|
||||
/* Output an element in the static constructor array. */
|
||||
#undef TARGET_ASM_CONSTRUCTOR
|
||||
#define TARGET_ASM_CONSTRUCTOR arm_elf_asm_constructor
|
||||
|
||||
#undef TARGET_ASM_DESTRUCTOR
|
||||
#define TARGET_ASM_DESTRUCTOR arm_elf_asm_destructor
|
||||
|
||||
/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
|
||||
#define NEED_PLT_RELOC flag_pic
|
||||
#define NEED_GOT_RELOC flag_pic
|
||||
|
||||
/* The ELF assembler handles GOT addressing differently to NetBSD. */
|
||||
#define GOT_PCREL 0
|
||||
|
||||
/* Align output to a power of two. Note ".align 0" is redundant,
|
||||
and also GAS will treat it as ".align 2" which we do not want. */
|
||||
#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
|
||||
do \
|
||||
{ \
|
||||
if ((POWER) > 0) \
|
||||
fprintf (STREAM, "\t.align\t%d\n", POWER); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Horrible hack: We want to prevent some libgcc routines being included
|
||||
for some multilibs. */
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#undef L_fixdfsi
|
||||
#undef L_fixunsdfsi
|
||||
#undef L_truncdfsf2
|
||||
#undef L_fixsfsi
|
||||
#undef L_fixunssfsi
|
||||
#undef L_floatdidf
|
||||
#undef L_floatdisf
|
||||
#undef L_floatundidf
|
||||
#undef L_floatundisf
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/* Definitions for non-Linux based ARM systems using ELF
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
Contributed by Catherine Moore <clm@cygnus.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* elfos.h should have already been included. Now just override
|
||||
any conflicting definitions and add any extras. */
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
|
||||
/* Default to using software floating point. */
|
||||
#ifndef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT (0)
|
||||
#endif
|
||||
|
||||
/* Now we define the strings used to build the spec file. */
|
||||
#define UNKNOWN_ELF_STARTFILE_SPEC " crti%O%s crtbegin%O%s crt0%O%s"
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC UNKNOWN_ELF_STARTFILE_SPEC
|
||||
|
||||
#define UNKNOWN_ELF_ENDFILE_SPEC "crtend%O%s crtn%O%s"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC UNKNOWN_ELF_ENDFILE_SPEC
|
||||
|
||||
/* The __USES_INITFINI__ define is tested in newlib/libc/sys/arm/crt0.S
|
||||
to see if it needs to invoked _init() and _fini(). */
|
||||
#undef SUBTARGET_CPP_SPEC
|
||||
#define SUBTARGET_CPP_SPEC "-D__USES_INITFINI__"
|
||||
|
||||
#undef PREFERRED_DEBUGGING_TYPE
|
||||
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||
|
||||
/* Return a nonzero value if DECL has a section attribute. */
|
||||
#define IN_NAMED_SECTION_P(DECL) \
|
||||
((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
|
||||
&& DECL_SECTION_NAME (DECL) != NULL_TREE)
|
||||
|
||||
#undef ASM_OUTPUT_ALIGNED_BSS
|
||||
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
if (IN_NAMED_SECTION_P (DECL)) \
|
||||
switch_to_section (get_named_section (DECL, NULL, 0)); \
|
||||
else \
|
||||
switch_to_section (bss_section); \
|
||||
\
|
||||
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
\
|
||||
last_assemble_variable_decl = DECL; \
|
||||
ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL); \
|
||||
ASM_OUTPUT_SKIP (FILE, SIZE ? (int)(SIZE) : 1); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
|
||||
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
if ((DECL) != NULL && IN_NAMED_SECTION_P (DECL)) \
|
||||
switch_to_section (get_named_section (DECL, NULL, 0)); \
|
||||
else \
|
||||
switch_to_section (bss_section); \
|
||||
\
|
||||
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
ASM_OUTPUT_LABEL (FILE, NAME); \
|
||||
fprintf (FILE, "\t.space\t%d\n", SIZE ? (int)(SIZE) : 1); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#ifndef SUBTARGET_CPU_DEFAULT
|
||||
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm7tdmi
|
||||
#endif
|
||||
|
||||
/* The libgcc udivmod functions may throw exceptions. If newlib is
|
||||
configured to support long longs in I/O, then printf will depend on
|
||||
udivmoddi4, which will depend on the exception unwind routines,
|
||||
which will depend on abort, which is defined in libc. */
|
||||
#undef LINK_GCC_C_SEQUENCE_SPEC
|
||||
#define LINK_GCC_C_SEQUENCE_SPEC "--start-group %G %L --end-group"
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* Definitions needed when using stabs embedded in ELF sections.
|
||||
Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This file may be included by any ELF target which wishes to
|
||||
support -gstabs generating stabs in sections, as produced by gas
|
||||
and understood by gdb. */
|
||||
|
||||
#ifndef GCC_DBX_ELF_H
|
||||
#define GCC_DBX_ELF_H
|
||||
|
||||
/* Output DBX (stabs) debugging information if doing -gstabs. */
|
||||
|
||||
#define DBX_DEBUGGING_INFO 1
|
||||
|
||||
/* Make LBRAC and RBRAC addresses relative to the start of the
|
||||
function. The native Solaris stabs debugging format works this
|
||||
way, gdb expects it, and it reduces the number of relocation
|
||||
entries... */
|
||||
|
||||
#define DBX_BLOCKS_FUNCTION_RELATIVE 1
|
||||
|
||||
/* ... but, to make this work, functions must appear prior to line info. */
|
||||
|
||||
#define DBX_FUNCTION_FIRST
|
||||
|
||||
/* When generating stabs debugging, use N_BINCL entries. */
|
||||
|
||||
#define DBX_USE_BINCL
|
||||
|
||||
/* There is no limit to the length of stabs strings. */
|
||||
|
||||
#ifndef DBX_CONTIN_LENGTH
|
||||
#define DBX_CONTIN_LENGTH 0
|
||||
#endif
|
||||
|
||||
/* Like block addresses, stabs line numbers are relative to the
|
||||
current function. */
|
||||
|
||||
#define DBX_LINES_FUNCTION_RELATIVE 1
|
||||
|
||||
/* Generate a blank trailing N_SO to mark the end of the .o file, since
|
||||
we can't depend upon the linker to mark .o file boundaries with
|
||||
embedded stabs. */
|
||||
|
||||
#define DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
|
||||
|
||||
#endif /* ! GCC_DBX_ELF_H */
|
||||
|
|
@ -0,0 +1,435 @@
|
|||
/* elfos.h -- operating system specific defines to be used when
|
||||
targeting GCC for some generic ELF system
|
||||
Copyright (C) 1991-2013 Free Software Foundation, Inc.
|
||||
Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com).
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TARGET_OBJFMT_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
builtin_define ("__ELF__"); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Define a symbol indicating that we are using elfos.h.
|
||||
Some CPU specific configuration files use this. */
|
||||
#define USING_ELFOS_H
|
||||
|
||||
/* The prefix to add to user-visible assembler symbols.
|
||||
|
||||
For ELF systems the convention is *not* to prepend a leading
|
||||
underscore onto user-level symbol names. */
|
||||
|
||||
#undef USER_LABEL_PREFIX
|
||||
#define USER_LABEL_PREFIX ""
|
||||
|
||||
/* The biggest alignment supported by ELF in bits. 32-bit ELF
|
||||
supports section alignment up to (0x80000000 * 8), while
|
||||
64-bit ELF supports (0x8000000000000000 * 8). If this macro
|
||||
is not defined, the default is the largest alignment supported
|
||||
by 32-bit ELF and representable on a 32-bit host. Use this
|
||||
macro to limit the alignment which can be specified using
|
||||
the `__attribute__ ((aligned (N)))' construct. */
|
||||
#ifndef MAX_OFILE_ALIGNMENT
|
||||
#define MAX_OFILE_ALIGNMENT (((unsigned int) 1 << 28) * 8)
|
||||
#endif
|
||||
|
||||
/* Use periods rather than dollar signs in special g++ assembler names. */
|
||||
|
||||
#define NO_DOLLAR_IN_LABEL
|
||||
|
||||
/* Writing `int' for a bit-field forces int alignment for the structure. */
|
||||
|
||||
#ifndef PCC_BITFIELD_TYPE_MATTERS
|
||||
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||
#endif
|
||||
|
||||
/* All ELF targets can support DWARF-2. */
|
||||
|
||||
#define DWARF2_DEBUGGING_INFO 1
|
||||
|
||||
/* The GNU tools operate better with dwarf2, and it is required by some
|
||||
psABI's. Since we don't have any native tools to be compatible with,
|
||||
default to dwarf2. */
|
||||
|
||||
#ifndef PREFERRED_DEBUGGING_TYPE
|
||||
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||
#endif
|
||||
|
||||
/* All SVR4 targets use the ELF object file format. */
|
||||
#define OBJECT_FORMAT_ELF
|
||||
|
||||
|
||||
/* Output #ident as a .ident. */
|
||||
|
||||
#undef TARGET_ASM_OUTPUT_IDENT
|
||||
#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
|
||||
|
||||
#undef SET_ASM_OP
|
||||
#define SET_ASM_OP "\t.set\t"
|
||||
|
||||
/* Most svr4 assemblers want a .file directive at the beginning of
|
||||
their input file. */
|
||||
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
||||
|
||||
/* This is how to allocate empty space in some section. The .zero
|
||||
pseudo-op is used for this on most svr4 assemblers. */
|
||||
|
||||
#define SKIP_ASM_OP "\t.zero\t"
|
||||
|
||||
#undef ASM_OUTPUT_SKIP
|
||||
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
|
||||
fprintf ((FILE), "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
|
||||
SKIP_ASM_OP, (SIZE))
|
||||
|
||||
/* This is how to store into the string LABEL
|
||||
the symbol_ref name of an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class.
|
||||
This is suitable for output with `assemble_name'.
|
||||
|
||||
For most svr4 systems, the convention is that any symbol which begins
|
||||
with a period is not put into the linker symbol table by the assembler. */
|
||||
|
||||
#undef ASM_GENERATE_INTERNAL_LABEL
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
|
||||
do \
|
||||
{ \
|
||||
char *__p; \
|
||||
(LABEL)[0] = '*'; \
|
||||
(LABEL)[1] = '.'; \
|
||||
__p = stpcpy (&(LABEL)[2], PREFIX); \
|
||||
sprint_ul (__p, (unsigned long) (NUM)); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Output the label which precedes a jumptable. Note that for all svr4
|
||||
systems where we actually generate jumptables (which is to say every
|
||||
svr4 target except i386, where we use casesi instead) we put the jump-
|
||||
tables into the .rodata section and since other stuff could have been
|
||||
put into the .rodata section prior to any given jumptable, we have to
|
||||
make sure that the location counter for the .rodata section gets pro-
|
||||
perly re-aligned prior to the actual beginning of the jump table. */
|
||||
|
||||
#undef ALIGN_ASM_OP
|
||||
#define ALIGN_ASM_OP "\t.align\t"
|
||||
|
||||
#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
|
||||
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
|
||||
ASM_OUTPUT_ALIGN ((FILE), 2);
|
||||
#endif
|
||||
|
||||
#undef ASM_OUTPUT_CASE_LABEL
|
||||
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
|
||||
do \
|
||||
{ \
|
||||
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
|
||||
(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* The standard SVR4 assembler seems to require that certain builtin
|
||||
library routines (e.g. .udiv) be explicitly declared as .globl
|
||||
in each assembly file where they are referenced. */
|
||||
|
||||
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
|
||||
(*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
|
||||
|
||||
/* This says how to output assembler code to declare an
|
||||
uninitialized external linkage data object. Under SVR4,
|
||||
the linker seems to want the alignment of data objects
|
||||
to depend on their types. We do exactly that here. */
|
||||
|
||||
#define COMMON_ASM_OP "\t.comm\t"
|
||||
|
||||
#undef ASM_OUTPUT_ALIGNED_COMMON
|
||||
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
fprintf ((FILE), "%s", COMMON_ASM_OP); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
|
||||
(SIZE), (ALIGN) / BITS_PER_UNIT); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* This says how to output assembler code to declare an
|
||||
uninitialized internal linkage data object. Under SVR4,
|
||||
the linker seems to want the alignment of data objects
|
||||
to depend on their types. We do exactly that here. */
|
||||
|
||||
#define LOCAL_ASM_OP "\t.local\t"
|
||||
|
||||
#undef ASM_OUTPUT_ALIGNED_LOCAL
|
||||
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
fprintf ((FILE), "%s", LOCAL_ASM_OP); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
fprintf ((FILE), "\n"); \
|
||||
ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* This is the pseudo-op used to generate a contiguous sequence of byte
|
||||
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
|
||||
AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
|
||||
|
||||
#undef ASCII_DATA_ASM_OP
|
||||
#define ASCII_DATA_ASM_OP "\t.ascii\t"
|
||||
|
||||
/* Support a read-only data section. */
|
||||
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
|
||||
|
||||
/* On svr4, we *do* have support for the .init and .fini sections, and we
|
||||
can put stuff in there to be executed before and after `main'. We let
|
||||
crtstuff.c and other files know this by defining the following symbols.
|
||||
The definitions say how to change sections to the .init and .fini
|
||||
sections. This is the same for all known svr4 assemblers. */
|
||||
|
||||
#define INIT_SECTION_ASM_OP "\t.section\t.init"
|
||||
#define FINI_SECTION_ASM_OP "\t.section\t.fini"
|
||||
|
||||
/* Output assembly directive to move to the beginning of current section. */
|
||||
#ifdef HAVE_GAS_SUBSECTION_ORDERING
|
||||
# define ASM_SECTION_START_OP "\t.subsection\t-1"
|
||||
# define ASM_OUTPUT_SECTION_START(FILE) \
|
||||
fprintf ((FILE), "%s\n", ASM_SECTION_START_OP)
|
||||
#endif
|
||||
|
||||
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
|
||||
|
||||
/* Switch into a generic section. */
|
||||
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
|
||||
|
||||
#undef TARGET_ASM_SELECT_RTX_SECTION
|
||||
#define TARGET_ASM_SELECT_RTX_SECTION default_elf_select_rtx_section
|
||||
#undef TARGET_ASM_SELECT_SECTION
|
||||
#define TARGET_ASM_SELECT_SECTION default_elf_select_section
|
||||
#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
|
||||
#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS true
|
||||
|
||||
/* Define the strings used for the special svr4 .type and .size directives.
|
||||
These strings generally do not vary from one system running svr4 to
|
||||
another, but if a given system (e.g. m88k running svr) needs to use
|
||||
different pseudo-op names for these, they may be overridden in the
|
||||
file which includes this one. */
|
||||
|
||||
#define TYPE_ASM_OP "\t.type\t"
|
||||
#define SIZE_ASM_OP "\t.size\t"
|
||||
|
||||
/* This is how we tell the assembler that a symbol is weak. */
|
||||
|
||||
#define ASM_WEAKEN_LABEL(FILE, NAME) \
|
||||
do \
|
||||
{ \
|
||||
fputs ("\t.weak\t", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
fputc ('\n', (FILE)); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* The following macro defines the format used to output the second
|
||||
operand of the .type assembler directive. Different svr4 assemblers
|
||||
expect various different forms for this operand. The one given here
|
||||
is just a default. You may need to override it in your machine-
|
||||
specific tm.h file (depending upon the particulars of your assembler). */
|
||||
|
||||
#define TYPE_OPERAND_FMT "@%s"
|
||||
|
||||
/* Write the extra assembler code needed to declare a function's result.
|
||||
Most svr4 assemblers don't require any special declaration of the
|
||||
result value, but there are exceptions. */
|
||||
|
||||
#ifndef ASM_DECLARE_RESULT
|
||||
#define ASM_DECLARE_RESULT(FILE, RESULT)
|
||||
#endif
|
||||
|
||||
/* These macros generate the special .type and .size directives which
|
||||
are used to set the corresponding fields of the linker symbol table
|
||||
entries in an ELF object file under SVR4. These macros also output
|
||||
the starting labels for the relevant functions/objects. */
|
||||
|
||||
/* Write the extra assembler code needed to declare a function properly.
|
||||
Some svr4 assemblers need to also have something extra said about the
|
||||
function's return value. We allow for that here. */
|
||||
|
||||
#ifndef ASM_DECLARE_FUNCTION_NAME
|
||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
|
||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||
ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Write the extra assembler code needed to declare an object properly. */
|
||||
|
||||
#ifdef HAVE_GAS_GNU_UNIQUE_OBJECT
|
||||
#define USE_GNU_UNIQUE_OBJECT 1
|
||||
#else
|
||||
#define USE_GNU_UNIQUE_OBJECT 0
|
||||
#endif
|
||||
|
||||
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
HOST_WIDE_INT size; \
|
||||
\
|
||||
/* For template static data member instantiations or \
|
||||
inline fn local statics and their guard variables, use \
|
||||
gnu_unique_object so that they will be combined even under \
|
||||
RTLD_LOCAL. Don't use gnu_unique_object for typeinfo, \
|
||||
vtables and other read-only artificial decls. */ \
|
||||
if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (DECL) \
|
||||
&& (!DECL_ARTIFICIAL (DECL) || !TREE_READONLY (DECL))) \
|
||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object"); \
|
||||
else \
|
||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
|
||||
\
|
||||
size_directive_output = 0; \
|
||||
if (!flag_inhibit_size_directive \
|
||||
&& (DECL) && DECL_SIZE (DECL)) \
|
||||
{ \
|
||||
size_directive_output = 1; \
|
||||
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
||||
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
|
||||
} \
|
||||
\
|
||||
ASM_OUTPUT_LABEL (FILE, NAME); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Output the size directive for a decl in rest_of_decl_compilation
|
||||
in the case where we did not do so before the initializer.
|
||||
Once we find the error_mark_node, we know that the value of
|
||||
size_directive_output was set
|
||||
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
|
||||
|
||||
#undef ASM_FINISH_DECLARE_OBJECT
|
||||
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)\
|
||||
do \
|
||||
{ \
|
||||
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
|
||||
HOST_WIDE_INT size; \
|
||||
\
|
||||
if (!flag_inhibit_size_directive \
|
||||
&& DECL_SIZE (DECL) \
|
||||
&& ! AT_END && TOP_LEVEL \
|
||||
&& DECL_INITIAL (DECL) == error_mark_node \
|
||||
&& !size_directive_output) \
|
||||
{ \
|
||||
size_directive_output = 1; \
|
||||
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
||||
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* This is how to declare the size of a function. */
|
||||
#ifndef ASM_DECLARE_FUNCTION_SIZE
|
||||
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
if (!flag_inhibit_size_directive) \
|
||||
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
|
||||
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
|
||||
corresponds to a particular byte value [0..255]. For any
|
||||
given byte value, if the value in the corresponding table
|
||||
position is zero, the given character can be output directly.
|
||||
If the table value is 1, the byte must be output as a \ooo
|
||||
octal escape. If the tables value is anything else, then the
|
||||
byte value should be output as a \ followed by the value
|
||||
in the table. Note that we can use standard UN*X escape
|
||||
sequences for many control characters, but we don't use
|
||||
\a to represent BEL because some svr4 assemblers (e.g. on
|
||||
the i386) don't know about that. Also, we don't use \v
|
||||
since some versions of gas, such as 2.2 did not accept it. */
|
||||
|
||||
#define ELF_ASCII_ESCAPES \
|
||||
"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||
\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
|
||||
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
|
||||
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
|
||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
|
||||
|
||||
/* Some svr4 assemblers have a limit on the number of characters which
|
||||
can appear in the operand of a .string directive. If your assembler
|
||||
has such a limitation, you should define STRING_LIMIT to reflect that
|
||||
limit. Note that at least some svr4 assemblers have a limit on the
|
||||
actual number of bytes in the double-quoted string, and that they
|
||||
count each character in an escape sequence as one byte. Thus, an
|
||||
escape sequence like \377 would count as four bytes.
|
||||
|
||||
If your target assembler doesn't support the .string directive, you
|
||||
should define this to zero.
|
||||
*/
|
||||
|
||||
#define ELF_STRING_LIMIT ((unsigned) 256)
|
||||
|
||||
#define STRING_ASM_OP "\t.string\t"
|
||||
|
||||
/* The routine used to output NUL terminated strings. We use a special
|
||||
version of this for most svr4 targets because doing so makes the
|
||||
generated assembly code more compact (and thus faster to assemble)
|
||||
as well as more readable, especially for targets like the i386
|
||||
(where the only alternative is to output character sequences as
|
||||
comma separated lists of numbers). */
|
||||
|
||||
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
|
||||
default_elf_asm_output_limited_string ((FILE), (STR))
|
||||
|
||||
/* The routine used to output sequences of byte values. We use a special
|
||||
version of this for most svr4 targets because doing so makes the
|
||||
generated assembly code more compact (and thus faster to assemble)
|
||||
as well as more readable. Note that if we find subparts of the
|
||||
character sequence which end with NUL (and which are shorter than
|
||||
STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
|
||||
|
||||
#undef ASM_OUTPUT_ASCII
|
||||
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
|
||||
default_elf_asm_output_ascii ((FILE), (STR), (LENGTH));
|
||||
|
||||
/* Allow the use of the -frecord-gcc-switches switch via the
|
||||
elf_record_gcc_switches function defined in varasm.c. */
|
||||
#undef TARGET_ASM_RECORD_GCC_SWITCHES
|
||||
#define TARGET_ASM_RECORD_GCC_SWITCHES elf_record_gcc_switches
|
||||
|
||||
/* A C statement (sans semicolon) to output to the stdio stream STREAM
|
||||
any text necessary for declaring the name of an external symbol
|
||||
named NAME which is referenced in this compilation but not defined.
|
||||
It is needed to properly support non-default visibility. */
|
||||
|
||||
#ifndef ASM_OUTPUT_EXTERNAL
|
||||
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
|
||||
default_elf_asm_output_external (FILE, DECL, NAME)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* Definitions for ELF systems with .init_array/.fini_array section
|
||||
support.
|
||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef HAVE_INITFINI_ARRAY_SUPPORT
|
||||
|
||||
#define USE_INITFINI_ARRAY
|
||||
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#undef FINI_SECTION_ASM_OP
|
||||
|
||||
#undef INIT_ARRAY_SECTION_ASM_OP
|
||||
#define INIT_ARRAY_SECTION_ASM_OP
|
||||
|
||||
#undef FINI_ARRAY_SECTION_ASM_OP
|
||||
#define FINI_ARRAY_SECTION_ASM_OP
|
||||
|
||||
/* Use .init_array/.fini_array section for constructors and destructors. */
|
||||
#undef TARGET_ASM_CONSTRUCTOR
|
||||
#define TARGET_ASM_CONSTRUCTOR default_elf_init_array_asm_out_constructor
|
||||
#undef TARGET_ASM_DESTRUCTOR
|
||||
#define TARGET_ASM_DESTRUCTOR default_elf_fini_array_asm_out_destructor
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* Definitions for <stdint.h> types on systems using newlib.
|
||||
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* newlib uses 32-bit long in certain cases for all non-SPU
|
||||
targets. */
|
||||
#ifndef STDINT_LONG32
|
||||
#define STDINT_LONG32 (LONG_TYPE_SIZE == 32)
|
||||
#endif
|
||||
|
||||
#define SIG_ATOMIC_TYPE "int"
|
||||
|
||||
/* The newlib logic actually checks for sizes greater than 32 rather
|
||||
than equal to 64 for various 64-bit types. */
|
||||
|
||||
#define INT8_TYPE (CHAR_TYPE_SIZE == 8 ? "signed char" : 0)
|
||||
#define INT16_TYPE (SHORT_TYPE_SIZE == 16 ? "short int" : INT_TYPE_SIZE == 16 ? "int" : CHAR_TYPE_SIZE == 16 ? "signed char" : 0)
|
||||
#define INT32_TYPE (STDINT_LONG32 ? "long int" : INT_TYPE_SIZE == 32 ? "int" : SHORT_TYPE_SIZE == 32 ? "short int" : CHAR_TYPE_SIZE == 32 ? "signed char" : 0)
|
||||
#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : LONG_LONG_TYPE_SIZE == 64 ? "long long int" : INT_TYPE_SIZE == 64 ? "int" : 0)
|
||||
#define UINT8_TYPE (CHAR_TYPE_SIZE == 8 ? "unsigned char" : 0)
|
||||
#define UINT16_TYPE (SHORT_TYPE_SIZE == 16 ? "short unsigned int" : INT_TYPE_SIZE == 16 ? "unsigned int" : CHAR_TYPE_SIZE == 16 ? "unsigned char" : 0)
|
||||
#define UINT32_TYPE (STDINT_LONG32 ? "long unsigned int" : INT_TYPE_SIZE == 32 ? "unsigned int" : SHORT_TYPE_SIZE == 32 ? "short unsigned int" : CHAR_TYPE_SIZE == 32 ? "unsigned char" : 0)
|
||||
#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : LONG_LONG_TYPE_SIZE == 64 ? "long long unsigned int" : INT_TYPE_SIZE == 64 ? "unsigned int" : 0)
|
||||
|
||||
#define INT_LEAST8_TYPE (INT8_TYPE ? INT8_TYPE : INT16_TYPE ? INT16_TYPE : INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0)
|
||||
#define INT_LEAST16_TYPE (INT16_TYPE ? INT16_TYPE : INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0)
|
||||
#define INT_LEAST32_TYPE (INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0)
|
||||
#define INT_LEAST64_TYPE INT64_TYPE
|
||||
#define UINT_LEAST8_TYPE (UINT8_TYPE ? UINT8_TYPE : UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)
|
||||
#define UINT_LEAST16_TYPE (UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)
|
||||
#define UINT_LEAST32_TYPE (UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)
|
||||
#define UINT_LEAST64_TYPE UINT64_TYPE
|
||||
|
||||
#define INT_FAST8_TYPE (INT_TYPE_SIZE >= 8 ? "int" : INT_LEAST8_TYPE)
|
||||
#define INT_FAST16_TYPE (INT_TYPE_SIZE >= 16 ? "int" : INT_LEAST16_TYPE)
|
||||
#define INT_FAST32_TYPE (INT_TYPE_SIZE >= 32 ? "int" : INT_LEAST32_TYPE)
|
||||
#define INT_FAST64_TYPE (INT_TYPE_SIZE >= 64 ? "int" : INT_LEAST64_TYPE)
|
||||
#define UINT_FAST8_TYPE (INT_TYPE_SIZE >= 8 ? "unsigned int" : UINT_LEAST8_TYPE)
|
||||
#define UINT_FAST16_TYPE (INT_TYPE_SIZE >= 16 ? "unsigned int" : UINT_LEAST16_TYPE)
|
||||
#define UINT_FAST32_TYPE (INT_TYPE_SIZE >= 32 ? "unsigned int" : UINT_LEAST32_TYPE)
|
||||
#define UINT_FAST64_TYPE (INT_TYPE_SIZE >= 64 ? "unsigned int" : UINT_LEAST64_TYPE)
|
||||
|
||||
/* Newlib uses the unsigned type corresponding to ptrdiff_t for
|
||||
uintptr_t; this is the same as size_t for most newlib-using
|
||||
targets. */
|
||||
#define INTPTR_TYPE PTRDIFF_TYPE
|
||||
#ifndef UINTPTR_TYPE
|
||||
#define UINTPTR_TYPE SIZE_TYPE
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* Dummy definitions of VxWorks-related macros
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* True if we're targeting VxWorks. */
|
||||
#ifndef TARGET_VXWORKS
|
||||
#define TARGET_VXWORKS 0
|
||||
#endif
|
||||
|
||||
/* True if generating code for a VxWorks RTP. */
|
||||
#ifndef TARGET_VXWORKS_RTP
|
||||
#define TARGET_VXWORKS_RTP false
|
||||
#endif
|
||||
|
||||
/* The symbol that points to an RTP's table of GOTs. */
|
||||
#define VXWORKS_GOTT_BASE (gcc_unreachable (), "")
|
||||
|
||||
/* The symbol that holds the index of the current module's GOT in
|
||||
VXWORKS_GOTT_BASE. */
|
||||
#define VXWORKS_GOTT_INDEX (gcc_unreachable (), "")
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/* Generated automatically. */
|
||||
static const char configuration_arguments[] = "/home/build/work/GCC-4-8-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-4-8-build/install-native --libexecdir=/home/build/work/GCC-4-8-build/install-native/lib --infodir=/home/build/work/GCC-4-8-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-4-8-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-4-8-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-4-8-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-4-8-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-4-8-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-4-8-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-4-8-build/build-native/host-libs/usr --with-isl=/home/build/work/GCC-4-8-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-4-8-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-4-8-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r";
|
||||
static const char thread_model[] = "single";
|
||||
|
||||
static const struct {
|
||||
const char *name, *value;
|
||||
} configure_default_options[] = { { NULL, NULL} };
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/* GCC core type declarations.
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Provide forward declarations of core types which are referred to by
|
||||
most of the compiler. This allows header files to use these types
|
||||
(e.g. in function prototypes) without concern for whether the full
|
||||
definitions are visible. Some other declarations that need to be
|
||||
universally visible are here, too.
|
||||
|
||||
In the context of tconfig.h, most of these have special definitions
|
||||
which prevent them from being used except in further type
|
||||
declarations. This is a kludge; the right thing is to avoid
|
||||
including the "tm.h" header set in the context of tconfig.h, but
|
||||
we're not there yet. */
|
||||
|
||||
#ifndef GCC_CORETYPES_H
|
||||
#define GCC_CORETYPES_H
|
||||
|
||||
#ifndef GTY
|
||||
#define GTY(x) /* nothing - marker for gengtype */
|
||||
#endif
|
||||
|
||||
#ifndef USED_FOR_TARGET
|
||||
|
||||
struct bitmap_head_def;
|
||||
typedef struct bitmap_head_def *bitmap;
|
||||
typedef const struct bitmap_head_def *const_bitmap;
|
||||
struct simple_bitmap_def;
|
||||
typedef struct simple_bitmap_def *sbitmap;
|
||||
typedef const struct simple_bitmap_def *const_sbitmap;
|
||||
struct rtx_def;
|
||||
typedef struct rtx_def *rtx;
|
||||
typedef const struct rtx_def *const_rtx;
|
||||
struct rtvec_def;
|
||||
typedef struct rtvec_def *rtvec;
|
||||
typedef const struct rtvec_def *const_rtvec;
|
||||
union tree_node;
|
||||
typedef union tree_node *tree;
|
||||
typedef const union tree_node *const_tree;
|
||||
union gimple_statement_d;
|
||||
typedef union gimple_statement_d *gimple;
|
||||
typedef const union gimple_statement_d *const_gimple;
|
||||
typedef gimple gimple_seq;
|
||||
union section;
|
||||
typedef union section section;
|
||||
struct gcc_options;
|
||||
struct cl_target_option;
|
||||
struct cl_optimization;
|
||||
struct cl_option;
|
||||
struct cl_decoded_option;
|
||||
struct cl_option_handlers;
|
||||
struct diagnostic_context;
|
||||
typedef struct diagnostic_context diagnostic_context;
|
||||
struct pretty_print_info;
|
||||
typedef struct pretty_print_info pretty_printer;
|
||||
|
||||
/* Address space number for named address space support. */
|
||||
typedef unsigned char addr_space_t;
|
||||
|
||||
/* The value of addr_space_t that represents the generic address space. */
|
||||
#define ADDR_SPACE_GENERIC 0
|
||||
#define ADDR_SPACE_GENERIC_P(AS) ((AS) == ADDR_SPACE_GENERIC)
|
||||
|
||||
/* The major intermediate representations of GCC. */
|
||||
enum ir_type {
|
||||
IR_GIMPLE,
|
||||
IR_RTL_CFGRTL,
|
||||
IR_RTL_CFGLAYOUT
|
||||
};
|
||||
|
||||
/* Provide forward struct declaration so that we don't have to include
|
||||
all of cpplib.h whenever a random prototype includes a pointer.
|
||||
Note that the cpp_reader and cpp_token typedefs remain part of
|
||||
cpplib.h. */
|
||||
|
||||
struct cpp_reader;
|
||||
struct cpp_token;
|
||||
|
||||
/* The thread-local storage model associated with a given VAR_DECL
|
||||
or SYMBOL_REF. This isn't used much, but both trees and RTL refer
|
||||
to it, so it's here. */
|
||||
enum tls_model {
|
||||
TLS_MODEL_NONE,
|
||||
TLS_MODEL_EMULATED,
|
||||
TLS_MODEL_REAL,
|
||||
TLS_MODEL_GLOBAL_DYNAMIC = TLS_MODEL_REAL,
|
||||
TLS_MODEL_LOCAL_DYNAMIC,
|
||||
TLS_MODEL_INITIAL_EXEC,
|
||||
TLS_MODEL_LOCAL_EXEC
|
||||
};
|
||||
|
||||
/* Types of unwind/exception handling info that can be generated. */
|
||||
|
||||
enum unwind_info_type
|
||||
{
|
||||
UI_NONE,
|
||||
UI_SJLJ,
|
||||
UI_DWARF2,
|
||||
UI_TARGET,
|
||||
UI_SEH
|
||||
};
|
||||
|
||||
/* Callgraph node profile representation. */
|
||||
enum node_frequency {
|
||||
/* This function most likely won't be executed at all.
|
||||
(set only when profile feedback is available or via function attribute). */
|
||||
NODE_FREQUENCY_UNLIKELY_EXECUTED,
|
||||
/* For functions that are known to be executed once (i.e. constructors, destructors
|
||||
and main function. */
|
||||
NODE_FREQUENCY_EXECUTED_ONCE,
|
||||
/* The default value. */
|
||||
NODE_FREQUENCY_NORMAL,
|
||||
/* Optimize this function hard
|
||||
(set only when profile feedback is available or via function attribute). */
|
||||
NODE_FREQUENCY_HOT
|
||||
};
|
||||
|
||||
/* Possible initialization status of a variable. When requested
|
||||
by the user, this information is tracked and recorded in the DWARF
|
||||
debug information, along with the variable's location. */
|
||||
enum var_init_status
|
||||
{
|
||||
VAR_INIT_STATUS_UNKNOWN,
|
||||
VAR_INIT_STATUS_UNINITIALIZED,
|
||||
VAR_INIT_STATUS_INITIALIZED
|
||||
};
|
||||
|
||||
|
||||
struct edge_def;
|
||||
typedef struct edge_def *edge;
|
||||
typedef const struct edge_def *const_edge;
|
||||
struct basic_block_def;
|
||||
typedef struct basic_block_def *basic_block;
|
||||
typedef const struct basic_block_def *const_basic_block;
|
||||
|
||||
#define obstack_chunk_alloc ((void *(*) (long)) xmalloc)
|
||||
#define obstack_chunk_free ((void (*) (void *)) free)
|
||||
#define OBSTACK_CHUNK_SIZE 0
|
||||
#define gcc_obstack_init(OBSTACK) \
|
||||
_obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0, \
|
||||
obstack_chunk_alloc, \
|
||||
obstack_chunk_free)
|
||||
|
||||
/* enum reg_class is target specific, so it should not appear in
|
||||
target-independent code or interfaces, like the target hook declarations
|
||||
in target.h. */
|
||||
typedef int reg_class_t;
|
||||
|
||||
#else
|
||||
|
||||
struct _dont_use_rtx_here_;
|
||||
struct _dont_use_rtvec_here_;
|
||||
union _dont_use_tree_here_;
|
||||
#define rtx struct _dont_use_rtx_here_ *
|
||||
#define const_rtx struct _dont_use_rtx_here_ *
|
||||
#define rtvec struct _dont_use_rtvec_here *
|
||||
#define const_rtvec struct _dont_use_rtvec_here *
|
||||
#define tree union _dont_use_tree_here_ *
|
||||
#define const_tree union _dont_use_tree_here_ *
|
||||
|
||||
#endif
|
||||
|
||||
/* Memory model types for the __atomic* builtins.
|
||||
This must match the order in libstdc++-v3/include/bits/atomic_base.h. */
|
||||
enum memmodel
|
||||
{
|
||||
MEMMODEL_RELAXED = 0,
|
||||
MEMMODEL_CONSUME = 1,
|
||||
MEMMODEL_ACQUIRE = 2,
|
||||
MEMMODEL_RELEASE = 3,
|
||||
MEMMODEL_ACQ_REL = 4,
|
||||
MEMMODEL_SEQ_CST = 5,
|
||||
MEMMODEL_LAST = 6
|
||||
};
|
||||
|
||||
/* Suppose that higher bits are target dependant. */
|
||||
#define MEMMODEL_MASK ((1<<16)-1)
|
||||
|
||||
/* Support for user-provided GGC and PCH markers. The first parameter
|
||||
is a pointer to a pointer, the second a cookie. */
|
||||
typedef void (*gt_pointer_operator) (void *, void *);
|
||||
|
||||
#if !defined (HAVE_UCHAR)
|
||||
typedef unsigned char uchar;
|
||||
#endif
|
||||
|
||||
#endif /* coretypes.h */
|
||||
|
|
@ -0,0 +1,479 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
additional tree codes used in the GNU C++ compiler (see tree.def
|
||||
for the standard codes).
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* An OFFSET_REF is used in two situations:
|
||||
|
||||
1. An expression of the form `A::m' where `A' is a class and `m' is
|
||||
a non-static member. In this case, operand 0 will be a TYPE
|
||||
(corresponding to `A') and operand 1 will be a FIELD_DECL,
|
||||
BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
|
||||
|
||||
The expression is a pointer-to-member if its address is taken,
|
||||
but simply denotes a member of the object if its address is not
|
||||
taken.
|
||||
|
||||
This form is only used during the parsing phase; once semantic
|
||||
analysis has taken place they are eliminated.
|
||||
|
||||
2. An expression of the form `x.*p'. In this case, operand 0 will
|
||||
be an expression corresponding to `x' and operand 1 will be an
|
||||
expression with pointer-to-member type. */
|
||||
DEFTREECODE (OFFSET_REF, "offset_ref", tcc_reference, 2)
|
||||
|
||||
/* A pointer-to-member constant. For a pointer-to-member constant
|
||||
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
|
||||
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
|
||||
DEFTREECODE (PTRMEM_CST, "ptrmem_cst", tcc_constant, 0)
|
||||
|
||||
/* For NEW_EXPR, operand 0 is the placement list.
|
||||
Operand 1 is the new-declarator.
|
||||
Operand 2 is the number of elements in the array.
|
||||
Operand 3 is the initializer. */
|
||||
DEFTREECODE (NEW_EXPR, "nw_expr", tcc_expression, 4)
|
||||
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", tcc_expression, 3)
|
||||
|
||||
/* For DELETE_EXPR, operand 0 is the store to be destroyed.
|
||||
Operand 1 is the value to pass to the destroying function
|
||||
saying whether the store should be deallocated as well. */
|
||||
DEFTREECODE (DELETE_EXPR, "dl_expr", tcc_expression, 2)
|
||||
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", tcc_expression, 2)
|
||||
|
||||
/* Value is reference to particular overloaded class method.
|
||||
Operand 0 is the class, operand 1 is the field
|
||||
The COMPLEXITY field holds the class level (usually 0). */
|
||||
DEFTREECODE (SCOPE_REF, "scope_ref", tcc_reference, 2)
|
||||
|
||||
/* When composing an object with a member, this is the result.
|
||||
Operand 0 is the object. Operand 1 is the member (usually
|
||||
a dereferenced pointer to member). */
|
||||
DEFTREECODE (MEMBER_REF, "member_ref", tcc_reference, 2)
|
||||
|
||||
/* Type conversion operator in C++. TREE_TYPE is type that this
|
||||
operator converts to. Operand is expression to be converted. */
|
||||
DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
|
||||
|
||||
/* AGGR_INIT_EXPRs have a variably-sized representation similar to
|
||||
that of CALL_EXPRs. Operand 0 is an INTEGER_CST node containing the
|
||||
operand count, operand 1 is the function which performs initialization,
|
||||
operand 2 is the slot which was allocated for this expression, and
|
||||
the remaining operands are the arguments to the initialization function. */
|
||||
DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
|
||||
|
||||
/* Initialization of an array from another array, expressed at a high level
|
||||
so that it works with TARGET_EXPR. Operand 0 is the target, operand 1
|
||||
is the initializer. */
|
||||
DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
|
||||
|
||||
/* A throw expression. operand 0 is the expression, if there was one,
|
||||
else it is NULL_TREE. */
|
||||
DEFTREECODE (THROW_EXPR, "throw_expr", tcc_expression, 1)
|
||||
|
||||
/* An empty class object. The TREE_TYPE gives the class type. We use
|
||||
these to avoid actually creating instances of the empty classes. */
|
||||
DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", tcc_expression, 0)
|
||||
|
||||
/* A reference to a member function or member functions from a base
|
||||
class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
|
||||
TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
|
||||
functions. BASELINK_BINFO gives the base from which the functions
|
||||
come, i.e., the base to which the `this' pointer must be converted
|
||||
before the functions are called. BASELINK_ACCESS_BINFO gives the
|
||||
base used to name the functions.
|
||||
|
||||
A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
|
||||
the type of the expression. This type is either a FUNCTION_TYPE,
|
||||
METHOD_TYPE, or `unknown_type_node' indicating that the function is
|
||||
overloaded. */
|
||||
DEFTREECODE (BASELINK, "baselink", tcc_exceptional, 0)
|
||||
|
||||
/* Template definition. The following fields have the specified uses,
|
||||
although there are other macros in cp-tree.h that should be used for
|
||||
accessing this data.
|
||||
DECL_ARGUMENTS template parm vector
|
||||
DECL_TEMPLATE_INFO template text &c
|
||||
DECL_VINDEX list of instantiations already produced;
|
||||
only done for functions so far
|
||||
For class template:
|
||||
DECL_INITIAL associated templates (methods &c)
|
||||
DECL_TEMPLATE_RESULT null
|
||||
For non-class templates:
|
||||
TREE_TYPE type of object to be constructed
|
||||
DECL_TEMPLATE_RESULT decl for object to be created
|
||||
(e.g., FUNCTION_DECL with tmpl parms used)
|
||||
*/
|
||||
DEFTREECODE (TEMPLATE_DECL, "template_decl", tcc_declaration, 0)
|
||||
|
||||
/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives
|
||||
the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL
|
||||
gives the level (from 1) of the parameter.
|
||||
|
||||
Here's an example:
|
||||
|
||||
template <class T> // Index 0, Level 1.
|
||||
struct S
|
||||
{
|
||||
template <class U, // Index 0, Level 2.
|
||||
class V> // Index 1, Level 2.
|
||||
void f();
|
||||
};
|
||||
|
||||
The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended
|
||||
from this one. The first descendant will have the same IDX, but
|
||||
its LEVEL will be one less. The TREE_CHAIN field is used to chain
|
||||
together the descendants. The TEMPLATE_PARM_DECL is the
|
||||
declaration of this parameter, either a TYPE_DECL or CONST_DECL.
|
||||
The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant
|
||||
parent, i.e., the LEVEL that the parameter originally had when it
|
||||
was declared. For example, if we instantiate S<int>, we will have:
|
||||
|
||||
struct S<int>
|
||||
{
|
||||
template <class U, // Index 0, Level 1, Orig Level 2
|
||||
class V> // Index 1, Level 1, Orig Level 2
|
||||
void f();
|
||||
};
|
||||
|
||||
The LEVEL is the level of the parameter when we are worrying about
|
||||
the types of things; the ORIG_LEVEL is the level when we are
|
||||
worrying about instantiating things. */
|
||||
DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", tcc_exceptional, 0)
|
||||
|
||||
/* Index into a template parameter list for template template parameters.
|
||||
This parameter must be a type. The TYPE_FIELDS value will be a
|
||||
TEMPLATE_PARM_INDEX.
|
||||
|
||||
It is used without template arguments like TT in C<TT>,
|
||||
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE
|
||||
and TYPE_NAME is a TEMPLATE_DECL. */
|
||||
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", tcc_type, 0)
|
||||
|
||||
/* The ordering of the following codes is optimized for the checking
|
||||
macros in tree.h. Changing the order will degrade the speed of the
|
||||
compiler. TEMPLATE_TYPE_PARM, TYPENAME_TYPE, TYPEOF_TYPE,
|
||||
BOUND_TEMPLATE_TEMPLATE_PARM. */
|
||||
|
||||
/* Index into a template parameter list. This parameter must be a type.
|
||||
The type.values field will be a TEMPLATE_PARM_INDEX. */
|
||||
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
|
||||
|
||||
/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
|
||||
TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via
|
||||
template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR.
|
||||
TREE_TYPE is always NULL. */
|
||||
DEFTREECODE (TYPENAME_TYPE, "typename_type", tcc_type, 0)
|
||||
|
||||
/* A type designated by `__typeof (expr)'. TYPEOF_TYPE_EXPR is the
|
||||
expression in question. */
|
||||
DEFTREECODE (TYPEOF_TYPE, "typeof_type", tcc_type, 0)
|
||||
|
||||
/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments
|
||||
like TT<int>.
|
||||
In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
|
||||
template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */
|
||||
DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm",
|
||||
tcc_type, 0)
|
||||
|
||||
/* For template template argument of the form `T::template C'.
|
||||
TYPE_CONTEXT is `T', the template parameter dependent object.
|
||||
TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template. */
|
||||
DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
|
||||
|
||||
/* A using declaration. USING_DECL_SCOPE contains the specified
|
||||
scope. In a member using decl, unless DECL_DEPENDENT_P is true,
|
||||
USING_DECL_DECLS contains the _DECL or OVERLOAD so named. This is
|
||||
not an alias, but is later expanded into multiple aliases. */
|
||||
DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
|
||||
|
||||
/* A using directive. The operand is USING_STMT_NAMESPACE. */
|
||||
DEFTREECODE (USING_STMT, "using_stmt", tcc_statement, 1)
|
||||
|
||||
/* An un-parsed default argument. Holds a vector of input tokens and
|
||||
a vector of places where the argument was instantiated before
|
||||
parsing had occurred. */
|
||||
DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0)
|
||||
|
||||
/* An uninstantiated noexcept-specification. DEFERRED_NOEXCEPT_PATTERN is
|
||||
the pattern from the template, and DEFERRED_NOEXCEPT_ARGS are the
|
||||
template arguments to substitute into the pattern when needed. */
|
||||
DEFTREECODE (DEFERRED_NOEXCEPT, "deferred_noexcept", tcc_exceptional, 0)
|
||||
|
||||
/* A template-id, like foo<int>. The first operand is the template.
|
||||
The second is NULL if there are no explicit arguments, or a
|
||||
TREE_VEC of arguments. The template will be a FUNCTION_DECL,
|
||||
TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
|
||||
member template, the template may be an IDENTIFIER_NODE. */
|
||||
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2)
|
||||
|
||||
/* A list-like node for chaining overloading candidates. TREE_TYPE is
|
||||
the original name, and the parameter is the FUNCTION_DECL. */
|
||||
DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0)
|
||||
|
||||
/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or
|
||||
"OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The
|
||||
second operand (if non-NULL) is the SCOPE. The third operand is
|
||||
the TYPE node corresponding to the DESTRUCTOR. The type of the
|
||||
first operand will always be a scalar type.
|
||||
|
||||
The type of a PSEUDO_DTOR_EXPR is always "void", even though it can
|
||||
be used as if it were a zero-argument function. We handle the
|
||||
function-call case specially, and giving it "void" type prevents it
|
||||
being used in expressions in ways that are not permitted. */
|
||||
DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", tcc_expression, 3)
|
||||
|
||||
/* A whole bunch of tree codes for the initial, superficial parsing of
|
||||
templates. */
|
||||
DEFTREECODE (MODOP_EXPR, "modop_expr", tcc_expression, 3)
|
||||
DEFTREECODE (CAST_EXPR, "cast_expr", tcc_unary, 1)
|
||||
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1)
|
||||
DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1)
|
||||
DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1)
|
||||
DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1)
|
||||
DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1)
|
||||
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2)
|
||||
DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
|
||||
DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
|
||||
|
||||
/* A placeholder for an expression that is not type-dependent, but
|
||||
does occur in a template. When an expression that is not
|
||||
type-dependent appears in a larger expression, we must compute the
|
||||
type of that larger expression. That computation would normally
|
||||
modify the original expression, which would change the mangling of
|
||||
that expression if it appeared in a template argument list. In
|
||||
that situation, we create a NON_DEPENDENT_EXPR to take the place of
|
||||
the original expression. The expression is the only operand -- it
|
||||
is only needed for diagnostics. */
|
||||
DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
|
||||
|
||||
/* CTOR_INITIALIZER is a placeholder in template code for a call to
|
||||
setup_vtbl_pointer (and appears in all functions, not just ctors). */
|
||||
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
|
||||
|
||||
DEFTREECODE (TRY_BLOCK, "try_block", tcc_statement, 2)
|
||||
|
||||
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2)
|
||||
|
||||
/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
|
||||
CATCH_ALL_TYPE, then the handler catches all types. The declaration of
|
||||
the catch variable is in HANDLER_PARMS, and the body block in
|
||||
HANDLER_BODY. */
|
||||
DEFTREECODE (HANDLER, "handler", tcc_statement, 2)
|
||||
|
||||
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
|
||||
throw, and must call terminate if it does. The second argument
|
||||
is a condition, used in templates to express noexcept (condition). */
|
||||
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2)
|
||||
|
||||
/* A CLEANUP_STMT marks the point at which a declaration is fully
|
||||
constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
|
||||
when CLEANUP_BODY completes. */
|
||||
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3)
|
||||
|
||||
/* Represents an 'if' statement. The operands are IF_COND,
|
||||
THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively. */
|
||||
/* ??? It is currently still necessary to distinguish between IF_STMT
|
||||
and COND_EXPR for the benefit of templates. */
|
||||
DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4)
|
||||
|
||||
/* Used to represent a `for' statement. The operands are
|
||||
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
|
||||
DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5)
|
||||
|
||||
/* Used to represent a range-based `for' statement. The operands are
|
||||
RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE,
|
||||
respectively. Only used in templates. */
|
||||
DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4)
|
||||
|
||||
/* Used to represent a 'while' statement. The operands are WHILE_COND
|
||||
and WHILE_BODY, respectively. */
|
||||
DEFTREECODE (WHILE_STMT, "while_stmt", tcc_statement, 2)
|
||||
|
||||
/* Used to represent a 'do' statement. The operands are DO_BODY and
|
||||
DO_COND, respectively. */
|
||||
DEFTREECODE (DO_STMT, "do_stmt", tcc_statement, 2)
|
||||
|
||||
/* Used to represent a 'break' statement. */
|
||||
DEFTREECODE (BREAK_STMT, "break_stmt", tcc_statement, 0)
|
||||
|
||||
/* Used to represent a 'continue' statement. */
|
||||
DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0)
|
||||
|
||||
/* Used to represent a 'switch' statement. The operands are
|
||||
SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE, and
|
||||
SWITCH_STMT_SCOPE, respectively. */
|
||||
DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4)
|
||||
|
||||
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
|
||||
obtain the expression. */
|
||||
DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1)
|
||||
|
||||
DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
|
||||
|
||||
/* Represents an 'offsetof' expression during template expansion. */
|
||||
DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1)
|
||||
|
||||
/* Represents the -> operator during template expansion. */
|
||||
DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1)
|
||||
|
||||
/* Represents an '__alignof__' expression during template
|
||||
expansion. */
|
||||
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_expression, 1)
|
||||
|
||||
/* Represents an Objective-C++ '@encode' expression during template
|
||||
expansion. */
|
||||
DEFTREECODE (AT_ENCODE_EXPR, "at_encode_expr", tcc_expression, 1)
|
||||
|
||||
/* A STMT_EXPR represents a statement-expression during template
|
||||
expansion. This is the GCC extension { ( ... ) }. The
|
||||
STMT_EXPR_STMT is the statement given by the expression. */
|
||||
DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1)
|
||||
|
||||
/* Unary plus. Operand 0 is the expression to which the unary plus
|
||||
is applied. */
|
||||
DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1)
|
||||
|
||||
/** C++0x extensions. */
|
||||
|
||||
/* A static assertion. This is a C++0x extension.
|
||||
STATIC_ASSERT_CONDITION contains the condition that is being
|
||||
checked. STATIC_ASSERT_MESSAGE contains the message (a string
|
||||
literal) to be displayed if the condition fails to hold. */
|
||||
DEFTREECODE (STATIC_ASSERT, "static_assert", tcc_exceptional, 0)
|
||||
|
||||
/* Represents an argument pack of types (or templates). An argument
|
||||
pack stores zero or more arguments that will be used to instantiate
|
||||
a parameter pack.
|
||||
|
||||
ARGUMENT_PACK_ARGS retrieves the arguments stored in the argument
|
||||
pack.
|
||||
|
||||
Example:
|
||||
template<typename... Values>
|
||||
class tuple { ... };
|
||||
|
||||
tuple<int, float, double> t;
|
||||
|
||||
Values is a (template) parameter pack. When tuple<int, float,
|
||||
double> is instantiated, the Values parameter pack is instantiated
|
||||
with the argument pack <int, float, double>. ARGUMENT_PACK_ARGS will
|
||||
be a TREE_VEC containing int, float, and double. */
|
||||
DEFTREECODE (TYPE_ARGUMENT_PACK, "type_argument_pack", tcc_type, 0)
|
||||
|
||||
/* Represents an argument pack of values, which can be used either for
|
||||
non-type template arguments or function call arguments.
|
||||
|
||||
NONTYPE_ARGUMENT_PACK plays precisely the same role as
|
||||
TYPE_ARGUMENT_PACK, but will be used for packing non-type template
|
||||
arguments (e.g., "int... Dimensions") or function arguments ("const
|
||||
Args&... args"). */
|
||||
DEFTREECODE (NONTYPE_ARGUMENT_PACK, "nontype_argument_pack", tcc_expression, 1)
|
||||
|
||||
/* Represents a type expression that will be expanded into a list of
|
||||
types when instantiated with one or more argument packs.
|
||||
|
||||
PACK_EXPANSION_PATTERN retrieves the expansion pattern. This is
|
||||
the type or expression that we will substitute into with each
|
||||
argument in an argument pack.
|
||||
|
||||
SET_PACK_EXPANSION_PATTERN sets the expansion pattern.
|
||||
|
||||
PACK_EXPANSION_PARAMETER_PACKS contains a TREE_LIST of the parameter
|
||||
packs that are used in this pack expansion.
|
||||
|
||||
Example:
|
||||
template<typename... Values>
|
||||
struct tied : tuple<Values&...> {
|
||||
// ...
|
||||
};
|
||||
|
||||
The derivation from tuple contains a TYPE_PACK_EXPANSION for the
|
||||
template arguments. Its PACK_EXPANSION_PATTERN is "Values&" and its
|
||||
PACK_EXPANSION_PARAMETER_PACKS will contain "Values". */
|
||||
DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0)
|
||||
|
||||
/* Represents an expression that will be expanded into a list of
|
||||
expressions when instantiated with one or more argument packs.
|
||||
|
||||
EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION,
|
||||
but will be used for expressions. */
|
||||
DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 3)
|
||||
|
||||
/* Selects the Ith parameter out of an argument pack. This node will
|
||||
be used when instantiating pack expansions; see
|
||||
tsubst_pack_expansion.
|
||||
|
||||
ARGUMENT_PACK_SELECT_FROM_PACK contains the *_ARGUMENT_PACK node
|
||||
from which the argument will be selected.
|
||||
|
||||
ARGUMENT_PACK_SELECT_INDEX contains the index into the argument
|
||||
pack that will be returned by this ARGUMENT_PACK_SELECT node. The
|
||||
index is a machine integer. */
|
||||
DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0)
|
||||
|
||||
/** C++ extensions. */
|
||||
|
||||
/* Represents a trait expression during template expansion. */
|
||||
DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0)
|
||||
|
||||
/* A lambda expression. This is a C++0x extension.
|
||||
LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be
|
||||
none.
|
||||
LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'.
|
||||
LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists.
|
||||
LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to
|
||||
be pushed once scope returns to the lambda.
|
||||
LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable.
|
||||
LAMBDA_EXPR_RETURN_TYPE holds the return type, if it was specified. */
|
||||
DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0)
|
||||
|
||||
/* The declared type of an expression. This is a C++0x extension.
|
||||
DECLTYPE_TYPE_EXPR is the expression whose type we are computing.
|
||||
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P states whether the
|
||||
expression was parsed as an id-expression or a member access
|
||||
expression. When false, it was parsed as a full expression.
|
||||
DECLTYPE_FOR_LAMBDA_CAPTURE is set if we want lambda capture semantics.
|
||||
DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */
|
||||
DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
|
||||
|
||||
/* A type designated by `__underlying_type (type)'.
|
||||
UNDERLYING_TYPE_TYPE is the type in question. */
|
||||
DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0)
|
||||
|
||||
/* A type designated by one of the bases type traits.
|
||||
BASES_TYPE is the type in question. */
|
||||
DEFTREECODE (BASES, "bases", tcc_type, 0)
|
||||
|
||||
/* Used to represent the template information stored by template
|
||||
specializations.
|
||||
The accessors are:
|
||||
TI_TEMPLATE the template declaration associated to the specialization
|
||||
TI_ARGS the arguments of the template specialization
|
||||
TI_TYPEDEFS_NEEDING_ACCESS_CHECKING the vector of typedefs used in
|
||||
the pattern of the template for which access check is needed at template
|
||||
instantiation time. */
|
||||
DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
End:
|
||||
*/
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,79 @@
|
|||
/* Interface for the GNU C++ pretty-printer.
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_CXX_PRETTY_PRINT_H
|
||||
#define GCC_CXX_PRETTY_PRINT_H
|
||||
|
||||
#include "c-family/c-pretty-print.h"
|
||||
|
||||
#undef pp_c_base
|
||||
#define pp_c_base(PP) (&(PP)->c_base)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Ask for a qualified-id. */
|
||||
pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
|
||||
|
||||
} cxx_pretty_printer_flags;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
c_pretty_printer c_base;
|
||||
/* This is the enclosing scope of the entity being pretty-printed. */
|
||||
tree enclosing_scope;
|
||||
} cxx_pretty_printer;
|
||||
|
||||
#define pp_cxx_cv_qualifier_seq(PP, T) \
|
||||
pp_c_type_qualifier_list (pp_c_base (PP), T)
|
||||
|
||||
#define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
|
||||
#define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
|
||||
#define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
|
||||
#define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
|
||||
#define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
|
||||
#define pp_cxx_left_bracket(PP) pp_c_left_bracket (pp_c_base (PP))
|
||||
#define pp_cxx_right_bracket(PP) pp_c_right_bracket (pp_c_base (PP))
|
||||
#define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
|
||||
#define pp_cxx_ampersand(PP) pp_c_ampersand (pp_c_base (PP))
|
||||
#define pp_cxx_star(PP) pp_c_star (pp_c_base (PP))
|
||||
#define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
|
||||
#define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
|
||||
#define pp_cxx_complement(PP) pp_c_complement (pp_c_base (PP))
|
||||
|
||||
#define pp_cxx_ws_string(PP, I) pp_c_ws_string (pp_c_base (PP), I)
|
||||
#define pp_cxx_identifier(PP, I) pp_c_identifier (pp_c_base (PP), I)
|
||||
#define pp_cxx_tree_identifier(PP, T) \
|
||||
pp_c_tree_identifier (pp_c_base (PP), T)
|
||||
|
||||
void pp_cxx_pretty_printer_init (cxx_pretty_printer *);
|
||||
void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
|
||||
void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
|
||||
void pp_cxx_colon_colon (cxx_pretty_printer *);
|
||||
void pp_cxx_separate_with (cxx_pretty_printer *, int);
|
||||
|
||||
void pp_cxx_declaration (cxx_pretty_printer *, tree);
|
||||
void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
|
||||
void pp_cxx_trait_expression (cxx_pretty_printer *, tree);
|
||||
void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree);
|
||||
void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree);
|
||||
void pp_cxx_userdef_literal (cxx_pretty_printer *, tree);
|
||||
|
||||
|
||||
#endif /* GCC_CXX_PRETTY_PRINT_H */
|
||||
|
|
@ -0,0 +1,369 @@
|
|||
/* Declarations for C++ name lookup routines.
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_CP_NAME_LOOKUP_H
|
||||
#define GCC_CP_NAME_LOOKUP_H
|
||||
|
||||
#include "c-family/c-common.h"
|
||||
|
||||
/* The type of dictionary used to map names to types declared at
|
||||
a given scope. */
|
||||
typedef struct binding_table_s *binding_table;
|
||||
typedef struct binding_entry_s *binding_entry;
|
||||
|
||||
/* The type of a routine repeatedly called by binding_table_foreach. */
|
||||
typedef void (*bt_foreach_proc) (binding_entry, void *);
|
||||
|
||||
struct GTY(()) binding_entry_s {
|
||||
binding_entry chain;
|
||||
tree name;
|
||||
tree type;
|
||||
};
|
||||
|
||||
/* These macros indicate the initial chains count for binding_table. */
|
||||
#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
|
||||
#define CLASS_SCOPE_HT_SIZE (1 << 3)
|
||||
#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
|
||||
#define NAMESPACE_STD_HT_SIZE (1 << 8)
|
||||
#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
|
||||
|
||||
extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
|
||||
extern binding_entry binding_table_find (binding_table, tree);
|
||||
|
||||
/* Datatype that represents binding established by a declaration between
|
||||
a name and a C++ entity. */
|
||||
typedef struct cxx_binding cxx_binding;
|
||||
|
||||
/* The datatype used to implement C++ scope. */
|
||||
typedef struct cp_binding_level cp_binding_level;
|
||||
|
||||
/* Nonzero if this binding is for a local scope, as opposed to a class
|
||||
or namespace scope. */
|
||||
#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
|
||||
|
||||
/* True if NODE->value is from a base class of the class which is
|
||||
currently being defined. */
|
||||
#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
|
||||
|
||||
struct GTY(()) cxx_binding {
|
||||
/* Link to chain together various bindings for this name. */
|
||||
cxx_binding *previous;
|
||||
/* The non-type entity this name is bound to. */
|
||||
tree value;
|
||||
/* The type entity this name is bound to. */
|
||||
tree type;
|
||||
/* The scope at which this binding was made. */
|
||||
cp_binding_level *scope;
|
||||
unsigned value_is_inherited : 1;
|
||||
unsigned is_local : 1;
|
||||
};
|
||||
|
||||
/* Datatype used to temporarily save C++ bindings (for implicit
|
||||
instantiations purposes and like). Implemented in decl.c. */
|
||||
typedef struct GTY(()) cxx_saved_binding {
|
||||
/* The name of the current binding. */
|
||||
tree identifier;
|
||||
/* The binding we're saving. */
|
||||
cxx_binding *binding;
|
||||
tree real_type_value;
|
||||
} cxx_saved_binding;
|
||||
|
||||
|
||||
extern tree identifier_type_value (tree);
|
||||
extern void set_identifier_type_value (tree, tree);
|
||||
extern void pop_binding (tree, tree);
|
||||
extern tree constructor_name (tree);
|
||||
extern bool constructor_name_p (tree, tree);
|
||||
|
||||
/* The kinds of scopes we recognize. */
|
||||
typedef enum scope_kind {
|
||||
sk_block = 0, /* An ordinary block scope. This enumerator must
|
||||
have the value zero because "cp_binding_level"
|
||||
is initialized by using "memset" to set the
|
||||
contents to zero, and the default scope kind
|
||||
is "sk_block". */
|
||||
sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
|
||||
pseudo in that it is transparent to name lookup
|
||||
activities. */
|
||||
sk_try, /* A try-block. */
|
||||
sk_catch, /* A catch-block. */
|
||||
sk_for, /* The scope of the variable declared in a
|
||||
for-init-statement. */
|
||||
sk_cond, /* The scope of the variable declared in the condition
|
||||
of an if or switch statement. */
|
||||
sk_function_parms, /* The scope containing function parameters. */
|
||||
sk_class, /* The scope containing the members of a class. */
|
||||
sk_scoped_enum, /* The scope containing the enumertors of a C++0x
|
||||
scoped enumeration. */
|
||||
sk_namespace, /* The scope containing the members of a
|
||||
namespace, including the global scope. */
|
||||
sk_template_parms, /* A scope for template parameters. */
|
||||
sk_template_spec, /* Like sk_template_parms, but for an explicit
|
||||
specialization. Since, by definition, an
|
||||
explicit specialization is introduced by
|
||||
"template <>", this scope is always empty. */
|
||||
sk_omp /* An OpenMP structured block. */
|
||||
} scope_kind;
|
||||
|
||||
/* The scope where the class/struct/union/enum tag applies. */
|
||||
typedef enum tag_scope {
|
||||
ts_current = 0, /* Current scope only. This is for the
|
||||
class-key identifier;
|
||||
case mentioned in [basic.lookup.elab]/2,
|
||||
or the class/enum definition
|
||||
class-key identifier { ... }; */
|
||||
ts_global = 1, /* All scopes. This is the 3.4.1
|
||||
[basic.lookup.unqual] lookup mentioned
|
||||
in [basic.lookup.elab]/2. */
|
||||
ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
|
||||
only, for friend class lookup
|
||||
according to [namespace.memdef]/3
|
||||
and [class.friend]/9. */
|
||||
ts_lambda = 3 /* Declaring a lambda closure. */
|
||||
} tag_scope;
|
||||
|
||||
typedef struct GTY(()) cp_class_binding {
|
||||
cxx_binding *base;
|
||||
/* The bound name. */
|
||||
tree identifier;
|
||||
} cp_class_binding;
|
||||
|
||||
|
||||
typedef struct GTY(()) cp_label_binding {
|
||||
/* The bound LABEL_DECL. */
|
||||
tree label;
|
||||
/* The previous IDENTIFIER_LABEL_VALUE. */
|
||||
tree prev_value;
|
||||
} cp_label_binding;
|
||||
|
||||
|
||||
/* For each binding contour we allocate a binding_level structure
|
||||
which records the names defined in that contour.
|
||||
Contours include:
|
||||
0) the global one
|
||||
1) one for each function definition,
|
||||
where internal declarations of the parameters appear.
|
||||
2) one for each compound statement,
|
||||
to record its declarations.
|
||||
|
||||
The current meaning of a name can be found by searching the levels
|
||||
from the current one out to the global one.
|
||||
|
||||
Off to the side, may be the class_binding_level. This exists only
|
||||
to catch class-local declarations. It is otherwise nonexistent.
|
||||
|
||||
Also there may be binding levels that catch cleanups that must be
|
||||
run when exceptions occur. Thus, to see whether a name is bound in
|
||||
the current scope, it is not enough to look in the
|
||||
CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
|
||||
instead. */
|
||||
|
||||
/* Note that the information in the `names' component of the global contour
|
||||
is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
|
||||
|
||||
struct GTY(()) cp_binding_level {
|
||||
/* A chain of _DECL nodes for all variables, constants, functions,
|
||||
and typedef types. These are in the reverse of the order
|
||||
supplied. There may be OVERLOADs on this list, too, but they
|
||||
are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
|
||||
tree names;
|
||||
|
||||
/* A chain of NAMESPACE_DECL nodes. */
|
||||
tree namespaces;
|
||||
|
||||
/* An array of static functions and variables (for namespaces only) */
|
||||
vec<tree, va_gc> *static_decls;
|
||||
|
||||
/* A list of USING_DECL nodes. */
|
||||
tree usings;
|
||||
|
||||
/* A list of used namespaces. PURPOSE is the namespace,
|
||||
VALUE the common ancestor with this binding_level's namespace. */
|
||||
tree using_directives;
|
||||
|
||||
/* For the binding level corresponding to a class, the entities
|
||||
declared in the class or its base classes. */
|
||||
vec<cp_class_binding, va_gc> *class_shadowed;
|
||||
|
||||
/* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
|
||||
is used for all binding levels. The TREE_PURPOSE is the name of
|
||||
the entity, the TREE_TYPE is the associated type. In addition
|
||||
the TREE_VALUE is the IDENTIFIER_TYPE_VALUE before we entered
|
||||
the class. */
|
||||
tree type_shadowed;
|
||||
|
||||
/* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and
|
||||
used for all binding levels. */
|
||||
vec<cp_label_binding, va_gc> *shadowed_labels;
|
||||
|
||||
/* For each level (except not the global one),
|
||||
a chain of BLOCK nodes for all the levels
|
||||
that were entered and exited one level down. */
|
||||
tree blocks;
|
||||
|
||||
/* The entity (namespace, class, function) the scope of which this
|
||||
binding contour corresponds to. Otherwise NULL. */
|
||||
tree this_entity;
|
||||
|
||||
/* The binding level which this one is contained in (inherits from). */
|
||||
cp_binding_level *level_chain;
|
||||
|
||||
/* List of VAR_DECLS saved from a previous for statement.
|
||||
These would be dead in ISO-conforming code, but might
|
||||
be referenced in ARM-era code. */
|
||||
vec<tree, va_gc> *dead_vars_from_for;
|
||||
|
||||
/* STATEMENT_LIST for statements in this binding contour.
|
||||
Only used at present for SK_CLEANUP temporary bindings. */
|
||||
tree statement_list;
|
||||
|
||||
/* Binding depth at which this level began. */
|
||||
int binding_depth;
|
||||
|
||||
/* The kind of scope that this object represents. However, a
|
||||
SK_TEMPLATE_SPEC scope is represented with KIND set to
|
||||
SK_TEMPLATE_PARMS and EXPLICIT_SPEC_P set to true. */
|
||||
ENUM_BITFIELD (scope_kind) kind : 4;
|
||||
|
||||
/* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
|
||||
only valid if KIND == SK_TEMPLATE_PARMS. */
|
||||
BOOL_BITFIELD explicit_spec_p : 1;
|
||||
|
||||
/* true means make a BLOCK for this level regardless of all else. */
|
||||
unsigned keep : 1;
|
||||
|
||||
/* Nonzero if this level can safely have additional
|
||||
cleanup-needing variables added to it. */
|
||||
unsigned more_cleanups_ok : 1;
|
||||
unsigned have_cleanups : 1;
|
||||
|
||||
/* 24 bits left to fill a 32-bit word. */
|
||||
};
|
||||
|
||||
/* The binding level currently in effect. */
|
||||
|
||||
#define current_binding_level \
|
||||
(*(cfun && cp_function_chain && cp_function_chain->bindings \
|
||||
? &cp_function_chain->bindings \
|
||||
: &scope_chain->bindings))
|
||||
|
||||
/* The binding level of the current class, if any. */
|
||||
|
||||
#define class_binding_level scope_chain->class_bindings
|
||||
|
||||
/* The tree node representing the global scope. */
|
||||
extern GTY(()) tree global_namespace;
|
||||
extern GTY(()) tree global_scope_name;
|
||||
|
||||
/* Indicates that there is a type value in some namespace, although
|
||||
that is not necessarily in scope at the moment. */
|
||||
|
||||
extern GTY(()) tree global_type_node;
|
||||
|
||||
/* True if SCOPE designates the global scope binding contour. */
|
||||
#define global_scope_p(SCOPE) \
|
||||
((SCOPE) == NAMESPACE_LEVEL (global_namespace))
|
||||
|
||||
extern cp_binding_level *leave_scope (void);
|
||||
extern bool kept_level_p (void);
|
||||
extern bool global_bindings_p (void);
|
||||
extern bool toplevel_bindings_p (void);
|
||||
extern bool namespace_bindings_p (void);
|
||||
extern bool local_bindings_p (void);
|
||||
extern bool template_parm_scope_p (void);
|
||||
extern scope_kind innermost_scope_kind (void);
|
||||
extern cp_binding_level *begin_scope (scope_kind, tree);
|
||||
extern void print_binding_stack (void);
|
||||
extern void push_to_top_level (void);
|
||||
extern void pop_from_top_level (void);
|
||||
extern void pop_everything (void);
|
||||
extern void keep_next_level (bool);
|
||||
extern bool is_ancestor (tree, tree);
|
||||
extern tree push_scope (tree);
|
||||
extern void pop_scope (tree);
|
||||
extern tree push_inner_scope (tree);
|
||||
extern void pop_inner_scope (tree, tree);
|
||||
extern void push_binding_level (cp_binding_level *);
|
||||
|
||||
extern void push_namespace (tree);
|
||||
extern void pop_namespace (void);
|
||||
extern void push_nested_namespace (tree);
|
||||
extern void pop_nested_namespace (tree);
|
||||
extern bool handle_namespace_attrs (tree, tree);
|
||||
extern void pushlevel_class (void);
|
||||
extern void poplevel_class (void);
|
||||
extern tree pushdecl_with_scope (tree, cp_binding_level *, bool);
|
||||
extern tree lookup_name_prefer_type (tree, int);
|
||||
extern tree lookup_name_real (tree, int, int, bool, int, int);
|
||||
extern tree lookup_type_scope (tree, tag_scope);
|
||||
extern tree namespace_binding (tree, tree);
|
||||
extern void set_namespace_binding (tree, tree, tree);
|
||||
extern bool hidden_name_p (tree);
|
||||
extern tree remove_hidden_names (tree);
|
||||
extern tree lookup_qualified_name (tree, tree, bool, bool);
|
||||
extern tree lookup_name_nonclass (tree);
|
||||
extern tree lookup_name_innermost_nonclass_level (tree);
|
||||
extern bool is_local_extern (tree);
|
||||
extern tree lookup_function_nonclass (tree, vec<tree, va_gc> *, bool);
|
||||
extern void push_local_binding (tree, tree, int);
|
||||
extern bool pushdecl_class_level (tree);
|
||||
extern tree pushdecl_namespace_level (tree, bool);
|
||||
extern bool push_class_level_binding (tree, tree);
|
||||
extern tree getdecls (void);
|
||||
extern int function_parm_depth (void);
|
||||
extern tree cp_namespace_decls (tree);
|
||||
extern void set_decl_namespace (tree, tree, bool);
|
||||
extern void push_decl_namespace (tree);
|
||||
extern void pop_decl_namespace (void);
|
||||
extern void do_namespace_alias (tree, tree);
|
||||
extern void do_toplevel_using_decl (tree, tree, tree);
|
||||
extern void do_local_using_decl (tree, tree, tree);
|
||||
extern tree do_class_using_decl (tree, tree);
|
||||
extern void do_using_directive (tree);
|
||||
extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *, bool);
|
||||
extern bool is_associated_namespace (tree, tree);
|
||||
extern void parse_using_directive (tree, tree);
|
||||
extern tree innermost_non_namespace_value (tree);
|
||||
extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
|
||||
extern void cp_emit_debug_info_for_using (tree, tree);
|
||||
|
||||
/* Set *DECL to the (non-hidden) declaration for ID at global scope,
|
||||
if present and return true; otherwise return false. */
|
||||
|
||||
static inline bool
|
||||
get_global_value_if_present (tree id, tree *decl)
|
||||
{
|
||||
tree global_value = namespace_binding (id, global_namespace);
|
||||
if (global_value)
|
||||
*decl = global_value;
|
||||
return global_value != NULL;
|
||||
}
|
||||
|
||||
/* True is the binding of IDENTIFIER at global scope names a type. */
|
||||
|
||||
static inline bool
|
||||
is_typename_at_global_scope (tree id)
|
||||
{
|
||||
tree global_value = namespace_binding (id, global_namespace);
|
||||
|
||||
return global_value && TREE_CODE (global_value) == TYPE_DECL;
|
||||
}
|
||||
|
||||
#endif /* GCC_CP_NAME_LOOKUP_H */
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* CPP Library.
|
||||
Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
||||
Contributed by Per Bothner, 1994-95.
|
||||
Based on CCCP program by Paul Rubin, June 1986
|
||||
Adapted to ANSI C, Richard Stallman, Jan 1987
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_CPPDEFAULT_H
|
||||
#define GCC_CPPDEFAULT_H
|
||||
|
||||
/* This is the default list of directories to search for include files.
|
||||
It may be overridden by the various -I and -ixxx options.
|
||||
|
||||
#include "file" looks in the same directory as the current file,
|
||||
then this list.
|
||||
#include <file> just looks in this list.
|
||||
|
||||
All these directories are treated as `system' include directories
|
||||
(they are not subject to pedantic warnings in some cases). */
|
||||
|
||||
struct default_include
|
||||
{
|
||||
const char *const fname; /* The name of the directory. */
|
||||
const char *const component; /* The component containing the directory
|
||||
(see update_path in prefix.c) */
|
||||
const char cplusplus; /* Only look here if we're compiling C++. */
|
||||
const char cxx_aware; /* Includes in this directory don't need to
|
||||
be wrapped in extern "C" when compiling
|
||||
C++. */
|
||||
const char add_sysroot; /* FNAME should be prefixed by
|
||||
cpp_SYSROOT. */
|
||||
const char multilib; /* FNAME should have appended
|
||||
- the multilib path specified with -imultilib
|
||||
when set to 1,
|
||||
- the multiarch path specified with
|
||||
-imultiarch, when set to 2. */
|
||||
};
|
||||
|
||||
extern const struct default_include cpp_include_defaults[];
|
||||
extern const char cpp_GCC_INCLUDE_DIR[];
|
||||
extern const size_t cpp_GCC_INCLUDE_DIR_len;
|
||||
|
||||
/* The configure-time prefix, i.e., the value supplied as the argument
|
||||
to --prefix=. */
|
||||
extern const char cpp_PREFIX[];
|
||||
/* The length of the configure-time prefix. */
|
||||
extern const size_t cpp_PREFIX_len;
|
||||
/* The configure-time execution prefix. This is typically the lib/gcc
|
||||
subdirectory of cpp_PREFIX. */
|
||||
extern const char cpp_EXEC_PREFIX[];
|
||||
/* The run-time execution prefix. This is typically the lib/gcc
|
||||
subdirectory of the actual installation. */
|
||||
extern const char *gcc_exec_prefix;
|
||||
|
||||
/* Return true if the toolchain is relocated. */
|
||||
bool cpp_relocated (void);
|
||||
|
||||
#endif /* ! GCC_CPPDEFAULT_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,195 @@
|
|||
/* Debug hooks for GCC.
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_DEBUG_H
|
||||
#define GCC_DEBUG_H
|
||||
|
||||
/* This structure contains hooks for the debug information output
|
||||
functions, accessed through the global instance debug_hooks set in
|
||||
toplev.c according to command line options. */
|
||||
struct gcc_debug_hooks
|
||||
{
|
||||
/* Initialize debug output. MAIN_FILENAME is the name of the main
|
||||
input file. */
|
||||
void (* init) (const char *main_filename);
|
||||
|
||||
/* Output debug symbols. */
|
||||
void (* finish) (const char *main_filename);
|
||||
|
||||
/* Called from cgraph_optimize before starting to assemble
|
||||
functions/variables/toplevel asms. */
|
||||
void (* assembly_start) (void);
|
||||
|
||||
/* Macro defined on line LINE with name and expansion TEXT. */
|
||||
void (* define) (unsigned int line, const char *text);
|
||||
|
||||
/* MACRO undefined on line LINE. */
|
||||
void (* undef) (unsigned int line, const char *macro);
|
||||
|
||||
/* Record the beginning of a new source file FILE from LINE number
|
||||
in the previous one. */
|
||||
void (* start_source_file) (unsigned int line, const char *file);
|
||||
|
||||
/* Record the resumption of a source file. LINE is the line number
|
||||
in the source file we are returning to. */
|
||||
void (* end_source_file) (unsigned int line);
|
||||
|
||||
/* Record the beginning of block N, counting from 1 and not
|
||||
including the function-scope block, at LINE. */
|
||||
void (* begin_block) (unsigned int line, unsigned int n);
|
||||
|
||||
/* Record the end of a block. Arguments as for begin_block. */
|
||||
void (* end_block) (unsigned int line, unsigned int n);
|
||||
|
||||
/* Returns nonzero if it is appropriate not to emit any debugging
|
||||
information for BLOCK, because it doesn't contain any
|
||||
instructions. This may not be the case for blocks containing
|
||||
nested functions, since we may actually call such a function even
|
||||
though the BLOCK information is messed up. Defaults to true. */
|
||||
bool (* ignore_block) (const_tree);
|
||||
|
||||
/* Record a source file location at (FILE, LINE, DISCRIMINATOR). */
|
||||
void (* source_line) (unsigned int line, const char *file,
|
||||
int discriminator, bool is_stmt);
|
||||
|
||||
/* Called at start of prologue code. LINE is the first line in the
|
||||
function. */
|
||||
void (* begin_prologue) (unsigned int line, const char *file);
|
||||
|
||||
/* Called at end of prologue code. LINE is the first line in the
|
||||
function. */
|
||||
void (* end_prologue) (unsigned int line, const char *file);
|
||||
|
||||
/* Called at beginning of epilogue code. */
|
||||
void (* begin_epilogue) (unsigned int line, const char *file);
|
||||
|
||||
/* Record end of epilogue code. */
|
||||
void (* end_epilogue) (unsigned int line, const char *file);
|
||||
|
||||
/* Called at start of function DECL, before it is declared. */
|
||||
void (* begin_function) (tree decl);
|
||||
|
||||
/* Record end of function. LINE is highest line number in function. */
|
||||
void (* end_function) (unsigned int line);
|
||||
|
||||
/* Debug information for a function DECL. This might include the
|
||||
function name (a symbol), its parameters, and the block that
|
||||
makes up the function's body, and the local variables of the
|
||||
function. */
|
||||
void (* function_decl) (tree decl);
|
||||
|
||||
/* Debug information for a global DECL. Called from toplev.c after
|
||||
compilation proper has finished. */
|
||||
void (* global_decl) (tree decl);
|
||||
|
||||
/* Debug information for a type DECL. Called from toplev.c after
|
||||
compilation proper, also from various language front ends to
|
||||
record built-in types. The second argument is properly a
|
||||
boolean, which indicates whether or not the type is a "local"
|
||||
type as determined by the language. (It's not a boolean for
|
||||
legacy reasons.) */
|
||||
void (* type_decl) (tree decl, int local);
|
||||
|
||||
/* Debug information for imported modules and declarations. */
|
||||
void (* imported_module_or_decl) (tree decl, tree name,
|
||||
tree context, bool child);
|
||||
|
||||
/* DECL is an inline function, whose body is present, but which is
|
||||
not being output at this point. */
|
||||
void (* deferred_inline_function) (tree decl);
|
||||
|
||||
/* DECL is an inline function which is about to be emitted out of
|
||||
line. The hook is useful to, e.g., emit abstract debug info for
|
||||
the inline before it gets mangled by optimization. */
|
||||
void (* outlining_inline_function) (tree decl);
|
||||
|
||||
/* Called from final_scan_insn for any CODE_LABEL insn whose
|
||||
LABEL_NAME is non-null. */
|
||||
void (* label) (rtx);
|
||||
|
||||
/* Called after the start and before the end of writing a PCH file.
|
||||
The parameter is 0 if after the start, 1 if before the end. */
|
||||
void (* handle_pch) (unsigned int);
|
||||
|
||||
/* Called from final_scan_insn for any NOTE_INSN_VAR_LOCATION note. */
|
||||
void (* var_location) (rtx);
|
||||
|
||||
/* Called from final_scan_insn if there is a switch between hot and cold
|
||||
text sections. */
|
||||
void (* switch_text_section) (void);
|
||||
|
||||
/* Called from grokdeclarator. Replaces the anonymous name with the
|
||||
type name. */
|
||||
void (* set_name) (tree, tree);
|
||||
|
||||
/* This is 1 if the debug writer wants to see start and end commands for the
|
||||
main source files, and 0 otherwise. */
|
||||
int start_end_main_source_file;
|
||||
|
||||
/* The type of symtab field used by these debug hooks. This is one
|
||||
of the TYPE_SYMTAB_IS_xxx values defined in tree.h. */
|
||||
int tree_type_symtab_field;
|
||||
};
|
||||
|
||||
extern const struct gcc_debug_hooks *debug_hooks;
|
||||
|
||||
/* The do-nothing hooks. */
|
||||
extern void debug_nothing_void (void);
|
||||
extern void debug_nothing_charstar (const char *);
|
||||
extern void debug_nothing_int_charstar (unsigned int, const char *);
|
||||
extern void debug_nothing_int_charstar_int_bool (unsigned int, const char *,
|
||||
int, bool);
|
||||
extern void debug_nothing_int (unsigned int);
|
||||
extern void debug_nothing_int_int (unsigned int, unsigned int);
|
||||
extern void debug_nothing_tree (tree);
|
||||
extern void debug_nothing_tree_tree (tree, tree);
|
||||
extern void debug_nothing_tree_int (tree, int);
|
||||
extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool);
|
||||
extern bool debug_true_const_tree (const_tree);
|
||||
extern void debug_nothing_rtx (rtx);
|
||||
extern void debug_nothing_rtx_rtx (rtx, rtx);
|
||||
|
||||
/* Hooks for various debug formats. */
|
||||
extern const struct gcc_debug_hooks do_nothing_debug_hooks;
|
||||
extern const struct gcc_debug_hooks dbx_debug_hooks;
|
||||
extern const struct gcc_debug_hooks sdb_debug_hooks;
|
||||
extern const struct gcc_debug_hooks xcoff_debug_hooks;
|
||||
extern const struct gcc_debug_hooks dwarf2_debug_hooks;
|
||||
extern const struct gcc_debug_hooks vmsdbg_debug_hooks;
|
||||
|
||||
/* Dwarf2 frame information. */
|
||||
|
||||
extern void dwarf2out_begin_prologue (unsigned int, const char *);
|
||||
extern void dwarf2out_vms_end_prologue (unsigned int, const char *);
|
||||
extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *);
|
||||
extern void dwarf2out_end_epilogue (unsigned int, const char *);
|
||||
extern void dwarf2out_frame_finish (void);
|
||||
/* Decide whether we want to emit frame unwind information for the current
|
||||
translation unit. */
|
||||
extern bool dwarf2out_do_frame (void);
|
||||
extern bool dwarf2out_do_cfi_asm (void);
|
||||
extern void dwarf2out_switch_text_section (void);
|
||||
|
||||
const char *remap_debug_filename (const char *);
|
||||
void add_debug_prefix_map (const char *);
|
||||
|
||||
/* For -fdump-go-spec. */
|
||||
|
||||
extern const struct gcc_debug_hooks *
|
||||
dump_go_spec_init (const char *, const struct gcc_debug_hooks *);
|
||||
|
||||
#endif /* !GCC_DEBUG_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,89 @@
|
|||
/* Declarations of core diagnostic functionality for code that does
|
||||
not need to deal with diagnostic contexts or diagnostic info
|
||||
structures.
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_DIAGNOSTIC_CORE_H
|
||||
#define GCC_DIAGNOSTIC_CORE_H
|
||||
|
||||
#include "input.h"
|
||||
#include "bversion.h"
|
||||
|
||||
/* Constants used to discriminate diagnostics. */
|
||||
typedef enum
|
||||
{
|
||||
#define DEFINE_DIAGNOSTIC_KIND(K, msgid) K,
|
||||
#include "diagnostic.def"
|
||||
#undef DEFINE_DIAGNOSTIC_KIND
|
||||
DK_LAST_DIAGNOSTIC_KIND,
|
||||
/* This is used for tagging pragma pops in the diagnostic
|
||||
classification history chain. */
|
||||
DK_POP
|
||||
} diagnostic_t;
|
||||
|
||||
extern const char *progname;
|
||||
|
||||
extern const char *trim_filename (const char *);
|
||||
|
||||
/* If we haven't already defined a front-end-specific diagnostics
|
||||
style, use the generic one. */
|
||||
#ifndef GCC_DIAG_STYLE
|
||||
#define GCC_DIAG_STYLE __gcc_tdiag__
|
||||
#endif
|
||||
/* None of these functions are suitable for ATTRIBUTE_PRINTF, because
|
||||
each language front end can extend them with its own set of format
|
||||
specifiers. We must use custom format checks. */
|
||||
#if (ENABLE_CHECKING && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION
|
||||
#define ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m)
|
||||
#else
|
||||
#define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m)
|
||||
#endif
|
||||
extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
||||
ATTRIBUTE_NORETURN;
|
||||
/* Pass one of the OPT_W* from options.h as the first parameter. */
|
||||
extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||
extern bool warning_at (location_t, int, const char *, ...)
|
||||
ATTRIBUTE_GCC_DIAG(3,4);
|
||||
extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
||||
extern void error_n (location_t, int, const char *, const char *, ...)
|
||||
ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
|
||||
extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
||||
ATTRIBUTE_NORETURN;
|
||||
/* Pass one of the OPT_W* from options.h as the second parameter. */
|
||||
extern bool pedwarn (location_t, int, const char *, ...)
|
||||
ATTRIBUTE_GCC_DIAG(3,4);
|
||||
extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||
extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
||||
extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||
extern void inform_n (location_t, int, const char *, const char *, ...)
|
||||
ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
|
||||
extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
||||
extern bool emit_diagnostic (diagnostic_t, location_t, int,
|
||||
const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
|
||||
extern bool seen_error (void);
|
||||
|
||||
#ifdef BUFSIZ
|
||||
/* N.B. Unlike all the others, fnotice is just gettext+fprintf, and
|
||||
therefore it can have ATTRIBUTE_PRINTF. */
|
||||
extern void fnotice (FILE *, const char *, ...)
|
||||
ATTRIBUTE_PRINTF_2;
|
||||
#endif
|
||||
|
||||
#endif /* ! GCC_DIAGNOSTIC_CORE_H */
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/* Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* DK_UNSPECIFIED must be first so it has a value of zero. We never
|
||||
assign this kind to an actual diagnostic, we only use this in
|
||||
variables that can hold a kind, to mean they have yet to have a
|
||||
kind specified. I.e. they're uninitialized. Within the diagnostic
|
||||
machinery, this kind also means "don't change the existing kind",
|
||||
meaning "no change is specified". */
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "")
|
||||
|
||||
/* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
|
||||
This is used by the diagnostic machinery when it wants to disable a
|
||||
diagnostic without disabling the option which causes it. */
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "")
|
||||
|
||||
/* The remainder are real diagnostic types. */
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug: ")
|
||||
/* These two would be re-classified as DK_WARNING or DK_ERROR, so the
|
||||
prefix does not matter. */
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn: ")
|
||||
DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror: ")
|
||||
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
/* Various declarations for language-independent diagnostics subroutines.
|
||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_DIAGNOSTIC_H
|
||||
#define GCC_DIAGNOSTIC_H
|
||||
|
||||
#include "pretty-print.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
/* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
|
||||
its context and its KIND (ice, error, warning, note, ...) See complete
|
||||
list in diagnostic.def. */
|
||||
typedef struct diagnostic_info
|
||||
{
|
||||
text_info message;
|
||||
location_t location;
|
||||
unsigned int override_column;
|
||||
/* Auxiliary data for client. */
|
||||
void *x_data;
|
||||
/* The kind of diagnostic it is about. */
|
||||
diagnostic_t kind;
|
||||
/* Which OPT_* directly controls this diagnostic. */
|
||||
int option_index;
|
||||
} diagnostic_info;
|
||||
|
||||
/* Each time a diagnostic's classification is changed with a pragma,
|
||||
we record the change and the location of the change in an array of
|
||||
these structs. */
|
||||
typedef struct diagnostic_classification_change_t
|
||||
{
|
||||
location_t location;
|
||||
int option;
|
||||
diagnostic_t kind;
|
||||
} diagnostic_classification_change_t;
|
||||
|
||||
/* Forward declarations. */
|
||||
typedef void (*diagnostic_starter_fn) (diagnostic_context *,
|
||||
diagnostic_info *);
|
||||
typedef diagnostic_starter_fn diagnostic_finalizer_fn;
|
||||
|
||||
/* This data structure bundles altogether any information relevant to
|
||||
the context of a diagnostic message. */
|
||||
struct diagnostic_context
|
||||
{
|
||||
/* Where most of the diagnostic formatting work is done. */
|
||||
pretty_printer *printer;
|
||||
|
||||
/* The number of times we have issued diagnostics. */
|
||||
int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
|
||||
|
||||
/* True if we should display the "warnings are being tread as error"
|
||||
message, usually displayed once per compiler run. */
|
||||
bool some_warnings_are_errors;
|
||||
|
||||
/* True if it has been requested that warnings be treated as errors. */
|
||||
bool warning_as_error_requested;
|
||||
|
||||
/* The number of option indexes that can be passed to warning() et
|
||||
al. */
|
||||
int n_opts;
|
||||
|
||||
/* For each option index that can be passed to warning() et al
|
||||
(OPT_* from options.h when using this code with the core GCC
|
||||
options), this array may contain a new kind that the diagnostic
|
||||
should be changed to before reporting, or DK_UNSPECIFIED to leave
|
||||
it as the reported kind, or DK_IGNORED to not report it at
|
||||
all. */
|
||||
diagnostic_t *classify_diagnostic;
|
||||
|
||||
/* History of all changes to the classifications above. This list
|
||||
is stored in location-order, so we can search it, either
|
||||
binary-wise or end-to-front, to find the most recent
|
||||
classification for a given diagnostic, given the location of the
|
||||
diagnostic. */
|
||||
diagnostic_classification_change_t *classification_history;
|
||||
|
||||
/* The size of the above array. */
|
||||
int n_classification_history;
|
||||
|
||||
/* For pragma push/pop. */
|
||||
int *push_list;
|
||||
int n_push;
|
||||
|
||||
/* True if we should print the source line with a caret indicating
|
||||
the location. */
|
||||
bool show_caret;
|
||||
|
||||
/* Maximum width of the source line printed. */
|
||||
int caret_max_width;
|
||||
|
||||
/* True if we should print the command line option which controls
|
||||
each diagnostic, if known. */
|
||||
bool show_option_requested;
|
||||
|
||||
/* True if we should raise a SIGABRT on errors. */
|
||||
bool abort_on_error;
|
||||
|
||||
/* True if we should show the column number on diagnostics. */
|
||||
bool show_column;
|
||||
|
||||
/* True if pedwarns are errors. */
|
||||
bool pedantic_errors;
|
||||
|
||||
/* True if permerrors are warnings. */
|
||||
bool permissive;
|
||||
|
||||
/* The index of the option to associate with turning permerrors into
|
||||
warnings. */
|
||||
int opt_permissive;
|
||||
|
||||
/* True if errors are fatal. */
|
||||
bool fatal_errors;
|
||||
|
||||
/* True if all warnings should be disabled. */
|
||||
bool dc_inhibit_warnings;
|
||||
|
||||
/* True if warnings should be given in system headers. */
|
||||
bool dc_warn_system_headers;
|
||||
|
||||
/* Maximum number of errors to report. */
|
||||
unsigned int max_errors;
|
||||
|
||||
/* This function is called before any message is printed out. It is
|
||||
responsible for preparing message prefix and such. For example, it
|
||||
might say:
|
||||
In file included from "/usr/local/include/curses.h:5:
|
||||
from "/home/gdr/src/nifty_printer.h:56:
|
||||
...
|
||||
*/
|
||||
diagnostic_starter_fn begin_diagnostic;
|
||||
|
||||
/* This function is called after the diagnostic message is printed. */
|
||||
diagnostic_finalizer_fn end_diagnostic;
|
||||
|
||||
/* Client hook to report an internal error. */
|
||||
void (*internal_error) (diagnostic_context *, const char *, va_list *);
|
||||
|
||||
/* Client hook to say whether the option controlling a diagnostic is
|
||||
enabled. Returns nonzero if enabled, zero if disabled. */
|
||||
int (*option_enabled) (int, void *);
|
||||
|
||||
/* Client information to pass as second argument to
|
||||
option_enabled. */
|
||||
void *option_state;
|
||||
|
||||
/* Client hook to return the name of an option that controls a
|
||||
diagnostic. Returns malloced memory. The first diagnostic_t
|
||||
argument is the kind of diagnostic before any reclassification
|
||||
(of warnings as errors, etc.); the second is the kind after any
|
||||
reclassification. May return NULL if no name is to be printed.
|
||||
May be passed 0 as well as the index of a particular option. */
|
||||
char *(*option_name) (diagnostic_context *, int, diagnostic_t, diagnostic_t);
|
||||
|
||||
/* Auxiliary data for client. */
|
||||
void *x_data;
|
||||
|
||||
/* Used to detect that the last caret was printed at the same location. */
|
||||
location_t last_location;
|
||||
|
||||
/* Used to detect when the input file stack has changed since last
|
||||
described. */
|
||||
const struct line_map *last_module;
|
||||
|
||||
int lock;
|
||||
|
||||
bool inhibit_notes_p;
|
||||
};
|
||||
|
||||
static inline void
|
||||
diagnostic_inhibit_notes (diagnostic_context * context)
|
||||
{
|
||||
context->inhibit_notes_p = true;
|
||||
}
|
||||
|
||||
|
||||
/* Client supplied function to announce a diagnostic. */
|
||||
#define diagnostic_starter(DC) (DC)->begin_diagnostic
|
||||
|
||||
/* Client supplied function called after a diagnostic message is
|
||||
displayed. */
|
||||
#define diagnostic_finalizer(DC) (DC)->end_diagnostic
|
||||
|
||||
/* Extension hooks for client. */
|
||||
#define diagnostic_context_auxiliary_data(DC) (DC)->x_data
|
||||
#define diagnostic_info_auxiliary_data(DI) (DI)->x_data
|
||||
|
||||
/* Same as pp_format_decoder. Works on 'diagnostic_context *'. */
|
||||
#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
|
||||
|
||||
/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */
|
||||
#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule)
|
||||
|
||||
/* Maximum characters per line in automatic line wrapping mode.
|
||||
Zero means don't wrap lines. */
|
||||
#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff)
|
||||
|
||||
#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer)
|
||||
|
||||
/* True if the last module or file in which a diagnostic was reported is
|
||||
different from the current one. */
|
||||
#define diagnostic_last_module_changed(DC, MAP) \
|
||||
((DC)->last_module != MAP)
|
||||
|
||||
/* Remember the current module or file as being the last one in which we
|
||||
report a diagnostic. */
|
||||
#define diagnostic_set_last_module(DC, MAP) \
|
||||
(DC)->last_module = MAP
|
||||
|
||||
/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
|
||||
#define diagnostic_abort_on_error(DC) \
|
||||
(DC)->abort_on_error = true
|
||||
|
||||
/* This diagnostic_context is used by front-ends that directly output
|
||||
diagnostic messages without going through `error', `warning',
|
||||
and similar functions. */
|
||||
extern diagnostic_context *global_dc;
|
||||
|
||||
/* The total count of a KIND of diagnostics emitted so far. */
|
||||
#define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)]
|
||||
|
||||
/* The number of errors that have been issued so far. Ideally, these
|
||||
would take a diagnostic_context as an argument. */
|
||||
#define errorcount diagnostic_kind_count (global_dc, DK_ERROR)
|
||||
/* Similarly, but for warnings. */
|
||||
#define warningcount diagnostic_kind_count (global_dc, DK_WARNING)
|
||||
/* Similarly, but for sorrys. */
|
||||
#define sorrycount diagnostic_kind_count (global_dc, DK_SORRY)
|
||||
|
||||
/* Returns nonzero if warnings should be emitted. */
|
||||
#define diagnostic_report_warnings_p(DC, LOC) \
|
||||
(!(DC)->dc_inhibit_warnings \
|
||||
&& !(in_system_header_at (LOC) && !(DC)->dc_warn_system_headers))
|
||||
|
||||
#define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
|
||||
|
||||
/* Override the column number to be used for reporting a
|
||||
diagnostic. */
|
||||
#define diagnostic_override_column(DI, COL) (DI)->override_column = (COL)
|
||||
|
||||
/* Override the option index to be used for reporting a
|
||||
diagnostic. */
|
||||
#define diagnostic_override_option_index(DI, OPTIDX) \
|
||||
((DI)->option_index = (OPTIDX))
|
||||
|
||||
/* Diagnostic related functions. */
|
||||
extern void diagnostic_initialize (diagnostic_context *, int);
|
||||
extern void diagnostic_finish (diagnostic_context *);
|
||||
extern void diagnostic_report_current_module (diagnostic_context *, location_t);
|
||||
extern void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *);
|
||||
|
||||
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
|
||||
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
|
||||
int /* optidx */,
|
||||
diagnostic_t /* kind */,
|
||||
location_t);
|
||||
extern void diagnostic_push_diagnostics (diagnostic_context *, location_t);
|
||||
extern void diagnostic_pop_diagnostics (diagnostic_context *, location_t);
|
||||
extern bool diagnostic_report_diagnostic (diagnostic_context *,
|
||||
diagnostic_info *);
|
||||
#ifdef ATTRIBUTE_GCC_DIAG
|
||||
extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
|
||||
location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
|
||||
extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
|
||||
va_list *, location_t,
|
||||
diagnostic_t)
|
||||
ATTRIBUTE_GCC_DIAG(2,0);
|
||||
extern void diagnostic_append_note (diagnostic_context *, location_t,
|
||||
const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
||||
#endif
|
||||
extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *);
|
||||
void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
|
||||
void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
|
||||
void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
|
||||
|
||||
|
||||
/* Pure text formatting support functions. */
|
||||
extern char *file_name_as_prefix (const char *);
|
||||
|
||||
#endif /* ! GCC_DIAGNOSTIC_H */
|
||||
|
|
@ -0,0 +1,457 @@
|
|||
/* Operations with long integers.
|
||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef DOUBLE_INT_H
|
||||
#define DOUBLE_INT_H
|
||||
|
||||
/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
|
||||
It therefore represents a number with precision of
|
||||
2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
|
||||
internal representation will change, if numbers with greater precision
|
||||
are needed, so the users should not rely on it). The representation does
|
||||
not contain any information about signedness of the represented value, so
|
||||
it can be used to represent both signed and unsigned numbers. For
|
||||
operations where the results depend on signedness (division, comparisons),
|
||||
it must be specified separately. For each such operation, there are three
|
||||
versions of the function -- double_int_op, that takes an extra UNS argument
|
||||
giving the signedness of the values, and double_int_sop and double_int_uop
|
||||
that stand for its specializations for signed and unsigned values.
|
||||
|
||||
You may also represent with numbers in smaller precision using double_int.
|
||||
You however need to use double_int_ext (that fills in the bits of the
|
||||
number over the prescribed precision with zeros or with the sign bit) before
|
||||
operations that do not perform arithmetics modulo 2^precision (comparisons,
|
||||
division), and possibly before storing the results, if you want to keep
|
||||
them in some canonical form). In general, the signedness of double_int_ext
|
||||
should match the signedness of the operation.
|
||||
|
||||
??? The components of double_int differ in signedness mostly for
|
||||
historical reasons (they replace an older structure used to represent
|
||||
numbers with precision higher than HOST_WIDE_INT). It might be less
|
||||
confusing to have them both signed or both unsigned. */
|
||||
|
||||
struct double_int
|
||||
{
|
||||
/* Normally, we would define constructors to create instances.
|
||||
Two things prevent us from doing so.
|
||||
First, defining a constructor makes the class non-POD in C++03,
|
||||
and we certainly want double_int to be a POD.
|
||||
Second, the GCC conding conventions prefer explicit conversion,
|
||||
and explicit conversion operators are not available until C++11. */
|
||||
|
||||
static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
|
||||
static double_int from_shwi (HOST_WIDE_INT cst);
|
||||
static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
|
||||
|
||||
/* Construct from a fuffer of length LEN. BUFFER will be read according
|
||||
to byte endianess and word endianess. */
|
||||
static double_int from_buffer (const unsigned char *buffer, int len);
|
||||
|
||||
/* No copy assignment operator or destructor to keep the type a POD. */
|
||||
|
||||
/* There are some special value-creation static member functions. */
|
||||
|
||||
static double_int mask (unsigned prec);
|
||||
static double_int max_value (unsigned int prec, bool uns);
|
||||
static double_int min_value (unsigned int prec, bool uns);
|
||||
|
||||
/* The following functions are mutating operations. */
|
||||
|
||||
double_int &operator ++ (); // prefix
|
||||
double_int &operator -- (); // prefix
|
||||
double_int &operator *= (double_int);
|
||||
double_int &operator += (double_int);
|
||||
double_int &operator -= (double_int);
|
||||
double_int &operator &= (double_int);
|
||||
double_int &operator ^= (double_int);
|
||||
double_int &operator |= (double_int);
|
||||
|
||||
/* The following functions are non-mutating operations. */
|
||||
|
||||
/* Conversion functions. */
|
||||
|
||||
HOST_WIDE_INT to_shwi () const;
|
||||
unsigned HOST_WIDE_INT to_uhwi () const;
|
||||
|
||||
/* Conversion query functions. */
|
||||
|
||||
bool fits_uhwi () const;
|
||||
bool fits_shwi () const;
|
||||
bool fits_hwi (bool uns) const;
|
||||
|
||||
/* Attribute query functions. */
|
||||
|
||||
int trailing_zeros () const;
|
||||
int popcount () const;
|
||||
|
||||
/* Arithmetic query operations. */
|
||||
|
||||
bool multiple_of (double_int, bool, double_int *) const;
|
||||
|
||||
/* Arithmetic operation functions. */
|
||||
|
||||
/* The following operations perform arithmetics modulo 2^precision, so you
|
||||
do not need to call .ext between them, even if you are representing
|
||||
numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */
|
||||
|
||||
double_int set_bit (unsigned) const;
|
||||
double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
|
||||
double_int wide_mul_with_sign (double_int, bool unsigned_p,
|
||||
double_int *higher, bool *overflow) const;
|
||||
double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
|
||||
double_int sub_with_overflow (double_int, bool *overflow) const;
|
||||
double_int neg_with_overflow (bool *overflow) const;
|
||||
|
||||
double_int operator * (double_int) const;
|
||||
double_int operator + (double_int) const;
|
||||
double_int operator - (double_int) const;
|
||||
double_int operator - () const;
|
||||
double_int operator ~ () const;
|
||||
double_int operator & (double_int) const;
|
||||
double_int operator | (double_int) const;
|
||||
double_int operator ^ (double_int) const;
|
||||
double_int and_not (double_int) const;
|
||||
|
||||
double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
|
||||
double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
|
||||
double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||
double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||
double_int llshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||
double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||
double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const;
|
||||
double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const;
|
||||
|
||||
/* You must ensure that double_int::ext is called on the operands
|
||||
of the following operations, if the precision of the numbers
|
||||
is less than HOST_BITS_PER_DOUBLE_INT bits. */
|
||||
|
||||
double_int div (double_int, bool, unsigned) const;
|
||||
double_int sdiv (double_int, unsigned) const;
|
||||
double_int udiv (double_int, unsigned) const;
|
||||
double_int mod (double_int, bool, unsigned) const;
|
||||
double_int smod (double_int, unsigned) const;
|
||||
double_int umod (double_int, unsigned) const;
|
||||
double_int divmod_with_overflow (double_int, bool, unsigned,
|
||||
double_int *, bool *) const;
|
||||
double_int divmod (double_int, bool, unsigned, double_int *) const;
|
||||
double_int sdivmod (double_int, unsigned, double_int *) const;
|
||||
double_int udivmod (double_int, unsigned, double_int *) const;
|
||||
|
||||
/* Precision control functions. */
|
||||
|
||||
double_int ext (unsigned prec, bool uns) const;
|
||||
double_int zext (unsigned prec) const;
|
||||
double_int sext (unsigned prec) const;
|
||||
|
||||
/* Comparative functions. */
|
||||
|
||||
bool is_zero () const;
|
||||
bool is_one () const;
|
||||
bool is_minus_one () const;
|
||||
bool is_negative () const;
|
||||
|
||||
int cmp (double_int b, bool uns) const;
|
||||
int ucmp (double_int b) const;
|
||||
int scmp (double_int b) const;
|
||||
|
||||
bool ult (double_int b) const;
|
||||
bool ule (double_int b) const;
|
||||
bool ugt (double_int b) const;
|
||||
bool slt (double_int b) const;
|
||||
bool sle (double_int b) const;
|
||||
bool sgt (double_int b) const;
|
||||
|
||||
double_int max (double_int b, bool uns);
|
||||
double_int smax (double_int b);
|
||||
double_int umax (double_int b);
|
||||
|
||||
double_int min (double_int b, bool uns);
|
||||
double_int smin (double_int b);
|
||||
double_int umin (double_int b);
|
||||
|
||||
bool operator == (double_int cst2) const;
|
||||
bool operator != (double_int cst2) const;
|
||||
|
||||
/* Please migrate away from using these member variables publically. */
|
||||
|
||||
unsigned HOST_WIDE_INT low;
|
||||
HOST_WIDE_INT high;
|
||||
|
||||
};
|
||||
|
||||
#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)
|
||||
|
||||
/* Constructors and conversions. */
|
||||
|
||||
/* Constructs double_int from integer CST. The bits over the precision of
|
||||
HOST_WIDE_INT are filled with the sign bit. */
|
||||
|
||||
inline double_int
|
||||
double_int::from_shwi (HOST_WIDE_INT cst)
|
||||
{
|
||||
double_int r;
|
||||
r.low = (unsigned HOST_WIDE_INT) cst;
|
||||
r.high = cst < 0 ? -1 : 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Some useful constants. */
|
||||
/* FIXME(crowl): Maybe remove after converting callers?
|
||||
The problem is that a named constant would not be as optimizable,
|
||||
while the functional syntax is more verbose. */
|
||||
|
||||
#define double_int_minus_one (double_int::from_shwi (-1))
|
||||
#define double_int_zero (double_int::from_shwi (0))
|
||||
#define double_int_one (double_int::from_shwi (1))
|
||||
#define double_int_two (double_int::from_shwi (2))
|
||||
#define double_int_ten (double_int::from_shwi (10))
|
||||
|
||||
/* Constructs double_int from unsigned integer CST. The bits over the
|
||||
precision of HOST_WIDE_INT are filled with zeros. */
|
||||
|
||||
inline double_int
|
||||
double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
|
||||
{
|
||||
double_int r;
|
||||
r.low = cst;
|
||||
r.high = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline double_int
|
||||
double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
|
||||
{
|
||||
double_int r;
|
||||
r.low = low;
|
||||
r.high = high;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator ++ ()
|
||||
{
|
||||
*this += double_int_one;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator -- ()
|
||||
{
|
||||
*this -= double_int_one;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator *= (double_int b)
|
||||
{
|
||||
*this = *this * b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator += (double_int b)
|
||||
{
|
||||
*this = *this + b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator -= (double_int b)
|
||||
{
|
||||
*this = *this - b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator &= (double_int b)
|
||||
{
|
||||
*this = *this & b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator ^= (double_int b)
|
||||
{
|
||||
*this = *this ^ b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline double_int &
|
||||
double_int::operator |= (double_int b)
|
||||
{
|
||||
*this = *this | b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Returns value of CST as a signed number. CST must satisfy
|
||||
double_int::fits_signed. */
|
||||
|
||||
inline HOST_WIDE_INT
|
||||
double_int::to_shwi () const
|
||||
{
|
||||
return (HOST_WIDE_INT) low;
|
||||
}
|
||||
|
||||
/* Returns value of CST as an unsigned number. CST must satisfy
|
||||
double_int::fits_unsigned. */
|
||||
|
||||
inline unsigned HOST_WIDE_INT
|
||||
double_int::to_uhwi () const
|
||||
{
|
||||
return low;
|
||||
}
|
||||
|
||||
/* Returns true if CST fits in unsigned HOST_WIDE_INT. */
|
||||
|
||||
inline bool
|
||||
double_int::fits_uhwi () const
|
||||
{
|
||||
return high == 0;
|
||||
}
|
||||
|
||||
/* Logical operations. */
|
||||
|
||||
/* Returns ~A. */
|
||||
|
||||
inline double_int
|
||||
double_int::operator ~ () const
|
||||
{
|
||||
double_int result;
|
||||
result.low = ~low;
|
||||
result.high = ~high;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns A | B. */
|
||||
|
||||
inline double_int
|
||||
double_int::operator | (double_int b) const
|
||||
{
|
||||
double_int result;
|
||||
result.low = low | b.low;
|
||||
result.high = high | b.high;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns A & B. */
|
||||
|
||||
inline double_int
|
||||
double_int::operator & (double_int b) const
|
||||
{
|
||||
double_int result;
|
||||
result.low = low & b.low;
|
||||
result.high = high & b.high;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns A & ~B. */
|
||||
|
||||
inline double_int
|
||||
double_int::and_not (double_int b) const
|
||||
{
|
||||
double_int result;
|
||||
result.low = low & ~b.low;
|
||||
result.high = high & ~b.high;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns A ^ B. */
|
||||
|
||||
inline double_int
|
||||
double_int::operator ^ (double_int b) const
|
||||
{
|
||||
double_int result;
|
||||
result.low = low ^ b.low;
|
||||
result.high = high ^ b.high;
|
||||
return result;
|
||||
}
|
||||
|
||||
void dump_double_int (FILE *, double_int, bool);
|
||||
|
||||
#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
|
||||
|
||||
/* The operands of the following comparison functions must be processed
|
||||
with double_int_ext, if their precision is less than
|
||||
HOST_BITS_PER_DOUBLE_INT bits. */
|
||||
|
||||
/* Returns true if CST is zero. */
|
||||
|
||||
inline bool
|
||||
double_int::is_zero () const
|
||||
{
|
||||
return low == 0 && high == 0;
|
||||
}
|
||||
|
||||
/* Returns true if CST is one. */
|
||||
|
||||
inline bool
|
||||
double_int::is_one () const
|
||||
{
|
||||
return low == 1 && high == 0;
|
||||
}
|
||||
|
||||
/* Returns true if CST is minus one. */
|
||||
|
||||
inline bool
|
||||
double_int::is_minus_one () const
|
||||
{
|
||||
return low == ALL_ONES && high == -1;
|
||||
}
|
||||
|
||||
/* Returns true if CST is negative. */
|
||||
|
||||
inline bool
|
||||
double_int::is_negative () const
|
||||
{
|
||||
return high < 0;
|
||||
}
|
||||
|
||||
/* Returns true if CST1 == CST2. */
|
||||
|
||||
inline bool
|
||||
double_int::operator == (double_int cst2) const
|
||||
{
|
||||
return low == cst2.low && high == cst2.high;
|
||||
}
|
||||
|
||||
/* Returns true if CST1 != CST2. */
|
||||
|
||||
inline bool
|
||||
double_int::operator != (double_int cst2) const
|
||||
{
|
||||
return low != cst2.low || high != cst2.high;
|
||||
}
|
||||
|
||||
/* Return number of set bits of CST. */
|
||||
|
||||
inline int
|
||||
double_int::popcount () const
|
||||
{
|
||||
return popcount_hwi (high) + popcount_hwi (low);
|
||||
}
|
||||
|
||||
|
||||
#ifndef GENERATOR_FILE
|
||||
/* Conversion to and from GMP integer representations. */
|
||||
|
||||
void mpz_set_double_int (mpz_t, double_int, bool);
|
||||
double_int mpz_get_double_int (const_tree, mpz_t, bool);
|
||||
#endif
|
||||
|
||||
#endif /* DOUBLE_INT_H */
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/* Definitions for the shared dumpfile.
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#ifndef GCC_DUMPFILE_H
|
||||
#define GCC_DUMPFILE_H 1
|
||||
|
||||
#include "line-map.h"
|
||||
|
||||
/* Different tree dump places. When you add new tree dump places,
|
||||
extend the DUMP_FILES array in dumpfile.c. */
|
||||
enum tree_dump_index
|
||||
{
|
||||
TDI_none, /* No dump */
|
||||
TDI_cgraph, /* dump function call graph. */
|
||||
TDI_tu, /* dump the whole translation unit. */
|
||||
TDI_class, /* dump class hierarchy. */
|
||||
TDI_original, /* dump each function before optimizing it */
|
||||
TDI_generic, /* dump each function after genericizing it */
|
||||
TDI_nested, /* dump each function after unnesting it */
|
||||
TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */
|
||||
TDI_rtl_all, /* enable all the RTL dumps. */
|
||||
TDI_ipa_all, /* enable all the IPA dumps. */
|
||||
|
||||
TDI_end
|
||||
};
|
||||
|
||||
/* Bit masks to control dumping. Not all values are applicable to all
|
||||
dumps. Add new ones at the end. When you define new values, extend
|
||||
the DUMP_OPTIONS array in dumpfile.c. The TDF_* flags coexist with
|
||||
MSG_* flags (for -fopt-info) and the bit values must be chosen to
|
||||
allow that. */
|
||||
#define TDF_ADDRESS (1 << 0) /* dump node addresses */
|
||||
#define TDF_SLIM (1 << 1) /* don't go wild following links */
|
||||
#define TDF_RAW (1 << 2) /* don't unparse the function */
|
||||
#define TDF_DETAILS (1 << 3) /* show more detailed info about
|
||||
each pass */
|
||||
#define TDF_STATS (1 << 4) /* dump various statistics about
|
||||
each pass */
|
||||
#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */
|
||||
#define TDF_VOPS (1 << 6) /* display virtual operands */
|
||||
#define TDF_LINENO (1 << 7) /* display statement line numbers */
|
||||
#define TDF_UID (1 << 8) /* display decl UIDs */
|
||||
|
||||
#define TDF_TREE (1 << 9) /* is a tree dump */
|
||||
#define TDF_RTL (1 << 10) /* is a RTL dump */
|
||||
#define TDF_IPA (1 << 11) /* is an IPA dump */
|
||||
#define TDF_STMTADDR (1 << 12) /* Address of stmt. */
|
||||
|
||||
#define TDF_GRAPH (1 << 13) /* a graph dump is being emitted */
|
||||
#define TDF_MEMSYMS (1 << 14) /* display memory symbols in expr.
|
||||
Implies TDF_VOPS. */
|
||||
|
||||
#define TDF_DIAGNOSTIC (1 << 15) /* A dump to be put in a diagnostic
|
||||
message. */
|
||||
#define TDF_VERBOSE (1 << 16) /* A dump that uses the full tree
|
||||
dumper to print stmts. */
|
||||
#define TDF_RHS_ONLY (1 << 17) /* a flag to only print the RHS of
|
||||
a gimple stmt. */
|
||||
#define TDF_ASMNAME (1 << 18) /* display asm names of decls */
|
||||
#define TDF_EH (1 << 19) /* display EH region number
|
||||
holding this gimple statement. */
|
||||
#define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */
|
||||
#define TDF_ALIAS (1 << 21) /* display alias information */
|
||||
#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */
|
||||
#define TDF_CSELIB (1 << 23) /* Dump cselib details. */
|
||||
#define TDF_SCEV (1 << 24) /* Dump SCEV details. */
|
||||
#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */
|
||||
#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */
|
||||
#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */
|
||||
#define MSG_NOTE (1 << 28) /* general optimization info */
|
||||
#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
|
||||
| MSG_NOTE)
|
||||
|
||||
|
||||
/* Flags to control high-level -fopt-info dumps. Usually these flags
|
||||
define a group of passes. An optimization pass can be part of
|
||||
multiple groups. */
|
||||
#define OPTGROUP_NONE (0)
|
||||
#define OPTGROUP_IPA (1 << 1) /* IPA optimization passes */
|
||||
#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */
|
||||
#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */
|
||||
#define OPTGROUP_VEC (1 << 4) /* Vectorization passes */
|
||||
#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
|
||||
| OPTGROUP_VEC)
|
||||
|
||||
/* Define a tree dump switch. */
|
||||
struct dump_file_info
|
||||
{
|
||||
const char *suffix; /* suffix to give output file. */
|
||||
const char *swtch; /* command line dump switch */
|
||||
const char *glob; /* command line glob */
|
||||
const char *pfilename; /* filename for the pass-specific stream */
|
||||
const char *alt_filename; /* filename for the -fopt-info stream */
|
||||
FILE *pstream; /* pass-specific dump stream */
|
||||
FILE *alt_stream; /* -fopt-info stream */
|
||||
int pflags; /* dump flags */
|
||||
int optgroup_flags; /* optgroup flags for -fopt-info */
|
||||
int alt_flags; /* flags for opt-info */
|
||||
int pstate; /* state of pass-specific stream */
|
||||
int alt_state; /* state of the -fopt-info stream */
|
||||
int num; /* dump file number */
|
||||
};
|
||||
|
||||
/* In dumpfile.c */
|
||||
extern char *get_dump_file_name (int);
|
||||
extern int dump_initialized_p (int);
|
||||
extern FILE *dump_begin (int, int *);
|
||||
extern void dump_end (int, FILE *);
|
||||
extern int dump_start (int, int *);
|
||||
extern void dump_finish (int);
|
||||
extern void dump_node (const_tree, int, FILE *);
|
||||
extern int dump_switch_p (const char *);
|
||||
extern int opt_info_switch_p (const char *);
|
||||
extern const char *dump_flag_name (int);
|
||||
extern void dump_printf (int, const char *, ...) ATTRIBUTE_PRINTF_2;
|
||||
extern void dump_printf_loc (int, source_location,
|
||||
const char *, ...) ATTRIBUTE_PRINTF_3;
|
||||
extern void dump_basic_block (int, basic_block, int);
|
||||
extern void dump_generic_expr_loc (int, source_location, int, tree);
|
||||
extern void dump_generic_expr (int, int, tree);
|
||||
extern void dump_gimple_stmt_loc (int, source_location, int, gimple, int);
|
||||
extern void dump_gimple_stmt (int, int, gimple, int);
|
||||
extern void print_combine_total_stats (void);
|
||||
extern unsigned int dump_register (const char *, const char *, const char *,
|
||||
int, int);
|
||||
extern bool enable_rtl_dump_file (void);
|
||||
|
||||
/* In combine.c */
|
||||
extern void dump_combine_total_stats (FILE *);
|
||||
/* In cfghooks.c */
|
||||
extern void dump_bb (FILE *, basic_block, int, int);
|
||||
|
||||
/* Global variables used to communicate with passes. */
|
||||
extern FILE *dump_file;
|
||||
extern FILE *alt_dump_file;
|
||||
extern int dump_flags;
|
||||
extern const char *dump_file_name;
|
||||
|
||||
/* Return the dump_file_info for the given phase. */
|
||||
extern struct dump_file_info *get_dump_file_info (int);
|
||||
|
||||
/* Return true if any of the dumps is enabled, false otherwise. */
|
||||
static inline bool
|
||||
dump_enabled_p (void)
|
||||
{
|
||||
return (dump_file || alt_dump_file);
|
||||
}
|
||||
|
||||
#endif /* GCC_DUMPFILE_H */
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* Exported functions from emit-rtl.c
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_EMIT_RTL_H
|
||||
#define GCC_EMIT_RTL_H
|
||||
|
||||
/* Set the alias set of MEM to SET. */
|
||||
extern void set_mem_alias_set (rtx, alias_set_type);
|
||||
|
||||
/* Set the alignment of MEM to ALIGN bits. */
|
||||
extern void set_mem_align (rtx, unsigned int);
|
||||
|
||||
/* Set the address space of MEM to ADDRSPACE. */
|
||||
extern void set_mem_addr_space (rtx, addr_space_t);
|
||||
|
||||
/* Set the expr for MEM to EXPR. */
|
||||
extern void set_mem_expr (rtx, tree);
|
||||
|
||||
/* Set the offset for MEM to OFFSET. */
|
||||
extern void set_mem_offset (rtx, HOST_WIDE_INT);
|
||||
|
||||
/* Clear the offset recorded for MEM. */
|
||||
extern void clear_mem_offset (rtx);
|
||||
|
||||
/* Set the size for MEM to SIZE. */
|
||||
extern void set_mem_size (rtx, HOST_WIDE_INT);
|
||||
|
||||
/* Clear the size recorded for MEM. */
|
||||
extern void clear_mem_size (rtx);
|
||||
|
||||
/* Set the attributes for MEM appropriate for a spill slot. */
|
||||
extern void set_mem_attrs_for_spill (rtx);
|
||||
extern tree get_spill_slot_decl (bool);
|
||||
|
||||
/* Return a memory reference like MEMREF, but with its address changed to
|
||||
ADDR. The caller is asserting that the actual piece of memory pointed
|
||||
to is the same, just the form of the address is being changed, such as
|
||||
by putting something into a register. */
|
||||
extern rtx replace_equiv_address (rtx, rtx);
|
||||
|
||||
/* Likewise, but the reference is not required to be valid. */
|
||||
extern rtx replace_equiv_address_nv (rtx, rtx);
|
||||
|
||||
extern rtx gen_blockage (void);
|
||||
extern rtvec gen_rtvec (int, ...);
|
||||
extern rtx copy_insn_1 (rtx);
|
||||
extern rtx copy_insn (rtx);
|
||||
extern rtx copy_delay_slot_insn (rtx);
|
||||
extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode);
|
||||
extern rtx emit_copy_of_insn_after (rtx, rtx);
|
||||
extern void set_reg_attrs_from_value (rtx, rtx);
|
||||
extern void set_reg_attrs_for_parm (rtx, rtx);
|
||||
extern void set_reg_attrs_for_decl_rtl (tree t, rtx x);
|
||||
extern void adjust_reg_mode (rtx, enum machine_mode);
|
||||
extern int mem_expr_equal_p (const_tree, const_tree);
|
||||
|
||||
extern bool need_atomic_barrier_p (enum memmodel, bool);
|
||||
|
||||
/* Return the first insn of the current sequence or current function. */
|
||||
|
||||
static inline rtx
|
||||
get_insns (void)
|
||||
{
|
||||
return crtl->emit.x_first_insn;
|
||||
}
|
||||
|
||||
/* Specify a new insn as the first in the chain. */
|
||||
|
||||
static inline void
|
||||
set_first_insn (rtx insn)
|
||||
{
|
||||
gcc_checking_assert (!insn || !PREV_INSN (insn));
|
||||
crtl->emit.x_first_insn = insn;
|
||||
}
|
||||
|
||||
/* Return the last insn emitted in current sequence or current function. */
|
||||
|
||||
static inline rtx
|
||||
get_last_insn (void)
|
||||
{
|
||||
return crtl->emit.x_last_insn;
|
||||
}
|
||||
|
||||
/* Specify a new insn as the last in the chain. */
|
||||
|
||||
static inline void
|
||||
set_last_insn (rtx insn)
|
||||
{
|
||||
gcc_checking_assert (!insn || !NEXT_INSN (insn));
|
||||
crtl->emit.x_last_insn = insn;
|
||||
}
|
||||
|
||||
/* Return a number larger than any instruction's uid in this function. */
|
||||
|
||||
static inline int
|
||||
get_max_uid (void)
|
||||
{
|
||||
return crtl->emit.x_cur_insn_uid;
|
||||
}
|
||||
#endif /* GCC_EMIT_RTL_H */
|
||||
|
|
@ -0,0 +1,335 @@
|
|||
/* Exception Handling interface routines.
|
||||
Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
Contributed by Mike Stump <mrs@cygnus.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* No include guards here, but define an include file marker anyway, so
|
||||
that the compiler can keep track of where this file is included. This
|
||||
is e.g. used to avoid including this file in front-end specific files. */
|
||||
#ifndef GCC_EXCEPT_H
|
||||
# define GCC_EXCEPT_H
|
||||
#endif
|
||||
|
||||
#include "hashtab.h"
|
||||
|
||||
struct function;
|
||||
struct eh_region_d;
|
||||
struct pointer_map_t;
|
||||
|
||||
/* The type of an exception region. */
|
||||
enum eh_region_type
|
||||
{
|
||||
/* CLEANUP regions implement e.g. destructors run when exiting a block.
|
||||
They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
|
||||
nodes. It is expected by the runtime that cleanup regions will *not*
|
||||
resume normal program flow, but will continue propagation of the
|
||||
exception. */
|
||||
ERT_CLEANUP,
|
||||
|
||||
/* TRY regions implement catching an exception. The list of types associated
|
||||
with the attached catch handlers is examined in order by the runtime and
|
||||
control is transferred to the appropriate handler. Note that a NULL type
|
||||
list is a catch-all handler, and that it will catch *all* exceptions
|
||||
including those originating from a different language. */
|
||||
ERT_TRY,
|
||||
|
||||
/* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
|
||||
throw(type-list) specification that can be added to C++ functions.
|
||||
The runtime examines the thrown exception vs the type list, and if
|
||||
the exception does not match, transfers control to the handler. The
|
||||
normal handler for C++ calls __cxa_call_unexpected. */
|
||||
ERT_ALLOWED_EXCEPTIONS,
|
||||
|
||||
/* MUST_NOT_THROW regions prevent all exceptions from propagating. This
|
||||
region type is used in C++ to surround destructors being run inside a
|
||||
CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with
|
||||
an empty type list in that the runtime is prepared to terminate the
|
||||
program directly. We only generate code for MUST_NOT_THROW regions
|
||||
along control paths that are already handling an exception within the
|
||||
current function. */
|
||||
ERT_MUST_NOT_THROW
|
||||
};
|
||||
|
||||
|
||||
/* A landing pad for a given exception region. Any transfer of control
|
||||
from the EH runtime to the function happens at a landing pad. */
|
||||
|
||||
struct GTY(()) eh_landing_pad_d
|
||||
{
|
||||
/* The linked list of all landing pads associated with the region. */
|
||||
struct eh_landing_pad_d *next_lp;
|
||||
|
||||
/* The region with which this landing pad is associated. */
|
||||
struct eh_region_d *region;
|
||||
|
||||
/* At the gimple level, the location to which control will be transferred
|
||||
for this landing pad. There can be both EH and normal edges into the
|
||||
block containing the post-landing-pad label. */
|
||||
tree post_landing_pad;
|
||||
|
||||
/* At the rtl level, the location to which the runtime will transfer
|
||||
control. This differs from the post-landing-pad in that the target's
|
||||
EXCEPTION_RECEIVER pattern will be expanded here, as well as other
|
||||
bookkeeping specific to exceptions. There must not be normal edges
|
||||
into the block containing the landing-pad label. */
|
||||
rtx landing_pad;
|
||||
|
||||
/* The index of this landing pad within fun->eh->lp_array. */
|
||||
int index;
|
||||
};
|
||||
|
||||
/* A catch handler associated with an ERT_TRY region. */
|
||||
|
||||
struct GTY(()) eh_catch_d
|
||||
{
|
||||
/* The double-linked list of all catch handlers for the region. */
|
||||
struct eh_catch_d *next_catch;
|
||||
struct eh_catch_d *prev_catch;
|
||||
|
||||
/* A TREE_LIST of runtime type objects that this catch handler
|
||||
will catch, or NULL if all exceptions are caught. */
|
||||
tree type_list;
|
||||
|
||||
/* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
|
||||
having been mapped by assign_filter_values. These integers are to be
|
||||
compared against the __builtin_eh_filter value. */
|
||||
tree filter_list;
|
||||
|
||||
/* The code that should be executed if this catch handler matches the
|
||||
thrown exception. This label is only maintained until
|
||||
pass_lower_eh_dispatch, at which point it is cleared. */
|
||||
tree label;
|
||||
};
|
||||
|
||||
/* Describes one exception region. */
|
||||
|
||||
struct GTY(()) eh_region_d
|
||||
{
|
||||
/* The immediately surrounding region. */
|
||||
struct eh_region_d *outer;
|
||||
|
||||
/* The list of immediately contained regions. */
|
||||
struct eh_region_d *inner;
|
||||
struct eh_region_d *next_peer;
|
||||
|
||||
/* The index of this region within fun->eh->region_array. */
|
||||
int index;
|
||||
|
||||
/* Each region does exactly one thing. */
|
||||
enum eh_region_type type;
|
||||
|
||||
/* Holds the action to perform based on the preceding type. */
|
||||
union eh_region_u {
|
||||
struct eh_region_u_try {
|
||||
/* The double-linked list of all catch handlers for this region. */
|
||||
struct eh_catch_d *first_catch;
|
||||
struct eh_catch_d *last_catch;
|
||||
} GTY ((tag ("ERT_TRY"))) eh_try;
|
||||
|
||||
struct eh_region_u_allowed {
|
||||
/* A TREE_LIST of runtime type objects allowed to pass. */
|
||||
tree type_list;
|
||||
/* The code that should be executed if the thrown exception does
|
||||
not match the type list. This label is only maintained until
|
||||
pass_lower_eh_dispatch, at which point it is cleared. */
|
||||
tree label;
|
||||
/* The integer that will be passed by the runtime to signal that
|
||||
we should execute the code at LABEL. This integer is assigned
|
||||
by assign_filter_values and is to be compared against the
|
||||
__builtin_eh_filter value. */
|
||||
int filter;
|
||||
} GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
|
||||
|
||||
struct eh_region_u_must_not_throw {
|
||||
/* A function decl to be invoked if this region is actually reachable
|
||||
from within the function, rather than implementable from the runtime.
|
||||
The normal way for this to happen is for there to be a CLEANUP region
|
||||
contained within this MUST_NOT_THROW region. Note that if the
|
||||
runtime handles the MUST_NOT_THROW region, we have no control over
|
||||
what termination function is called; it will be decided by the
|
||||
personality function in effect for this CIE. */
|
||||
tree failure_decl;
|
||||
/* The location assigned to the call of FAILURE_DECL, if expanded. */
|
||||
location_t failure_loc;
|
||||
} GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
|
||||
} GTY ((desc ("%0.type"))) u;
|
||||
|
||||
/* The list of landing pads associated with this region. */
|
||||
struct eh_landing_pad_d *landing_pads;
|
||||
|
||||
/* EXC_PTR and FILTER values copied from the runtime for this region.
|
||||
Each region gets its own psuedos so that if there are nested exceptions
|
||||
we do not overwrite the values of the first exception. */
|
||||
rtx exc_ptr_reg, filter_reg;
|
||||
|
||||
/* True if this region should use __cxa_end_cleanup instead
|
||||
of _Unwind_Resume. */
|
||||
bool use_cxa_end_cleanup;
|
||||
};
|
||||
|
||||
typedef struct eh_landing_pad_d *eh_landing_pad;
|
||||
typedef struct eh_catch_d *eh_catch;
|
||||
typedef struct eh_region_d *eh_region;
|
||||
|
||||
|
||||
|
||||
|
||||
/* The exception status for each function. */
|
||||
|
||||
struct GTY(()) eh_status
|
||||
{
|
||||
/* The tree of all regions for this function. */
|
||||
eh_region region_tree;
|
||||
|
||||
/* The same information as an indexable array. */
|
||||
vec<eh_region, va_gc> *region_array;
|
||||
|
||||
/* The landing pads as an indexable array. */
|
||||
vec<eh_landing_pad, va_gc> *lp_array;
|
||||
|
||||
/* At the gimple level, a mapping from gimple statement to landing pad
|
||||
or must-not-throw region. See record_stmt_eh_region. */
|
||||
htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
|
||||
|
||||
/* All of the runtime type data used by the function. These objects
|
||||
are emitted to the lang-specific-data-area for the function. */
|
||||
vec<tree, va_gc> *ttype_data;
|
||||
|
||||
/* The table of all action chains. These encode the eh_region tree in
|
||||
a compact form for use by the runtime, and is also emitted to the
|
||||
lang-specific-data-area. Note that the ARM EABI uses a different
|
||||
format for the encoding than all other ports. */
|
||||
union eh_status_u {
|
||||
vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi;
|
||||
vec<uchar, va_gc> *GTY((tag ("0"))) other;
|
||||
} GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
|
||||
};
|
||||
|
||||
|
||||
/* Invokes CALLBACK for every exception handler label. Only used by old
|
||||
loop hackery; should not be used by new code. */
|
||||
extern void for_each_eh_label (void (*) (rtx));
|
||||
|
||||
extern void init_eh_for_function (void);
|
||||
|
||||
extern void remove_eh_landing_pad (eh_landing_pad);
|
||||
extern void remove_eh_handler (eh_region);
|
||||
extern void remove_unreachable_eh_regions (sbitmap);
|
||||
|
||||
extern bool current_function_has_exception_handlers (void);
|
||||
extern void output_function_exception_table (const char *);
|
||||
|
||||
extern rtx expand_builtin_eh_pointer (tree);
|
||||
extern rtx expand_builtin_eh_filter (tree);
|
||||
extern rtx expand_builtin_eh_copy_values (tree);
|
||||
extern void expand_builtin_unwind_init (void);
|
||||
extern rtx expand_builtin_eh_return_data_regno (tree);
|
||||
extern rtx expand_builtin_extract_return_addr (tree);
|
||||
extern void expand_builtin_init_dwarf_reg_sizes (tree);
|
||||
extern rtx expand_builtin_frob_return_addr (tree);
|
||||
extern rtx expand_builtin_dwarf_sp_column (void);
|
||||
extern void expand_builtin_eh_return (tree, tree);
|
||||
extern void expand_eh_return (void);
|
||||
extern rtx expand_builtin_extend_pointer (tree);
|
||||
extern void expand_dw2_landing_pad_for_region (eh_region);
|
||||
|
||||
typedef tree (*duplicate_eh_regions_map) (tree, void *);
|
||||
extern struct pointer_map_t *duplicate_eh_regions
|
||||
(struct function *, eh_region, int, duplicate_eh_regions_map, void *);
|
||||
|
||||
extern void sjlj_emit_function_exit_after (rtx);
|
||||
|
||||
extern eh_region gen_eh_region_cleanup (eh_region);
|
||||
extern eh_region gen_eh_region_try (eh_region);
|
||||
extern eh_region gen_eh_region_allowed (eh_region, tree);
|
||||
extern eh_region gen_eh_region_must_not_throw (eh_region);
|
||||
|
||||
extern eh_catch gen_eh_region_catch (eh_region, tree);
|
||||
extern eh_landing_pad gen_eh_landing_pad (eh_region);
|
||||
|
||||
extern eh_region get_eh_region_from_number_fn (struct function *, int);
|
||||
extern eh_region get_eh_region_from_number (int);
|
||||
extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
|
||||
extern eh_landing_pad get_eh_landing_pad_from_number (int);
|
||||
extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
|
||||
extern eh_region get_eh_region_from_lp_number (int);
|
||||
|
||||
extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
|
||||
|
||||
extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr);
|
||||
extern void make_reg_eh_region_note_nothrow_nononlocal (rtx);
|
||||
|
||||
extern void verify_eh_tree (struct function *);
|
||||
extern void dump_eh_tree (FILE *, struct function *);
|
||||
void debug_eh_tree (struct function *);
|
||||
extern void add_type_for_runtime (tree);
|
||||
extern tree lookup_type_for_runtime (tree);
|
||||
extern void assign_filter_values (void);
|
||||
|
||||
extern eh_region get_eh_region_from_rtx (const_rtx);
|
||||
extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
|
||||
|
||||
extern void finish_eh_generation (void);
|
||||
|
||||
struct GTY(()) throw_stmt_node {
|
||||
gimple stmt;
|
||||
int lp_nr;
|
||||
};
|
||||
|
||||
extern struct htab *get_eh_throw_stmt_table (struct function *);
|
||||
extern void set_eh_throw_stmt_table (struct function *, struct htab *);
|
||||
|
||||
enum eh_personality_kind {
|
||||
eh_personality_none,
|
||||
eh_personality_any,
|
||||
eh_personality_lang
|
||||
};
|
||||
|
||||
extern enum eh_personality_kind
|
||||
function_needs_eh_personality (struct function *);
|
||||
|
||||
/* Pre-order iteration within the eh_region tree. */
|
||||
|
||||
static inline eh_region
|
||||
ehr_next (eh_region r, eh_region start)
|
||||
{
|
||||
if (r->inner)
|
||||
r = r->inner;
|
||||
else if (r->next_peer && r != start)
|
||||
r = r->next_peer;
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
r = r->outer;
|
||||
if (r == start)
|
||||
return NULL;
|
||||
}
|
||||
while (r->next_peer == NULL);
|
||||
r = r->next_peer;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
#define FOR_ALL_EH_REGION_AT(R, START) \
|
||||
for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))
|
||||
|
||||
#define FOR_ALL_EH_REGION_FN(R, FN) \
|
||||
for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))
|
||||
|
||||
#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* Macros for taking apart, interpreting and processing file names.
|
||||
|
||||
These are here because some non-Posix (a.k.a. DOSish) systems have
|
||||
drive letter brain-damage at the beginning of an absolute file name,
|
||||
use forward- and back-slash in path names interchangeably, and
|
||||
some of them have case-insensitive file names.
|
||||
|
||||
Copyright 2000, 2001, 2007, 2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef FILENAMES_H
|
||||
#define FILENAMES_H
|
||||
|
||||
#include "hashtab.h" /* for hashval_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
|
||||
# ifndef HAVE_DOS_BASED_FILE_SYSTEM
|
||||
# define HAVE_DOS_BASED_FILE_SYSTEM 1
|
||||
# endif
|
||||
# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
|
||||
# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
|
||||
# endif
|
||||
# define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f)
|
||||
# define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c)
|
||||
# define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f)
|
||||
#else /* not DOSish */
|
||||
# if defined(__APPLE__)
|
||||
# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
|
||||
# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
|
||||
# endif
|
||||
# endif /* __APPLE__ */
|
||||
# define HAS_DRIVE_SPEC(f) (0)
|
||||
# define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c)
|
||||
# define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f)
|
||||
#endif
|
||||
|
||||
#define IS_DIR_SEPARATOR_1(dos_based, c) \
|
||||
(((c) == '/') \
|
||||
|| (((c) == '\\') && (dos_based)))
|
||||
|
||||
#define HAS_DRIVE_SPEC_1(dos_based, f) \
|
||||
((f)[0] && ((f)[1] == ':') && (dos_based))
|
||||
|
||||
/* Remove the drive spec from F, assuming HAS_DRIVE_SPEC (f).
|
||||
The result is a pointer to the remainder of F. */
|
||||
#define STRIP_DRIVE_SPEC(f) ((f) + 2)
|
||||
|
||||
#define IS_DOS_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (1, c)
|
||||
#define IS_DOS_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (1, f)
|
||||
#define HAS_DOS_DRIVE_SPEC(f) HAS_DRIVE_SPEC_1 (1, f)
|
||||
|
||||
#define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c)
|
||||
#define IS_UNIX_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (0, f)
|
||||
|
||||
/* Note that when DOS_BASED is true, IS_ABSOLUTE_PATH accepts d:foo as
|
||||
well, although it is only semi-absolute. This is because the users
|
||||
of IS_ABSOLUTE_PATH want to know whether to prepend the current
|
||||
working directory to a file name, which should not be done with a
|
||||
name like d:foo. */
|
||||
#define IS_ABSOLUTE_PATH_1(dos_based, f) \
|
||||
(IS_DIR_SEPARATOR_1 (dos_based, (f)[0]) \
|
||||
|| HAS_DRIVE_SPEC_1 (dos_based, f))
|
||||
|
||||
extern int filename_cmp (const char *s1, const char *s2);
|
||||
#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2)
|
||||
|
||||
extern int filename_ncmp (const char *s1, const char *s2,
|
||||
size_t n);
|
||||
|
||||
extern hashval_t filename_hash (const void *s);
|
||||
|
||||
extern int filename_eq (const void *s1, const void *s2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FILENAMES_H */
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* Fixed-point arithmetic support.
|
||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_FIXED_VALUE_H
|
||||
#define GCC_FIXED_VALUE_H
|
||||
|
||||
#include "machmode.h"
|
||||
#include "real.h"
|
||||
#include "double-int.h"
|
||||
|
||||
struct GTY(()) fixed_value
|
||||
{
|
||||
double_int data; /* Store data up to 2 wide integers. */
|
||||
enum machine_mode mode; /* Use machine mode to know IBIT and FBIT. */
|
||||
};
|
||||
|
||||
#define FIXED_VALUE_TYPE struct fixed_value
|
||||
|
||||
#define MAX_FCONST0 18 /* For storing 18 fixed-point zeros per
|
||||
fract, ufract, accum, and uaccum modes . */
|
||||
#define MAX_FCONST1 8 /* For storing 8 fixed-point ones per accum
|
||||
and uaccum modes. */
|
||||
/* Constant fixed-point values 0 and 1. */
|
||||
extern FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
|
||||
extern FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
|
||||
|
||||
/* Macros to access fconst0 and fconst1 via machine modes. */
|
||||
#define FCONST0(mode) fconst0[mode - QQmode]
|
||||
#define FCONST1(mode) fconst1[mode - HAmode]
|
||||
|
||||
/* Return a CONST_FIXED with value R and mode M. */
|
||||
#define CONST_FIXED_FROM_FIXED_VALUE(r, m) \
|
||||
const_fixed_from_fixed_value (r, m)
|
||||
extern rtx const_fixed_from_fixed_value (FIXED_VALUE_TYPE, enum machine_mode);
|
||||
|
||||
/* Construct a FIXED_VALUE from a bit payload and machine mode MODE.
|
||||
The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */
|
||||
extern FIXED_VALUE_TYPE fixed_from_double_int (double_int,
|
||||
enum machine_mode);
|
||||
|
||||
/* Return a CONST_FIXED from a bit payload and machine mode MODE.
|
||||
The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */
|
||||
static inline rtx
|
||||
const_fixed_from_double_int (double_int payload,
|
||||
enum machine_mode mode)
|
||||
{
|
||||
return
|
||||
const_fixed_from_fixed_value (fixed_from_double_int (payload, mode),
|
||||
mode);
|
||||
}
|
||||
|
||||
/* Initialize from a decimal or hexadecimal string. */
|
||||
extern void fixed_from_string (FIXED_VALUE_TYPE *, const char *,
|
||||
enum machine_mode);
|
||||
|
||||
/* In tree.c: wrap up a FIXED_VALUE_TYPE in a tree node. */
|
||||
extern tree build_fixed (tree, FIXED_VALUE_TYPE);
|
||||
|
||||
/* Extend or truncate to a new mode. */
|
||||
extern bool fixed_convert (FIXED_VALUE_TYPE *, enum machine_mode,
|
||||
const FIXED_VALUE_TYPE *, bool);
|
||||
|
||||
/* Convert to a fixed-point mode from an integer. */
|
||||
extern bool fixed_convert_from_int (FIXED_VALUE_TYPE *, enum machine_mode,
|
||||
double_int, bool, bool);
|
||||
|
||||
/* Convert to a fixed-point mode from a real. */
|
||||
extern bool fixed_convert_from_real (FIXED_VALUE_TYPE *, enum machine_mode,
|
||||
const REAL_VALUE_TYPE *, bool);
|
||||
|
||||
/* Convert to a real mode from a fixed-point. */
|
||||
extern void real_convert_from_fixed (REAL_VALUE_TYPE *, enum machine_mode,
|
||||
const FIXED_VALUE_TYPE *);
|
||||
|
||||
/* Compare two fixed-point objects for bitwise identity. */
|
||||
extern bool fixed_identical (const FIXED_VALUE_TYPE *, const FIXED_VALUE_TYPE *);
|
||||
|
||||
/* Calculate a hash value. */
|
||||
extern unsigned int fixed_hash (const FIXED_VALUE_TYPE *);
|
||||
|
||||
#define FIXED_VALUES_IDENTICAL(x, y) fixed_identical (&(x), &(y))
|
||||
|
||||
/* Determine whether a fixed-point value X is negative. */
|
||||
#define FIXED_VALUE_NEGATIVE(x) fixed_isneg (&(x))
|
||||
|
||||
/* Render F as a decimal floating point constant. */
|
||||
extern void fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *, size_t);
|
||||
|
||||
/* Binary or unary arithmetic on tree_code. */
|
||||
extern bool fixed_arithmetic (FIXED_VALUE_TYPE *, int, const FIXED_VALUE_TYPE *,
|
||||
const FIXED_VALUE_TYPE *, bool);
|
||||
|
||||
/* Compare fixed-point values by tree_code. */
|
||||
extern bool fixed_compare (int, const FIXED_VALUE_TYPE *,
|
||||
const FIXED_VALUE_TYPE *);
|
||||
|
||||
/* Determine whether a fixed-point value X is negative. */
|
||||
extern bool fixed_isneg (const FIXED_VALUE_TYPE *);
|
||||
|
||||
#endif /* GCC_FIXED_VALUE_H */
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/* Compilation switch flag type definitions for GCC.
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_FLAG_TYPES_H
|
||||
#define GCC_FLAG_TYPES_H
|
||||
|
||||
enum debug_info_type
|
||||
{
|
||||
NO_DEBUG, /* Write no debug info. */
|
||||
DBX_DEBUG, /* Write BSD .stabs for DBX (using dbxout.c). */
|
||||
SDB_DEBUG, /* Write COFF for (old) SDB (using sdbout.c). */
|
||||
DWARF2_DEBUG, /* Write Dwarf v2 debug info (using dwarf2out.c). */
|
||||
XCOFF_DEBUG, /* Write IBM/Xcoff debug info (using dbxout.c). */
|
||||
VMS_DEBUG, /* Write VMS debug info (using vmsdbgout.c). */
|
||||
VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c).
|
||||
and DWARF v2 debug info (using dwarf2out.c). */
|
||||
};
|
||||
|
||||
enum debug_info_levels
|
||||
{
|
||||
DINFO_LEVEL_NONE, /* Write no debugging info. */
|
||||
DINFO_LEVEL_TERSE, /* Write minimal info to support tracebacks only. */
|
||||
DINFO_LEVEL_NORMAL, /* Write info for all declarations (and line table). */
|
||||
DINFO_LEVEL_VERBOSE /* Write normal info plus #define/#undef info. */
|
||||
};
|
||||
|
||||
/* A major contribution to object and executable size is debug
|
||||
information size. A major contribution to debug information
|
||||
size is struct descriptions replicated in several object files.
|
||||
The following function determines whether or not debug information
|
||||
should be generated for a given struct. The indirect parameter
|
||||
indicates that the struct is being handled indirectly, via
|
||||
a pointer. See opts.c for the implementation. */
|
||||
|
||||
enum debug_info_usage
|
||||
{
|
||||
DINFO_USAGE_DFN, /* A struct definition. */
|
||||
DINFO_USAGE_DIR_USE, /* A direct use, such as the type of a variable. */
|
||||
DINFO_USAGE_IND_USE, /* An indirect use, such as through a pointer. */
|
||||
DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
|
||||
};
|
||||
|
||||
/* A major contribution to object and executable size is debug
|
||||
information size. A major contribution to debug information size
|
||||
is struct descriptions replicated in several object files. The
|
||||
following flags attempt to reduce this information. The basic
|
||||
idea is to not emit struct debugging information in the current
|
||||
compilation unit when that information will be generated by
|
||||
another compilation unit.
|
||||
|
||||
Debug information for a struct defined in the current source
|
||||
file should be generated in the object file. Likewise the
|
||||
debug information for a struct defined in a header should be
|
||||
generated in the object file of the corresponding source file.
|
||||
Both of these case are handled when the base name of the file of
|
||||
the struct definition matches the base name of the source file
|
||||
of the current compilation unit. This matching emits minimal
|
||||
struct debugging information.
|
||||
|
||||
The base file name matching rule above will fail to emit debug
|
||||
information for structs defined in system headers. So a second
|
||||
category of files includes system headers in addition to files
|
||||
with matching bases.
|
||||
|
||||
The remaining types of files are library headers and application
|
||||
headers. We cannot currently distinguish these two types. */
|
||||
|
||||
enum debug_struct_file
|
||||
{
|
||||
DINFO_STRUCT_FILE_NONE, /* Debug no structs. */
|
||||
DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the
|
||||
same base name as the compilation unit. */
|
||||
DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system
|
||||
header files. */
|
||||
DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */
|
||||
};
|
||||
|
||||
/* Enumerate visibility settings. This is deliberately ordered from most
|
||||
to least visibility. */
|
||||
#ifndef SYMBOL_VISIBILITY_DEFINED
|
||||
#define SYMBOL_VISIBILITY_DEFINED
|
||||
enum symbol_visibility
|
||||
{
|
||||
VISIBILITY_DEFAULT,
|
||||
VISIBILITY_PROTECTED,
|
||||
VISIBILITY_HIDDEN,
|
||||
VISIBILITY_INTERNAL
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The stack reuse level. */
|
||||
enum stack_reuse_level
|
||||
{
|
||||
SR_NONE,
|
||||
SR_NAMED_VARS,
|
||||
SR_ALL
|
||||
};
|
||||
|
||||
/* The algorithm used for the integrated register allocator (IRA). */
|
||||
enum ira_algorithm
|
||||
{
|
||||
IRA_ALGORITHM_CB,
|
||||
IRA_ALGORITHM_PRIORITY
|
||||
};
|
||||
|
||||
/* The regions used for the integrated register allocator (IRA). */
|
||||
enum ira_region
|
||||
{
|
||||
IRA_REGION_ONE,
|
||||
IRA_REGION_ALL,
|
||||
IRA_REGION_MIXED,
|
||||
/* This value means that there were no options -fira-region on the
|
||||
command line and that we should choose a value depending on the
|
||||
used -O option. */
|
||||
IRA_REGION_AUTODETECT
|
||||
};
|
||||
|
||||
/* The options for excess precision. */
|
||||
enum excess_precision
|
||||
{
|
||||
EXCESS_PRECISION_DEFAULT,
|
||||
EXCESS_PRECISION_FAST,
|
||||
EXCESS_PRECISION_STANDARD
|
||||
};
|
||||
|
||||
/* Type of stack check. */
|
||||
enum stack_check_type
|
||||
{
|
||||
/* Do not check the stack. */
|
||||
NO_STACK_CHECK = 0,
|
||||
|
||||
/* Check the stack generically, i.e. assume no specific support
|
||||
from the target configuration files. */
|
||||
GENERIC_STACK_CHECK,
|
||||
|
||||
/* Check the stack and rely on the target configuration files to
|
||||
check the static frame of functions, i.e. use the generic
|
||||
mechanism only for dynamic stack allocations. */
|
||||
STATIC_BUILTIN_STACK_CHECK,
|
||||
|
||||
/* Check the stack and entirely rely on the target configuration
|
||||
files, i.e. do not use the generic mechanism at all. */
|
||||
FULL_BUILTIN_STACK_CHECK
|
||||
};
|
||||
|
||||
/* Names for the different levels of -Wstrict-overflow=N. The numeric
|
||||
values here correspond to N. */
|
||||
|
||||
enum warn_strict_overflow_code
|
||||
{
|
||||
/* Overflow warning that should be issued with -Wall: a questionable
|
||||
construct that is easy to avoid even when using macros. Example:
|
||||
folding (x + CONSTANT > x) to 1. */
|
||||
WARN_STRICT_OVERFLOW_ALL = 1,
|
||||
/* Overflow warning about folding a comparison to a constant because
|
||||
of undefined signed overflow, other than cases covered by
|
||||
WARN_STRICT_OVERFLOW_ALL. Example: folding (abs (x) >= 0) to 1
|
||||
(this is false when x == INT_MIN). */
|
||||
WARN_STRICT_OVERFLOW_CONDITIONAL = 2,
|
||||
/* Overflow warning about changes to comparisons other than folding
|
||||
them to a constant. Example: folding (x + 1 > 1) to (x > 0). */
|
||||
WARN_STRICT_OVERFLOW_COMPARISON = 3,
|
||||
/* Overflow warnings not covered by the above cases. Example:
|
||||
folding ((x * 10) / 5) to (x * 2). */
|
||||
WARN_STRICT_OVERFLOW_MISC = 4,
|
||||
/* Overflow warnings about reducing magnitude of constants in
|
||||
comparison. Example: folding (x + 2 > y) to (x + 1 >= y). */
|
||||
WARN_STRICT_OVERFLOW_MAGNITUDE = 5
|
||||
};
|
||||
|
||||
/* Floating-point contraction mode. */
|
||||
enum fp_contract_mode {
|
||||
FP_CONTRACT_OFF = 0,
|
||||
FP_CONTRACT_ON = 1,
|
||||
FP_CONTRACT_FAST = 2
|
||||
};
|
||||
|
||||
#endif /* ! GCC_FLAG_TYPES_H */
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/* Compilation switch flag definitions for GCC.
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_FLAGS_H
|
||||
#define GCC_FLAGS_H
|
||||
|
||||
#include "flag-types.h"
|
||||
#include "options.h"
|
||||
|
||||
#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
|
||||
|
||||
/* Names of debug_info_type, for error messages. */
|
||||
extern const char *const debug_type_names[];
|
||||
|
||||
extern void strip_off_ending (char *, int);
|
||||
extern int base_of_path (const char *path, const char **base_out);
|
||||
|
||||
/* Return true iff flags are set as if -ffast-math. */
|
||||
extern bool fast_math_flags_set_p (const struct gcc_options *);
|
||||
extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
|
||||
|
||||
|
||||
/* Now the symbols that are set with `-f' switches. */
|
||||
|
||||
/* True if printing into -fdump-final-insns= dump. */
|
||||
|
||||
extern bool final_insns_dump_p;
|
||||
|
||||
|
||||
/* Other basic status info about current function. */
|
||||
|
||||
/* Target-dependent global state. */
|
||||
struct target_flag_state {
|
||||
/* Values of the -falign-* flags: how much to align labels in code.
|
||||
0 means `use default', 1 means `don't align'.
|
||||
For each variable, there is an _log variant which is the power
|
||||
of two not less than the variable, for .align output. */
|
||||
int x_align_loops_log;
|
||||
int x_align_loops_max_skip;
|
||||
int x_align_jumps_log;
|
||||
int x_align_jumps_max_skip;
|
||||
int x_align_labels_log;
|
||||
int x_align_labels_max_skip;
|
||||
int x_align_functions_log;
|
||||
|
||||
/* The excess precision currently in effect. */
|
||||
enum excess_precision x_flag_excess_precision;
|
||||
};
|
||||
|
||||
extern struct target_flag_state default_target_flag_state;
|
||||
#if SWITCHABLE_TARGET
|
||||
extern struct target_flag_state *this_target_flag_state;
|
||||
#else
|
||||
#define this_target_flag_state (&default_target_flag_state)
|
||||
#endif
|
||||
|
||||
#define align_loops_log \
|
||||
(this_target_flag_state->x_align_loops_log)
|
||||
#define align_loops_max_skip \
|
||||
(this_target_flag_state->x_align_loops_max_skip)
|
||||
#define align_jumps_log \
|
||||
(this_target_flag_state->x_align_jumps_log)
|
||||
#define align_jumps_max_skip \
|
||||
(this_target_flag_state->x_align_jumps_max_skip)
|
||||
#define align_labels_log \
|
||||
(this_target_flag_state->x_align_labels_log)
|
||||
#define align_labels_max_skip \
|
||||
(this_target_flag_state->x_align_labels_max_skip)
|
||||
#define align_functions_log \
|
||||
(this_target_flag_state->x_align_functions_log)
|
||||
#define flag_excess_precision \
|
||||
(this_target_flag_state->x_flag_excess_precision)
|
||||
|
||||
/* Returns TRUE if generated code should match ABI version N or
|
||||
greater is in use. */
|
||||
|
||||
#define abi_version_at_least(N) \
|
||||
(flag_abi_version == 0 || flag_abi_version >= (N))
|
||||
|
||||
/* Whether to emit an overflow warning whose code is C. */
|
||||
#define issue_strict_overflow_warning(c) (warn_strict_overflow >= (int) (c))
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ! GCC_FLAGS_H */
|
||||
|
|
@ -0,0 +1,782 @@
|
|||
/* Structure for saving state for a nested function.
|
||||
Copyright (C) 1989-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_FUNCTION_H
|
||||
#define GCC_FUNCTION_H
|
||||
|
||||
#include "hashtab.h"
|
||||
#include "vec.h"
|
||||
#include "machmode.h"
|
||||
#include "tm.h" /* For CUMULATIVE_ARGS. */
|
||||
#include "hard-reg-set.h" /* For HARD_REG_SET in struct rtl_data. */
|
||||
#include "input.h" /* For location_t. */
|
||||
|
||||
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
|
||||
Each element describes one pending sequence.
|
||||
The main insn-chain is saved in the last element of the chain,
|
||||
unless the chain is empty. */
|
||||
|
||||
struct GTY(()) sequence_stack {
|
||||
/* First and last insns in the chain of the saved sequence. */
|
||||
rtx first;
|
||||
rtx last;
|
||||
struct sequence_stack *next;
|
||||
};
|
||||
|
||||
struct GTY(()) emit_status {
|
||||
/* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
|
||||
After rtl generation, it is 1 plus the largest register number used. */
|
||||
int x_reg_rtx_no;
|
||||
|
||||
/* Lowest label number in current function. */
|
||||
int x_first_label_num;
|
||||
|
||||
/* The ends of the doubly-linked chain of rtl for the current function.
|
||||
Both are reset to null at the start of rtl generation for the function.
|
||||
|
||||
start_sequence saves both of these on `sequence_stack' and then starts
|
||||
a new, nested sequence of insns. */
|
||||
rtx x_first_insn;
|
||||
rtx x_last_insn;
|
||||
|
||||
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
|
||||
Each element describes one pending sequence.
|
||||
The main insn-chain is saved in the last element of the chain,
|
||||
unless the chain is empty. */
|
||||
struct sequence_stack *sequence_stack;
|
||||
|
||||
/* INSN_UID for next insn emitted.
|
||||
Reset to 1 for each function compiled. */
|
||||
int x_cur_insn_uid;
|
||||
|
||||
/* INSN_UID for next debug insn emitted. Only used if
|
||||
--param min-nondebug-insn-uid=<value> is given with nonzero value. */
|
||||
int x_cur_debug_insn_uid;
|
||||
|
||||
/* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
|
||||
vectors. Since these vectors are needed during the expansion phase when
|
||||
the total number of registers in the function is not yet known, the
|
||||
vectors are copied and made bigger when necessary. */
|
||||
int regno_pointer_align_length;
|
||||
|
||||
/* Indexed by pseudo register number, if nonzero gives the known alignment
|
||||
for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
|
||||
Allocated in parallel with x_regno_reg_rtx. */
|
||||
unsigned char * GTY((skip)) regno_pointer_align;
|
||||
};
|
||||
|
||||
|
||||
/* Indexed by register number, gives an rtx for that register (and only
|
||||
that register). For pseudo registers, it is the unique rtx for
|
||||
that pseudo. For hard registers, it is an rtx of the mode specified
|
||||
by reg_raw_mode.
|
||||
|
||||
FIXME: We could put it into emit_status struct, but gengtype is not
|
||||
able to deal with length attribute nested in top level structures. */
|
||||
|
||||
extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx;
|
||||
|
||||
/* For backward compatibility... eventually these should all go away. */
|
||||
#define reg_rtx_no (crtl->emit.x_reg_rtx_no)
|
||||
#define seq_stack (crtl->emit.sequence_stack)
|
||||
|
||||
#define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
|
||||
|
||||
struct GTY(()) expr_status {
|
||||
/* Number of units that we should eventually pop off the stack.
|
||||
These are the arguments to function calls that have already returned. */
|
||||
int x_pending_stack_adjust;
|
||||
|
||||
/* Under some ABIs, it is the caller's responsibility to pop arguments
|
||||
pushed for function calls. A naive implementation would simply pop
|
||||
the arguments immediately after each call. However, if several
|
||||
function calls are made in a row, it is typically cheaper to pop
|
||||
all the arguments after all of the calls are complete since a
|
||||
single pop instruction can be used. Therefore, GCC attempts to
|
||||
defer popping the arguments until absolutely necessary. (For
|
||||
example, at the end of a conditional, the arguments must be popped,
|
||||
since code outside the conditional won't know whether or not the
|
||||
arguments need to be popped.)
|
||||
|
||||
When INHIBIT_DEFER_POP is nonzero, however, the compiler does not
|
||||
attempt to defer pops. Instead, the stack is popped immediately
|
||||
after each call. Rather then setting this variable directly, use
|
||||
NO_DEFER_POP and OK_DEFER_POP. */
|
||||
int x_inhibit_defer_pop;
|
||||
|
||||
/* If PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING are defined, the stack
|
||||
boundary can be momentarily unaligned while pushing the arguments.
|
||||
Record the delta since last aligned boundary here in order to get
|
||||
stack alignment in the nested function calls working right. */
|
||||
int x_stack_pointer_delta;
|
||||
|
||||
/* Nonzero means __builtin_saveregs has already been done in this function.
|
||||
The value is the pseudoreg containing the value __builtin_saveregs
|
||||
returned. */
|
||||
rtx x_saveregs_value;
|
||||
|
||||
/* Similarly for __builtin_apply_args. */
|
||||
rtx x_apply_args_value;
|
||||
|
||||
/* List of labels that must never be deleted. */
|
||||
rtx x_forced_labels;
|
||||
};
|
||||
|
||||
typedef struct call_site_record_d *call_site_record;
|
||||
|
||||
/* RTL representation of exception handling. */
|
||||
struct GTY(()) rtl_eh {
|
||||
rtx ehr_stackadj;
|
||||
rtx ehr_handler;
|
||||
rtx ehr_label;
|
||||
|
||||
rtx sjlj_fc;
|
||||
rtx sjlj_exit_after;
|
||||
|
||||
vec<uchar, va_gc> *action_record_data;
|
||||
|
||||
vec<call_site_record, va_gc> *call_site_record_v[2];
|
||||
};
|
||||
|
||||
#define pending_stack_adjust (crtl->expr.x_pending_stack_adjust)
|
||||
#define inhibit_defer_pop (crtl->expr.x_inhibit_defer_pop)
|
||||
#define saveregs_value (crtl->expr.x_saveregs_value)
|
||||
#define apply_args_value (crtl->expr.x_apply_args_value)
|
||||
#define forced_labels (crtl->expr.x_forced_labels)
|
||||
#define stack_pointer_delta (crtl->expr.x_stack_pointer_delta)
|
||||
|
||||
struct gimple_df;
|
||||
struct temp_slot;
|
||||
typedef struct temp_slot *temp_slot_p;
|
||||
struct call_site_record_d;
|
||||
struct dw_fde_struct;
|
||||
|
||||
struct ipa_opt_pass_d;
|
||||
typedef struct ipa_opt_pass_d *ipa_opt_pass;
|
||||
|
||||
|
||||
struct GTY(()) varasm_status {
|
||||
/* If we're using a per-function constant pool, this is it. */
|
||||
struct rtx_constant_pool *pool;
|
||||
|
||||
/* Number of tree-constants deferred during the expansion of this
|
||||
function. */
|
||||
unsigned int deferred_constants;
|
||||
};
|
||||
|
||||
/* Information mainlined about RTL representation of incoming arguments. */
|
||||
struct GTY(()) incoming_args {
|
||||
/* Number of bytes of args popped by function being compiled on its return.
|
||||
Zero if no bytes are to be popped.
|
||||
May affect compilation of return insn or of function epilogue. */
|
||||
int pops_args;
|
||||
|
||||
/* If function's args have a fixed size, this is that size, in bytes.
|
||||
Otherwise, it is -1.
|
||||
May affect compilation of return insn or of function epilogue. */
|
||||
int size;
|
||||
|
||||
/* # bytes the prologue should push and pretend that the caller pushed them.
|
||||
The prologue must do this, but only if parms can be passed in
|
||||
registers. */
|
||||
int pretend_args_size;
|
||||
|
||||
/* This is the offset from the arg pointer to the place where the first
|
||||
anonymous arg can be found, if there is one. */
|
||||
rtx arg_offset_rtx;
|
||||
|
||||
/* Quantities of various kinds of registers
|
||||
used for the current function's args. */
|
||||
CUMULATIVE_ARGS info;
|
||||
|
||||
/* The arg pointer hard register, or the pseudo into which it was copied. */
|
||||
rtx internal_arg_pointer;
|
||||
};
|
||||
|
||||
/* Data for function partitioning. */
|
||||
struct GTY(()) function_subsections {
|
||||
/* Assembly labels for the hot and cold text sections, to
|
||||
be used by debugger functions for determining the size of text
|
||||
sections. */
|
||||
|
||||
const char *hot_section_label;
|
||||
const char *cold_section_label;
|
||||
const char *hot_section_end_label;
|
||||
const char *cold_section_end_label;
|
||||
};
|
||||
|
||||
/* Describe an empty area of space in the stack frame. These can be chained
|
||||
into a list; this is used to keep track of space wasted for alignment
|
||||
reasons. */
|
||||
struct GTY(()) frame_space
|
||||
{
|
||||
struct frame_space *next;
|
||||
|
||||
HOST_WIDE_INT start;
|
||||
HOST_WIDE_INT length;
|
||||
};
|
||||
|
||||
/* Datastructures maintained for currently processed function in RTL form. */
|
||||
struct GTY(()) rtl_data {
|
||||
struct expr_status expr;
|
||||
struct emit_status emit;
|
||||
struct varasm_status varasm;
|
||||
struct incoming_args args;
|
||||
struct function_subsections subsections;
|
||||
struct rtl_eh eh;
|
||||
|
||||
/* For function.c */
|
||||
|
||||
/* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is
|
||||
defined, the needed space is pushed by the prologue. */
|
||||
int outgoing_args_size;
|
||||
|
||||
/* If nonzero, an RTL expression for the location at which the current
|
||||
function returns its result. If the current function returns its
|
||||
result in a register, current_function_return_rtx will always be
|
||||
the hard register containing the result. */
|
||||
rtx return_rtx;
|
||||
|
||||
/* Vector of initial-value pairs. Each pair consists of a pseudo
|
||||
register of approprite mode that stores the initial value a hard
|
||||
register REGNO, and that hard register itself. */
|
||||
/* ??? This could be a VEC but there is currently no way to define an
|
||||
opaque VEC type. */
|
||||
struct initial_value_struct *hard_reg_initial_vals;
|
||||
|
||||
/* A variable living at the top of the frame that holds a known value.
|
||||
Used for detecting stack clobbers. */
|
||||
tree stack_protect_guard;
|
||||
|
||||
/* List (chain of EXPR_LIST) of labels heading the current handlers for
|
||||
nonlocal gotos. */
|
||||
rtx x_nonlocal_goto_handler_labels;
|
||||
|
||||
/* Label that will go on function epilogue.
|
||||
Jumping to this label serves as a "return" instruction
|
||||
on machines which require execution of the epilogue on all returns. */
|
||||
rtx x_return_label;
|
||||
|
||||
/* Label that will go on the end of function epilogue.
|
||||
Jumping to this label serves as a "naked return" instruction
|
||||
on machines which require execution of the epilogue on all returns. */
|
||||
rtx x_naked_return_label;
|
||||
|
||||
/* List (chain of EXPR_LISTs) of all stack slots in this function.
|
||||
Made for the sake of unshare_all_rtl. */
|
||||
rtx x_stack_slot_list;
|
||||
|
||||
/* List of empty areas in the stack frame. */
|
||||
struct frame_space *frame_space_list;
|
||||
|
||||
/* Place after which to insert the tail_recursion_label if we need one. */
|
||||
rtx x_stack_check_probe_note;
|
||||
|
||||
/* Location at which to save the argument pointer if it will need to be
|
||||
referenced. There are two cases where this is done: if nonlocal gotos
|
||||
exist, or if vars stored at an offset from the argument pointer will be
|
||||
needed by inner routines. */
|
||||
rtx x_arg_pointer_save_area;
|
||||
|
||||
/* Dynamic Realign Argument Pointer used for realigning stack. */
|
||||
rtx drap_reg;
|
||||
|
||||
/* Offset to end of allocated area of stack frame.
|
||||
If stack grows down, this is the address of the last stack slot allocated.
|
||||
If stack grows up, this is the address for the next slot. */
|
||||
HOST_WIDE_INT x_frame_offset;
|
||||
|
||||
/* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
|
||||
rtx x_parm_birth_insn;
|
||||
|
||||
/* List of all used temporaries allocated, by level. */
|
||||
vec<temp_slot_p, va_gc> *x_used_temp_slots;
|
||||
|
||||
/* List of available temp slots. */
|
||||
struct temp_slot *x_avail_temp_slots;
|
||||
|
||||
/* Current nesting level for temporaries. */
|
||||
int x_temp_slot_level;
|
||||
|
||||
/* The largest alignment needed on the stack, including requirement
|
||||
for outgoing stack alignment. */
|
||||
unsigned int stack_alignment_needed;
|
||||
|
||||
/* Preferred alignment of the end of stack frame, which is preferred
|
||||
to call other functions. */
|
||||
unsigned int preferred_stack_boundary;
|
||||
|
||||
/* The minimum alignment of parameter stack. */
|
||||
unsigned int parm_stack_boundary;
|
||||
|
||||
/* The largest alignment of slot allocated on the stack. */
|
||||
unsigned int max_used_stack_slot_alignment;
|
||||
|
||||
/* The stack alignment estimated before reload, with consideration of
|
||||
following factors:
|
||||
1. Alignment of local stack variables (max_used_stack_slot_alignment)
|
||||
2. Alignment requirement to call other functions
|
||||
(preferred_stack_boundary)
|
||||
3. Alignment of non-local stack variables but might be spilled in
|
||||
local stack. */
|
||||
unsigned int stack_alignment_estimated;
|
||||
|
||||
/* For reorg. */
|
||||
|
||||
/* Nonzero if function being compiled called builtin_return_addr or
|
||||
builtin_frame_address with nonzero count. */
|
||||
bool accesses_prior_frames;
|
||||
|
||||
/* Nonzero if the function calls __builtin_eh_return. */
|
||||
bool calls_eh_return;
|
||||
|
||||
/* Nonzero if function saves all registers, e.g. if it has a nonlocal
|
||||
label that can reach the exit block via non-exceptional paths. */
|
||||
bool saves_all_registers;
|
||||
|
||||
/* Nonzero if function being compiled has nonlocal gotos to parent
|
||||
function. */
|
||||
bool has_nonlocal_goto;
|
||||
|
||||
/* Nonzero if function being compiled has an asm statement. */
|
||||
bool has_asm_statement;
|
||||
|
||||
/* This bit is used by the exception handling logic. It is set if all
|
||||
calls (if any) are sibling calls. Such functions do not have to
|
||||
have EH tables generated, as they cannot throw. A call to such a
|
||||
function, however, should be treated as throwing if any of its callees
|
||||
can throw. */
|
||||
bool all_throwers_are_sibcalls;
|
||||
|
||||
/* Nonzero if stack limit checking should be enabled in the current
|
||||
function. */
|
||||
bool limit_stack;
|
||||
|
||||
/* Nonzero if profiling code should be generated. */
|
||||
bool profile;
|
||||
|
||||
/* Nonzero if the current function uses the constant pool. */
|
||||
bool uses_const_pool;
|
||||
|
||||
/* Nonzero if the current function uses pic_offset_table_rtx. */
|
||||
bool uses_pic_offset_table;
|
||||
|
||||
/* Nonzero if the current function needs an lsda for exception handling. */
|
||||
bool uses_eh_lsda;
|
||||
|
||||
/* Set when the tail call has been produced. */
|
||||
bool tail_call_emit;
|
||||
|
||||
/* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
|
||||
bool arg_pointer_save_area_init;
|
||||
|
||||
/* Nonzero if current function must be given a frame pointer.
|
||||
Set in reload1.c or lra-eliminations.c if anything is allocated
|
||||
on the stack there. */
|
||||
bool frame_pointer_needed;
|
||||
|
||||
/* When set, expand should optimize for speed. */
|
||||
bool maybe_hot_insn_p;
|
||||
|
||||
/* Nonzero if function stack realignment is needed. This flag may be
|
||||
set twice: before and after reload. It is set before reload wrt
|
||||
stack alignment estimation before reload. It will be changed after
|
||||
reload if by then criteria of stack realignment is different.
|
||||
The value set after reload is the accurate one and is finalized. */
|
||||
bool stack_realign_needed;
|
||||
|
||||
/* Nonzero if function stack realignment is tried. This flag is set
|
||||
only once before reload. It affects register elimination. This
|
||||
is used to generate DWARF debug info for stack variables. */
|
||||
bool stack_realign_tried;
|
||||
|
||||
/* Nonzero if function being compiled needs dynamic realigned
|
||||
argument pointer (drap) if stack needs realigning. */
|
||||
bool need_drap;
|
||||
|
||||
/* Nonzero if function stack realignment estimation is done, namely
|
||||
stack_realign_needed flag has been set before reload wrt estimated
|
||||
stack alignment info. */
|
||||
bool stack_realign_processed;
|
||||
|
||||
/* Nonzero if function stack realignment has been finalized, namely
|
||||
stack_realign_needed flag has been set and finalized after reload. */
|
||||
bool stack_realign_finalized;
|
||||
|
||||
/* True if dbr_schedule has already been called for this function. */
|
||||
bool dbr_scheduled_p;
|
||||
|
||||
/* True if current function can not throw. Unlike
|
||||
TREE_NOTHROW (current_function_decl) it is set even for overwritable
|
||||
function where currently compiled version of it is nothrow. */
|
||||
bool nothrow;
|
||||
|
||||
/* True if we performed shrink-wrapping for the current function. */
|
||||
bool shrink_wrapped;
|
||||
|
||||
/* Nonzero if function being compiled doesn't modify the stack pointer
|
||||
(ignoring the prologue and epilogue). This is only valid after
|
||||
pass_stack_ptr_mod has run. */
|
||||
bool sp_is_unchanging;
|
||||
|
||||
/* Nonzero if function being compiled doesn't contain any calls
|
||||
(ignoring the prologue and epilogue). This is set prior to
|
||||
local register allocation and is valid for the remaining
|
||||
compiler passes. */
|
||||
bool is_leaf;
|
||||
|
||||
/* Nonzero if the function being compiled is a leaf function which only
|
||||
uses leaf registers. This is valid after reload (specifically after
|
||||
sched2) and is useful only if the port defines LEAF_REGISTERS. */
|
||||
bool uses_only_leaf_regs;
|
||||
|
||||
/* Like regs_ever_live, but 1 if a reg is set or clobbered from an
|
||||
asm. Unlike regs_ever_live, elements of this array corresponding
|
||||
to eliminable regs (like the frame pointer) are set if an asm
|
||||
sets them. */
|
||||
HARD_REG_SET asm_clobbers;
|
||||
};
|
||||
|
||||
#define return_label (crtl->x_return_label)
|
||||
#define naked_return_label (crtl->x_naked_return_label)
|
||||
#define stack_slot_list (crtl->x_stack_slot_list)
|
||||
#define parm_birth_insn (crtl->x_parm_birth_insn)
|
||||
#define frame_offset (crtl->x_frame_offset)
|
||||
#define stack_check_probe_note (crtl->x_stack_check_probe_note)
|
||||
#define arg_pointer_save_area (crtl->x_arg_pointer_save_area)
|
||||
#define used_temp_slots (crtl->x_used_temp_slots)
|
||||
#define avail_temp_slots (crtl->x_avail_temp_slots)
|
||||
#define temp_slot_level (crtl->x_temp_slot_level)
|
||||
#define nonlocal_goto_handler_labels (crtl->x_nonlocal_goto_handler_labels)
|
||||
#define frame_pointer_needed (crtl->frame_pointer_needed)
|
||||
#define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap)
|
||||
#define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap)
|
||||
|
||||
extern GTY(()) struct rtl_data x_rtl;
|
||||
|
||||
/* Accessor to RTL datastructures. We keep them statically allocated now since
|
||||
we never keep multiple functions. For threaded compiler we might however
|
||||
want to do differently. */
|
||||
#define crtl (&x_rtl)
|
||||
|
||||
struct GTY(()) stack_usage
|
||||
{
|
||||
/* # of bytes of static stack space allocated by the function. */
|
||||
HOST_WIDE_INT static_stack_size;
|
||||
|
||||
/* # of bytes of dynamic stack space allocated by the function. This is
|
||||
meaningful only if has_unbounded_dynamic_stack_size is zero. */
|
||||
HOST_WIDE_INT dynamic_stack_size;
|
||||
|
||||
/* # of bytes of space pushed onto the stack after the prologue. If
|
||||
!ACCUMULATE_OUTGOING_ARGS, it contains the outgoing arguments. */
|
||||
int pushed_stack_size;
|
||||
|
||||
/* Nonzero if the amount of stack space allocated dynamically cannot
|
||||
be bounded at compile-time. */
|
||||
unsigned int has_unbounded_dynamic_stack_size : 1;
|
||||
};
|
||||
|
||||
#define current_function_static_stack_size (cfun->su->static_stack_size)
|
||||
#define current_function_dynamic_stack_size (cfun->su->dynamic_stack_size)
|
||||
#define current_function_pushed_stack_size (cfun->su->pushed_stack_size)
|
||||
#define current_function_has_unbounded_dynamic_stack_size \
|
||||
(cfun->su->has_unbounded_dynamic_stack_size)
|
||||
#define current_function_allocates_dynamic_stack_space \
|
||||
(current_function_dynamic_stack_size != 0 \
|
||||
|| current_function_has_unbounded_dynamic_stack_size)
|
||||
|
||||
/* This structure can save all the important global and static variables
|
||||
describing the status of the current function. */
|
||||
|
||||
struct GTY(()) function {
|
||||
struct eh_status *eh;
|
||||
|
||||
/* The control flow graph for this function. */
|
||||
struct control_flow_graph *cfg;
|
||||
|
||||
/* GIMPLE body for this function. */
|
||||
gimple_seq gimple_body;
|
||||
|
||||
/* SSA and dataflow information. */
|
||||
struct gimple_df *gimple_df;
|
||||
|
||||
/* The loops in this function. */
|
||||
struct loops *x_current_loops;
|
||||
|
||||
/* The stack usage of this function. */
|
||||
struct stack_usage *su;
|
||||
|
||||
/* Value histograms attached to particular statements. */
|
||||
htab_t GTY((skip)) value_histograms;
|
||||
|
||||
/* For function.c. */
|
||||
|
||||
/* Points to the FUNCTION_DECL of this function. */
|
||||
tree decl;
|
||||
|
||||
/* A PARM_DECL that should contain the static chain for this function.
|
||||
It will be initialized at the beginning of the function. */
|
||||
tree static_chain_decl;
|
||||
|
||||
/* An expression that contains the non-local goto save area. The first
|
||||
word is the saved frame pointer and the second is the saved stack
|
||||
pointer. */
|
||||
tree nonlocal_goto_save_area;
|
||||
|
||||
/* Vector of function local variables, functions, types and constants. */
|
||||
vec<tree, va_gc> *local_decls;
|
||||
|
||||
/* For md files. */
|
||||
|
||||
/* tm.h can use this to store whatever it likes. */
|
||||
struct machine_function * GTY ((maybe_undef)) machine;
|
||||
|
||||
/* Language-specific code can use this to store whatever it likes. */
|
||||
struct language_function * language;
|
||||
|
||||
/* Used types hash table. */
|
||||
htab_t GTY ((param_is (union tree_node))) used_types_hash;
|
||||
|
||||
/* Dwarf2 Frame Description Entry, containing the Call Frame Instructions
|
||||
used for unwinding. Only set when either dwarf2 unwinding or dwarf2
|
||||
debugging is enabled. */
|
||||
struct dw_fde_struct *fde;
|
||||
|
||||
/* Last statement uid. */
|
||||
int last_stmt_uid;
|
||||
|
||||
/* Function sequence number for profiling, debugging, etc. */
|
||||
int funcdef_no;
|
||||
|
||||
/* Line number of the start of the function for debugging purposes. */
|
||||
location_t function_start_locus;
|
||||
|
||||
/* Line number of the end of the function. */
|
||||
location_t function_end_locus;
|
||||
|
||||
/* Properties used by the pass manager. */
|
||||
unsigned int curr_properties;
|
||||
unsigned int last_verified;
|
||||
|
||||
/* Non-null if the function does something that would prevent it from
|
||||
being copied; this applies to both versioning and inlining. Set to
|
||||
a string describing the reason for failure. */
|
||||
const char * GTY((skip)) cannot_be_copied_reason;
|
||||
|
||||
/* Collected bit flags. */
|
||||
|
||||
/* Number of units of general registers that need saving in stdarg
|
||||
function. What unit is depends on the backend, either it is number
|
||||
of bytes, or it can be number of registers. */
|
||||
unsigned int va_list_gpr_size : 8;
|
||||
|
||||
/* Number of units of floating point registers that need saving in stdarg
|
||||
function. */
|
||||
unsigned int va_list_fpr_size : 8;
|
||||
|
||||
/* Nonzero if function being compiled can call setjmp. */
|
||||
unsigned int calls_setjmp : 1;
|
||||
|
||||
/* Nonzero if function being compiled can call alloca,
|
||||
either as a subroutine or builtin. */
|
||||
unsigned int calls_alloca : 1;
|
||||
|
||||
/* Nonzero if function being compiled receives nonlocal gotos
|
||||
from nested functions. */
|
||||
unsigned int has_nonlocal_label : 1;
|
||||
|
||||
/* Nonzero if we've set cannot_be_copied_reason. I.e. if
|
||||
(cannot_be_copied_set && !cannot_be_copied_reason), the function
|
||||
can in fact be copied. */
|
||||
unsigned int cannot_be_copied_set : 1;
|
||||
|
||||
/* Nonzero if current function uses stdarg.h or equivalent. */
|
||||
unsigned int stdarg : 1;
|
||||
|
||||
unsigned int after_inlining : 1;
|
||||
unsigned int always_inline_functions_inlined : 1;
|
||||
|
||||
/* Nonzero if function being compiled can throw synchronous non-call
|
||||
exceptions. */
|
||||
unsigned int can_throw_non_call_exceptions : 1;
|
||||
|
||||
/* Nonzero if instructions that may throw exceptions but don't otherwise
|
||||
contribute to the execution of the program can be deleted. */
|
||||
unsigned int can_delete_dead_exceptions : 1;
|
||||
|
||||
/* Fields below this point are not set for abstract functions; see
|
||||
allocate_struct_function. */
|
||||
|
||||
/* Nonzero if function being compiled needs to be given an address
|
||||
where the value should be stored. */
|
||||
unsigned int returns_struct : 1;
|
||||
|
||||
/* Nonzero if function being compiled needs to
|
||||
return the address of where it has put a structure value. */
|
||||
unsigned int returns_pcc_struct : 1;
|
||||
|
||||
/* Nonzero if this function has local DECL_HARD_REGISTER variables.
|
||||
In this case code motion has to be done more carefully. */
|
||||
unsigned int has_local_explicit_reg_vars : 1;
|
||||
|
||||
/* Nonzero if the current function is a thunk, i.e., a lightweight
|
||||
function implemented by the output_mi_thunk hook) that just
|
||||
adjusts one of its arguments and forwards to another
|
||||
function. */
|
||||
unsigned int is_thunk : 1;
|
||||
};
|
||||
|
||||
/* Add the decl D to the local_decls list of FUN. */
|
||||
|
||||
static inline void
|
||||
add_local_decl (struct function *fun, tree d)
|
||||
{
|
||||
vec_safe_push (fun->local_decls, d);
|
||||
}
|
||||
|
||||
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
||||
FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D)
|
||||
|
||||
/* If va_list_[gf]pr_size is set to this, it means we don't know how
|
||||
many units need to be saved. */
|
||||
#define VA_LIST_MAX_GPR_SIZE 255
|
||||
#define VA_LIST_MAX_FPR_SIZE 255
|
||||
|
||||
/* The function currently being compiled. */
|
||||
extern GTY(()) struct function *cfun;
|
||||
|
||||
/* In order to ensure that cfun is not set directly, we redefine it so
|
||||
that it is not an lvalue. Rather than assign to cfun, use
|
||||
push_cfun or set_cfun. */
|
||||
#define cfun (cfun + 0)
|
||||
|
||||
/* Nonzero if we've already converted virtual regs to hard regs. */
|
||||
extern int virtuals_instantiated;
|
||||
|
||||
/* Nonzero if at least one trampoline has been created. */
|
||||
extern int trampolines_created;
|
||||
|
||||
struct GTY(()) types_used_by_vars_entry {
|
||||
tree type;
|
||||
tree var_decl;
|
||||
};
|
||||
|
||||
/* Hash table making the relationship between a global variable
|
||||
and the types it references in its initializer. The key of the
|
||||
entry is a referenced type, and the value is the DECL of the global
|
||||
variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are
|
||||
the hash and equality functions to use for this hash table. */
|
||||
extern GTY((param_is (struct types_used_by_vars_entry))) htab_t
|
||||
types_used_by_vars_hash;
|
||||
|
||||
hashval_t types_used_by_vars_do_hash (const void*);
|
||||
int types_used_by_vars_eq (const void *, const void *);
|
||||
void types_used_by_var_decl_insert (tree type, tree var_decl);
|
||||
|
||||
/* During parsing of a global variable, this vector contains the types
|
||||
referenced by the global variable. */
|
||||
extern GTY(()) vec<tree, va_gc> *types_used_by_cur_var_decl;
|
||||
|
||||
/* cfun shouldn't be set directly; use one of these functions instead. */
|
||||
extern void set_cfun (struct function *new_cfun);
|
||||
extern void push_cfun (struct function *new_cfun);
|
||||
extern void pop_cfun (void);
|
||||
extern void instantiate_decl_rtl (rtx x);
|
||||
|
||||
/* For backward compatibility... eventually these should all go away. */
|
||||
#define current_function_funcdef_no (cfun->funcdef_no)
|
||||
|
||||
#define current_loops (cfun->x_current_loops)
|
||||
#define dom_computed (cfun->cfg->x_dom_computed)
|
||||
#define n_bbs_in_dom_tree (cfun->cfg->x_n_bbs_in_dom_tree)
|
||||
#define VALUE_HISTOGRAMS(fun) (fun)->value_histograms
|
||||
|
||||
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
|
||||
and create duplicate blocks. */
|
||||
extern void reorder_blocks (void);
|
||||
|
||||
/* Set BLOCK_NUMBER for all the blocks in FN. */
|
||||
extern void number_blocks (tree);
|
||||
|
||||
extern void clear_block_marks (tree);
|
||||
extern tree blocks_nreverse (tree);
|
||||
extern tree block_chainon (tree, tree);
|
||||
|
||||
/* Return size needed for stack frame based on slots so far allocated.
|
||||
This size counts from zero. It is not rounded to STACK_BOUNDARY;
|
||||
the caller may have to do that. */
|
||||
extern HOST_WIDE_INT get_frame_size (void);
|
||||
|
||||
/* Issue an error message and return TRUE if frame OFFSET overflows in
|
||||
the signed target pointer arithmetics for function FUNC. Otherwise
|
||||
return FALSE. */
|
||||
extern bool frame_offset_overflow (HOST_WIDE_INT, tree);
|
||||
|
||||
/* A pointer to a function to create target specific, per-function
|
||||
data structures. */
|
||||
extern struct machine_function * (*init_machine_status) (void);
|
||||
|
||||
/* Save and restore status information for a nested function. */
|
||||
extern void free_after_parsing (struct function *);
|
||||
extern void free_after_compilation (struct function *);
|
||||
|
||||
extern void init_varasm_status (void);
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern void diddle_return_value (void (*)(rtx, void*), void*);
|
||||
extern void clobber_return_register (void);
|
||||
#endif
|
||||
|
||||
extern rtx get_arg_pointer_save_area (void);
|
||||
|
||||
/* Returns the name of the current function. */
|
||||
extern const char *fndecl_name (tree);
|
||||
extern const char *function_name (struct function *);
|
||||
extern const char *current_function_name (void);
|
||||
|
||||
extern void do_warn_unused_parameter (tree);
|
||||
|
||||
extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
extern void used_types_insert (tree);
|
||||
|
||||
extern int get_next_funcdef_no (void);
|
||||
extern int get_last_funcdef_no (void);
|
||||
|
||||
#ifdef HAVE_simple_return
|
||||
extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET);
|
||||
#endif
|
||||
|
||||
extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int);
|
||||
extern rtx has_hard_reg_initial_val (enum machine_mode, unsigned int);
|
||||
extern rtx get_hard_reg_initial_reg (rtx);
|
||||
extern bool initial_value_entry (int i, rtx *, rtx *);
|
||||
|
||||
/* Called from gimple_expand_cfg. */
|
||||
extern unsigned int emit_initial_value_sets (void);
|
||||
|
||||
/* In predict.c */
|
||||
extern bool optimize_function_for_size_p (struct function *);
|
||||
extern bool optimize_function_for_speed_p (struct function *);
|
||||
|
||||
#endif /* GCC_FUNCTION_H */
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/* Public header file for plugins to include.
|
||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_PLUGIN_H
|
||||
#define GCC_PLUGIN_H
|
||||
|
||||
#ifndef IN_GCC
|
||||
#define IN_GCC
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "highlev-plugin-common.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
/* Event names. */
|
||||
enum plugin_event
|
||||
{
|
||||
# define DEFEVENT(NAME) NAME,
|
||||
# include "plugin.def"
|
||||
# undef DEFEVENT
|
||||
PLUGIN_EVENT_FIRST_DYNAMIC
|
||||
};
|
||||
|
||||
/* All globals declared here have C linkage to reduce link compatibility
|
||||
issues with implementation language choice and mangling. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char **plugin_event_name;
|
||||
|
||||
struct plugin_argument
|
||||
{
|
||||
char *key; /* key of the argument. */
|
||||
char *value; /* value is optional and can be NULL. */
|
||||
};
|
||||
|
||||
/* Additional information about the plugin. Used by --help and --version. */
|
||||
|
||||
struct plugin_info
|
||||
{
|
||||
const char *version;
|
||||
const char *help;
|
||||
};
|
||||
|
||||
/* Represents the gcc version. Used to avoid using an incompatible plugin. */
|
||||
|
||||
struct plugin_gcc_version
|
||||
{
|
||||
const char *basever;
|
||||
const char *datestamp;
|
||||
const char *devphase;
|
||||
const char *revision;
|
||||
const char *configuration_arguments;
|
||||
};
|
||||
|
||||
/* Object that keeps track of the plugin name and its arguments. */
|
||||
struct plugin_name_args
|
||||
{
|
||||
char *base_name; /* Short name of the plugin (filename without
|
||||
.so suffix). */
|
||||
const char *full_name; /* Path to the plugin as specified with
|
||||
-fplugin=. */
|
||||
int argc; /* Number of arguments specified with
|
||||
-fplugin-arg-... */
|
||||
struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
|
||||
const char *version; /* Version string provided by plugin. */
|
||||
const char *help; /* Help string provided by plugin. */
|
||||
};
|
||||
|
||||
/* The default version check. Compares every field in VERSION. */
|
||||
|
||||
extern bool plugin_default_version_check (struct plugin_gcc_version *,
|
||||
struct plugin_gcc_version *);
|
||||
|
||||
/* Function type for the plugin initialization routine. Each plugin module
|
||||
should define this as an externally-visible function with name
|
||||
"plugin_init."
|
||||
|
||||
PLUGIN_INFO - plugin invocation information.
|
||||
VERSION - the plugin_gcc_version symbol of GCC.
|
||||
|
||||
Returns 0 if initialization finishes successfully. */
|
||||
|
||||
typedef int (*plugin_init_func) (struct plugin_name_args *plugin_info,
|
||||
struct plugin_gcc_version *version);
|
||||
|
||||
/* Declaration for "plugin_init" function so that it doesn't need to be
|
||||
duplicated in every plugin. */
|
||||
extern int plugin_init (struct plugin_name_args *plugin_info,
|
||||
struct plugin_gcc_version *version);
|
||||
|
||||
/* Function type for a plugin callback routine.
|
||||
|
||||
GCC_DATA - event-specific data provided by GCC
|
||||
USER_DATA - plugin-specific data provided by the plugin */
|
||||
|
||||
typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
|
||||
|
||||
/* Called from the plugin's initialization code. Register a single callback.
|
||||
This function can be called multiple times.
|
||||
|
||||
PLUGIN_NAME - display name for this plugin
|
||||
EVENT - which event the callback is for
|
||||
CALLBACK - the callback to be called at the event
|
||||
USER_DATA - plugin-provided data.
|
||||
*/
|
||||
|
||||
/* Number of event ids / names registered so far. */
|
||||
|
||||
extern int get_event_last (void);
|
||||
|
||||
int get_named_event_id (const char *name, enum insert_option insert);
|
||||
|
||||
/* This is also called without a callback routine for the
|
||||
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
|
||||
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
|
||||
*/
|
||||
|
||||
extern void register_callback (const char *plugin_name,
|
||||
int event,
|
||||
plugin_callback_func callback,
|
||||
void *user_data);
|
||||
|
||||
extern int unregister_callback (const char *plugin_name, int event);
|
||||
|
||||
|
||||
/* Retrieve the plugin directory name, as returned by the
|
||||
-fprint-file-name=plugin argument to the gcc program, which is the
|
||||
-iplugindir program argument to cc1. */
|
||||
extern const char* default_plugin_dir_name (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* In case the C++ compiler does name mangling for globals, declare
|
||||
plugin_is_GPL_compatible extern "C" so that a later definition
|
||||
in a plugin file will have this linkage. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int plugin_is_GPL_compatible;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GCC_PLUGIN_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,279 @@
|
|||
/* Garbage collection for the GNU compiler.
|
||||
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_GGC_H
|
||||
#define GCC_GGC_H
|
||||
#include "statistics.h"
|
||||
|
||||
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
|
||||
an external gc library that might be linked in. */
|
||||
|
||||
/* Constants for general use. */
|
||||
extern const char empty_string[]; /* empty string */
|
||||
|
||||
/* Internal functions and data structures used by the GTY
|
||||
machinery, including the generated gt*.[hc] files. */
|
||||
|
||||
#include "gtype-desc.h"
|
||||
|
||||
/* One of these applies its third parameter (with cookie in the fourth
|
||||
parameter) to each pointer in the object pointed to by the first
|
||||
parameter, using the second parameter. */
|
||||
typedef void (*gt_note_pointers) (void *, void *, gt_pointer_operator,
|
||||
void *);
|
||||
|
||||
/* One of these is called before objects are re-ordered in memory.
|
||||
The first parameter is the original object, the second is the
|
||||
subobject that has had its pointers reordered, the third parameter
|
||||
can compute the new values of a pointer when given the cookie in
|
||||
the fourth parameter. */
|
||||
typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
|
||||
void *);
|
||||
|
||||
/* Used by the gt_pch_n_* routines. Register an object in the hash table. */
|
||||
extern int gt_pch_note_object (void *, void *, gt_note_pointers);
|
||||
|
||||
/* Used by the gt_pch_n_* routines. Register that an object has a reorder
|
||||
function. */
|
||||
extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
|
||||
|
||||
/* Mark the object in the first parameter and anything it points to. */
|
||||
typedef void (*gt_pointer_walker) (void *);
|
||||
|
||||
/* Structures for the easy way to mark roots.
|
||||
In an array, terminated by having base == NULL. */
|
||||
struct ggc_root_tab {
|
||||
void *base;
|
||||
size_t nelt;
|
||||
size_t stride;
|
||||
gt_pointer_walker cb;
|
||||
gt_pointer_walker pchw;
|
||||
};
|
||||
#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL }
|
||||
/* Pointers to arrays of ggc_root_tab, terminated by NULL. */
|
||||
extern const struct ggc_root_tab * const gt_ggc_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_pch_cache_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
|
||||
|
||||
/* Structure for hash table cache marking. */
|
||||
struct htab;
|
||||
struct ggc_cache_tab {
|
||||
struct htab * *base;
|
||||
size_t nelt;
|
||||
size_t stride;
|
||||
gt_pointer_walker cb;
|
||||
gt_pointer_walker pchw;
|
||||
int (*marked_p) (const void *);
|
||||
};
|
||||
#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL }
|
||||
/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
|
||||
extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
|
||||
|
||||
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
|
||||
to true. Otherwise evaluate to false. */
|
||||
#define ggc_test_and_set_mark(EXPR) \
|
||||
((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
|
||||
|
||||
#define ggc_mark(EXPR) \
|
||||
do { \
|
||||
const void *const a__ = (EXPR); \
|
||||
if (a__ != NULL && a__ != (void *) 1) \
|
||||
ggc_set_mark (a__); \
|
||||
} while (0)
|
||||
|
||||
/* Actually set the mark on a particular region of memory, but don't
|
||||
follow pointers. This function is called by ggc_mark_*. It
|
||||
returns zero if the object was not previously marked; nonzero if
|
||||
the object was already marked, or if, for any other reason,
|
||||
pointers in this data structure should not be traversed. */
|
||||
extern int ggc_set_mark (const void *);
|
||||
|
||||
/* Return 1 if P has been marked, zero otherwise.
|
||||
P must have been allocated by the GC allocator; it mustn't point to
|
||||
static objects, stack variables, or memory allocated with malloc. */
|
||||
extern int ggc_marked_p (const void *);
|
||||
|
||||
/* PCH and GGC handling for strings, mostly trivial. */
|
||||
extern void gt_pch_n_S (const void *);
|
||||
extern void gt_ggc_m_S (const void *);
|
||||
|
||||
/* End of GTY machinery API. */
|
||||
|
||||
/* Initialize the string pool. */
|
||||
extern void init_stringpool (void);
|
||||
|
||||
/* Initialize the garbage collector. */
|
||||
extern void init_ggc (void);
|
||||
|
||||
/* When true, identifier nodes are considered as GC roots. When
|
||||
false, identifier nodes are treated like any other GC-allocated
|
||||
object, and the identifier hash table is treated as a weak
|
||||
hash. */
|
||||
extern bool ggc_protect_identifiers;
|
||||
|
||||
/* Write out all GCed objects to F. */
|
||||
extern void gt_pch_save (FILE *f);
|
||||
|
||||
|
||||
/* Allocation. */
|
||||
|
||||
/* The internal primitive. */
|
||||
extern void *ggc_internal_alloc_stat (size_t MEM_STAT_DECL)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
extern size_t ggc_round_alloc_size (size_t requested_size);
|
||||
|
||||
#define ggc_internal_alloc(s) ggc_internal_alloc_stat (s MEM_STAT_INFO)
|
||||
|
||||
/* Allocates cleared memory. */
|
||||
extern void *ggc_internal_cleared_alloc_stat (size_t MEM_STAT_DECL)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Resize a block. */
|
||||
extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL);
|
||||
|
||||
/* Free a block. To be used when known for certain it's not reachable. */
|
||||
extern void ggc_free (void *);
|
||||
|
||||
extern void dump_ggc_loc_statistics (bool);
|
||||
|
||||
/* Reallocators. */
|
||||
#define GGC_RESIZEVEC(T, P, N) \
|
||||
((T *) ggc_realloc_stat ((P), (N) * sizeof (T) MEM_STAT_INFO))
|
||||
|
||||
#define GGC_RESIZEVAR(T, P, N) \
|
||||
((T *) ggc_realloc_stat ((P), (N) MEM_STAT_INFO))
|
||||
|
||||
static inline void *
|
||||
ggc_internal_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL)
|
||||
{
|
||||
return ggc_internal_alloc_stat (c * s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
ggc_internal_cleared_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL)
|
||||
{
|
||||
return ggc_internal_cleared_alloc_stat (c * s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
#define ggc_internal_cleared_vec_alloc(s, c) \
|
||||
(ggc_internal_cleared_vec_alloc_stat ((s), (c) MEM_STAT_INFO))
|
||||
|
||||
static inline void *
|
||||
ggc_alloc_atomic_stat (size_t s MEM_STAT_DECL)
|
||||
{
|
||||
return ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
#define ggc_alloc_atomic(S) (ggc_alloc_atomic_stat ((S) MEM_STAT_INFO))
|
||||
|
||||
#define ggc_alloc_cleared_atomic(S) \
|
||||
(ggc_internal_cleared_alloc_stat ((S) MEM_STAT_INFO))
|
||||
|
||||
extern void *ggc_cleared_alloc_htab_ignore_args (size_t, size_t)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
extern void *ggc_cleared_alloc_ptr_array_two_args (size_t, size_t)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
|
||||
htab_create_typed_alloc (SIZE, HASH, EQ, DEL, \
|
||||
ggc_cleared_alloc_htab_ignore_args, \
|
||||
ggc_cleared_alloc_ptr_array_two_args, \
|
||||
ggc_free)
|
||||
|
||||
#define splay_tree_new_ggc(COMPARE, ALLOC_TREE, ALLOC_NODE) \
|
||||
splay_tree_new_typed_alloc (COMPARE, NULL, NULL, &ALLOC_TREE, &ALLOC_NODE, \
|
||||
&ggc_splay_dont_free, NULL)
|
||||
|
||||
extern void *ggc_splay_alloc (int, void *)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
extern void ggc_splay_dont_free (void *, void *);
|
||||
|
||||
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
|
||||
If LENGTH is -1, then CONTENTS is assumed to be a
|
||||
null-terminated string and the memory sized accordingly. */
|
||||
extern const char *ggc_alloc_string_stat (const char *contents, int length
|
||||
MEM_STAT_DECL);
|
||||
|
||||
#define ggc_alloc_string(c, l) ggc_alloc_string_stat (c, l MEM_STAT_INFO)
|
||||
|
||||
/* Make a copy of S, in GC-able memory. */
|
||||
#define ggc_strdup(S) ggc_alloc_string_stat ((S), -1 MEM_STAT_INFO)
|
||||
|
||||
/* Invoke the collector. Garbage collection occurs only when this
|
||||
function is called, not during allocations. */
|
||||
extern void ggc_collect (void);
|
||||
|
||||
/* Register an additional root table. This can be useful for some
|
||||
plugins. Does nothing if the passed pointer is NULL. */
|
||||
extern void ggc_register_root_tab (const struct ggc_root_tab *);
|
||||
|
||||
/* Register an additional cache table. This can be useful for some
|
||||
plugins. Does nothing if the passed pointer is NULL. */
|
||||
extern void ggc_register_cache_tab (const struct ggc_cache_tab *);
|
||||
|
||||
/* Read objects previously saved with gt_pch_save from F. */
|
||||
extern void gt_pch_restore (FILE *f);
|
||||
|
||||
/* Statistics. */
|
||||
|
||||
/* Print allocation statistics. */
|
||||
extern void ggc_print_statistics (void);
|
||||
|
||||
extern void stringpool_statistics (void);
|
||||
|
||||
/* Heuristics. */
|
||||
extern void init_ggc_heuristics (void);
|
||||
|
||||
#define ggc_alloc_rtvec_sized(NELT) \
|
||||
ggc_alloc_rtvec_def (sizeof (struct rtvec_def) \
|
||||
+ ((NELT) - 1) * sizeof (rtx)) \
|
||||
|
||||
/* Memory statistics passing versions of some allocators. Too few of them to
|
||||
make gengtype produce them, so just define the needed ones here. */
|
||||
static inline struct rtx_def *
|
||||
ggc_alloc_rtx_def_stat (size_t s MEM_STAT_DECL)
|
||||
{
|
||||
return (struct rtx_def *) ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
static inline union tree_node *
|
||||
ggc_alloc_tree_node_stat (size_t s MEM_STAT_DECL)
|
||||
{
|
||||
return (union tree_node *) ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
static inline union tree_node *
|
||||
ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL)
|
||||
{
|
||||
return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
static inline union gimple_statement_d *
|
||||
ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL)
|
||||
{
|
||||
return (union gimple_statement_d *)
|
||||
ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* Various declarations for pretty formatting of GIMPLE statements and
|
||||
expressions.
|
||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_GIMPLE_PRETTY_PRINT_H
|
||||
#define GCC_GIMPLE_PRETTY_PRINT_H
|
||||
|
||||
#include "pretty-print.h"
|
||||
#include "tree-pretty-print.h"
|
||||
|
||||
/* In gimple-pretty-print.c */
|
||||
extern void debug_gimple_stmt (gimple);
|
||||
extern void debug_gimple_seq (gimple_seq);
|
||||
extern void print_gimple_seq (FILE *, gimple_seq, int, int);
|
||||
extern void print_gimple_stmt (FILE *, gimple, int, int);
|
||||
extern void print_gimple_expr (FILE *, gimple, int, int);
|
||||
extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
|
||||
extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
|
||||
|
||||
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
/* This file contains the definitions of the GIMPLE IR tuples used in GCC.
|
||||
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The format of this file is
|
||||
DEFGSCODE(GIMPLE_symbol, printable name, GSS_symbol). */
|
||||
|
||||
|
||||
/* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */
|
||||
DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE)
|
||||
|
||||
/* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and
|
||||
GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls.
|
||||
These are all the GIMPLE statements with register operands. */
|
||||
|
||||
/* GIMPLE_COND <COND_CODE, OP1, OP2, TRUE_LABEL, FALSE_LABEL>
|
||||
represents the conditional jump:
|
||||
|
||||
if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL
|
||||
|
||||
COND_CODE is the tree code used as the comparison predicate. It
|
||||
must be of class tcc_comparison.
|
||||
|
||||
OP1 and OP2 are the operands used in the comparison. They must be
|
||||
accepted by is_gimple_operand.
|
||||
|
||||
TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the
|
||||
jump target for the comparison. */
|
||||
DEFGSCODE(GIMPLE_COND, "gimple_cond", GSS_WITH_OPS)
|
||||
|
||||
/* GIMPLE_DEBUG represents a debug statement. */
|
||||
DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS)
|
||||
|
||||
/* GIMPLE_GOTO <TARGET> represents unconditional jumps.
|
||||
TARGET is a LABEL_DECL or an expression node for computed GOTOs. */
|
||||
DEFGSCODE(GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS)
|
||||
|
||||
/* GIMPLE_LABEL <LABEL> represents label statements. LABEL is a
|
||||
LABEL_DECL representing a jump target. */
|
||||
DEFGSCODE(GIMPLE_LABEL, "gimple_label", GSS_WITH_OPS)
|
||||
|
||||
/* GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the
|
||||
multiway branch:
|
||||
|
||||
switch (INDEX)
|
||||
{
|
||||
case LAB1: ...; break;
|
||||
...
|
||||
case LABN: ...; break;
|
||||
default: ...
|
||||
}
|
||||
|
||||
INDEX is the variable evaluated to decide which label to jump to.
|
||||
|
||||
DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels.
|
||||
They must be CASE_LABEL_EXPR nodes. */
|
||||
DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", GSS_WITH_OPS)
|
||||
|
||||
/* IMPORTANT.
|
||||
|
||||
Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN.
|
||||
It's exposed by GIMPLE_RANGE_CHECK calls. These are all the GIMPLE
|
||||
statements with memory and register operands. */
|
||||
|
||||
/* GIMPLE_ASSIGN <SUBCODE, LHS, RHS1[, RHS2]> represents the assignment
|
||||
statement
|
||||
|
||||
LHS = RHS1 SUBCODE RHS2.
|
||||
|
||||
SUBCODE is the tree code for the expression computed by the RHS of the
|
||||
assignment. It must be one of the tree codes accepted by
|
||||
get_gimple_rhs_class. If LHS is not a gimple register according to
|
||||
is_gimple_reg, SUBCODE must be of class GIMPLE_SINGLE_RHS.
|
||||
|
||||
LHS is the operand on the LHS of the assignment. It must be a tree node
|
||||
accepted by is_gimple_lvalue.
|
||||
|
||||
RHS1 is the first operand on the RHS of the assignment. It must always be
|
||||
present. It must be a tree node accepted by is_gimple_val.
|
||||
|
||||
RHS2 is the second operand on the RHS of the assignment. It must be a tree
|
||||
node accepted by is_gimple_val. This argument exists only if SUBCODE is
|
||||
of class GIMPLE_BINARY_RHS. */
|
||||
DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", GSS_WITH_MEM_OPS)
|
||||
|
||||
/* GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP>
|
||||
represents inline assembly statements.
|
||||
|
||||
STRING is the string containing the assembly statements.
|
||||
I1 ... IN are the N input operands.
|
||||
O1 ... OM are the M output operands.
|
||||
C1 ... CP are the P clobber operands.
|
||||
L1 ... LQ are the Q label operands. */
|
||||
DEFGSCODE(GIMPLE_ASM, "gimple_asm", GSS_ASM)
|
||||
|
||||
/* GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function
|
||||
calls.
|
||||
|
||||
FN is the callee. It must be accepted by is_gimple_call_addr.
|
||||
|
||||
LHS is the operand where the return value from FN is stored. It may
|
||||
be NULL.
|
||||
|
||||
ARG1 ... ARGN are the arguments. They must all be accepted by
|
||||
is_gimple_operand.
|
||||
|
||||
CHAIN is the optional static chain link for nested functions. */
|
||||
DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_CALL)
|
||||
|
||||
/* GIMPLE_TRANSACTION <BODY, LABEL> represents __transaction_atomic and
|
||||
__transaction_relaxed blocks.
|
||||
BODY is the sequence of statements inside the transaction.
|
||||
LABEL is a label for the statement immediately following the
|
||||
transaction. This is before RETURN so that it has MEM_OPS,
|
||||
so that it can clobber global memory. */
|
||||
DEFGSCODE(GIMPLE_TRANSACTION, "gimple_transaction", GSS_TRANSACTION)
|
||||
|
||||
/* GIMPLE_RETURN <RETVAL> represents return statements.
|
||||
|
||||
RETVAL is the value to return or NULL. If a value is returned it
|
||||
must be accepted by is_gimple_operand. */
|
||||
DEFGSCODE(GIMPLE_RETURN, "gimple_return", GSS_WITH_MEM_OPS)
|
||||
|
||||
/* GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope.
|
||||
VARS is the set of variables declared in that scope.
|
||||
BLOCK is the symbol binding block used for debug information.
|
||||
BODY is the sequence of statements in the scope. */
|
||||
DEFGSCODE(GIMPLE_BIND, "gimple_bind", GSS_BIND)
|
||||
|
||||
/* GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler.
|
||||
TYPES is the type (or list of types) handled. HANDLER is the
|
||||
sequence of statements that handle these types. */
|
||||
DEFGSCODE(GIMPLE_CATCH, "gimple_catch", GSS_CATCH)
|
||||
|
||||
/* GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception
|
||||
specification. TYPES is a list of allowed types and FAILURE is the
|
||||
sequence of statements to execute on failure. */
|
||||
DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", GSS_EH_FILTER)
|
||||
|
||||
/* GIMPLE_EH_MUST_NOT_THROW <DECL> represents an exception barrier.
|
||||
DECL is a noreturn function decl taking no arguments that will
|
||||
be invoked if an exception propagates to this point. */
|
||||
DEFGSCODE(GIMPLE_EH_MUST_NOT_THROW, "gimple_eh_must_not_throw", GSS_EH_MNT)
|
||||
|
||||
/* GIMPLE_EH_ELSE <N_BODY, E_BODY> must be the sole contents of
|
||||
a GIMPLE_TRY_FINALLY node. For all normal exits from the try block,
|
||||
N_BODY is run; for all exception exits from the try block,
|
||||
E_BODY is run. */
|
||||
DEFGSCODE(GIMPLE_EH_ELSE, "gimple_eh_else", GSS_EH_ELSE)
|
||||
|
||||
/* GIMPLE_RESX resumes execution after an exception. */
|
||||
DEFGSCODE(GIMPLE_RESX, "gimple_resx", GSS_EH_CTRL)
|
||||
|
||||
/* GIMPLE_EH_DISPATCH demultiplexes an exception edge based on
|
||||
the FILTER argument. */
|
||||
DEFGSCODE(GIMPLE_EH_DISPATCH, "gimple_eh_dispatch", GSS_EH_CTRL)
|
||||
|
||||
/* GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node
|
||||
|
||||
RESULT = PHI <ARG1, ..., ARGN>
|
||||
|
||||
RESULT is the SSA name created by this PHI node.
|
||||
|
||||
ARG1 ... ARGN are the arguments to the PHI node. N must be
|
||||
exactly the same as the number of incoming edges to the basic block
|
||||
holding the PHI node. Every argument is either an SSA name or a
|
||||
tree node of class tcc_constant. */
|
||||
DEFGSCODE(GIMPLE_PHI, "gimple_phi", GSS_PHI)
|
||||
|
||||
/* GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP>
|
||||
represents a try/catch or a try/finally statement.
|
||||
|
||||
TRY_KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY.
|
||||
|
||||
EVAL is the sequence of statements to execute on entry to GIMPLE_TRY.
|
||||
|
||||
CLEANUP is the sequence of statements to execute according to
|
||||
TRY_KIND. If TRY_KIND is GIMPLE_TRY_CATCH, CLEANUP is only exected
|
||||
if an exception is thrown during execution of EVAL. If TRY_KIND is
|
||||
GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL
|
||||
(regardless of whether EVAL finished normally, or jumped out or an
|
||||
exception was thrown). */
|
||||
DEFGSCODE(GIMPLE_TRY, "gimple_try", GSS_TRY)
|
||||
|
||||
/* GIMPLE_NOP represents the "do nothing" statement. */
|
||||
DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE)
|
||||
|
||||
|
||||
/* IMPORTANT.
|
||||
|
||||
Do not rearrange any of the GIMPLE_OMP_* codes. This ordering is
|
||||
exposed by the range check in gimple_omp_subcode(). */
|
||||
|
||||
|
||||
/* Tuples used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC
|
||||
expression is very simple (just in form mem op= expr), various implicit
|
||||
conversions may cause the expression to become more complex, so that it does
|
||||
not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC
|
||||
is rewritten as a sequence of two codes in gimplification:
|
||||
|
||||
GIMPLE_OMP_LOAD (tmp, mem)
|
||||
val = some computations involving tmp;
|
||||
GIMPLE_OMP_STORE (val). */
|
||||
DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load",
|
||||
GSS_OMP_ATOMIC_LOAD)
|
||||
DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store",
|
||||
GSS_OMP_ATOMIC_STORE)
|
||||
|
||||
/* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
|
||||
iteration in partially lowered OpenMP code. */
|
||||
DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", GSS_OMP_CONTINUE)
|
||||
|
||||
/* GIMPLE_OMP_CRITICAL <NAME, BODY> represents
|
||||
|
||||
#pragma omp critical [name]
|
||||
|
||||
NAME is the name given to the critical section.
|
||||
BODY is the sequence of statements that are inside the critical section. */
|
||||
DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
|
||||
|
||||
/* GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY>
|
||||
represents
|
||||
|
||||
PRE_BODY
|
||||
#pragma omp for [clause1 ... clauseN]
|
||||
for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR)
|
||||
BODY
|
||||
|
||||
BODY is the loop body.
|
||||
|
||||
CLAUSES is the list of clauses.
|
||||
|
||||
INDEX must be an integer or pointer variable, which is implicitly thread
|
||||
private. It must be accepted by is_gimple_operand.
|
||||
|
||||
INITIAL is the initial value given to INDEX. It must be
|
||||
accepted by is_gimple_operand.
|
||||
|
||||
FINAL is the final value that INDEX should take. It must
|
||||
be accepted by is_gimple_operand.
|
||||
|
||||
COND is the condition code for the controlling predicate. It must
|
||||
be one of { <, >, <=, >= }
|
||||
|
||||
INCR is the loop index increment. It must be tree node of type
|
||||
tcc_constant.
|
||||
|
||||
PRE_BODY is a landing pad filled by the gimplifier with things from
|
||||
INIT, COND, and INCR that are technically part of the OMP_FOR
|
||||
structured block, but are evaluated before the loop body begins.
|
||||
|
||||
INITIAL, FINAL and INCR are required to be loop invariant integer
|
||||
expressions that are evaluated without any synchronization.
|
||||
The evaluation order, frequency of evaluation and side-effects are
|
||||
unspecified by the standard. */
|
||||
DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
|
||||
|
||||
/* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
|
||||
BODY is the sequence of statements to execute in the master section. */
|
||||
DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
|
||||
|
||||
/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
|
||||
BODY is the sequence of statements to execute in the ordered section. */
|
||||
DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
|
||||
|
||||
/* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
|
||||
|
||||
#pragma omp parallel [CLAUSES]
|
||||
BODY
|
||||
|
||||
BODY is a the sequence of statements to be executed by all threads.
|
||||
|
||||
CLAUSES is a TREE_LIST node with all the clauses.
|
||||
|
||||
CHILD_FN is set when outlining the body of the parallel region.
|
||||
All the statements in BODY are moved into this newly created
|
||||
function when converting OMP constructs into low-GIMPLE.
|
||||
|
||||
DATA_ARG is a local variable in the parent function containing data
|
||||
to be shared with CHILD_FN. This is used to implement all the data
|
||||
sharing clauses. */
|
||||
DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
|
||||
|
||||
/* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
|
||||
ARG_SIZE, ARG_ALIGN> represents
|
||||
|
||||
#pragma omp task [CLAUSES]
|
||||
BODY
|
||||
|
||||
BODY is a the sequence of statements to be executed by all threads.
|
||||
|
||||
CLAUSES is a TREE_LIST node with all the clauses.
|
||||
|
||||
CHILD_FN is set when outlining the body of the explicit task region.
|
||||
All the statements in BODY are moved into this newly created
|
||||
function when converting OMP constructs into low-GIMPLE.
|
||||
|
||||
DATA_ARG is a local variable in the parent function containing data
|
||||
to be shared with CHILD_FN. This is used to implement all the data
|
||||
sharing clauses.
|
||||
|
||||
COPY_FN is set when outlining the firstprivate var initialization.
|
||||
All the needed statements are emitted into the newly created
|
||||
function, or when only memcpy is needed, it is NULL.
|
||||
|
||||
ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming
|
||||
data area allocated by GOMP_task and passed to CHILD_FN. */
|
||||
DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
|
||||
|
||||
/* OMP_RETURN marks the end of an OpenMP directive. */
|
||||
DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE)
|
||||
|
||||
/* OMP_SECTION <BODY> represents #pragma omp section.
|
||||
BODY is the sequence of statements in the section body. */
|
||||
DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
|
||||
|
||||
/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
|
||||
|
||||
BODY is the sequence of statements in the sections body.
|
||||
CLAUSES is a TREE_LIST node holding the list of associated clauses.
|
||||
CONTROL is a VAR_DECL used for deciding which of the sections
|
||||
to execute. */
|
||||
DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS)
|
||||
|
||||
/* GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after
|
||||
OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which
|
||||
branch is taken. */
|
||||
DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
|
||||
|
||||
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
|
||||
BODY is the sequence of statements inside the single section.
|
||||
CLAUSES is a TREE_LIST node holding the associated clauses. */
|
||||
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
|
||||
|
||||
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
|
||||
|
||||
PREDICT is one of the predictors from predict.def.
|
||||
|
||||
OUTCOME is NOT_TAKEN or TAKEN. */
|
||||
DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", GSS_BASE)
|
||||
|
||||
/* This node represents a cleanup expression. It is ONLY USED INTERNALLY
|
||||
by the gimplifier as a placeholder for cleanups, and its uses will be
|
||||
cleaned up by the time gimplification is done.
|
||||
|
||||
This tuple should not exist outside of the gimplifier proper. */
|
||||
DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", GSS_WCE)
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,53 @@
|
|||
/* This file contains the definitions for the gimple IR structure
|
||||
enumeration used in GCC.
|
||||
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The format of this file is
|
||||
DEFGSSTRUCT(GSS enumeration value, structure name, has-tree-operands).
|
||||
Each enum value should correspond with a single member of the union
|
||||
gimple_statement_d. */
|
||||
|
||||
DEFGSSTRUCT(GSS_BASE, gimple_statement_base, false)
|
||||
DEFGSSTRUCT(GSS_WITH_OPS, gimple_statement_with_ops, true)
|
||||
DEFGSSTRUCT(GSS_WITH_MEM_OPS_BASE, gimple_statement_with_memory_ops_base, false)
|
||||
DEFGSSTRUCT(GSS_WITH_MEM_OPS, gimple_statement_with_memory_ops, true)
|
||||
DEFGSSTRUCT(GSS_CALL, gimple_statement_call, true)
|
||||
DEFGSSTRUCT(GSS_ASM, gimple_statement_asm, true)
|
||||
DEFGSSTRUCT(GSS_BIND, gimple_statement_bind, false)
|
||||
DEFGSSTRUCT(GSS_PHI, gimple_statement_phi, false)
|
||||
DEFGSSTRUCT(GSS_TRY, gimple_statement_try, false)
|
||||
DEFGSSTRUCT(GSS_CATCH, gimple_statement_catch, false)
|
||||
DEFGSSTRUCT(GSS_EH_FILTER, gimple_statement_eh_filter, false)
|
||||
DEFGSSTRUCT(GSS_EH_MNT, gimple_statement_eh_mnt, false)
|
||||
DEFGSSTRUCT(GSS_EH_CTRL, gimple_statement_eh_ctrl, false)
|
||||
DEFGSSTRUCT(GSS_EH_ELSE, gimple_statement_eh_else, false)
|
||||
DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false)
|
||||
DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false)
|
||||
DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false)
|
||||
DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false)
|
||||
DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false)
|
||||
DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false)
|
||||
DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false)
|
||||
DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false)
|
||||
DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false)
|
||||
DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false)
|
||||
DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false)
|
||||
DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false)
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
DEF_TM_BUILTIN (BUILT_IN_TM_START, "_ITM_beginTransaction",
|
||||
BT_FN_UINT32_UINT32_VAR, ATTR_TM_NOTHROW_RT_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT, "_ITM_commitTransaction",
|
||||
BT_FN_VOID, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT_EH, "_ITM_commitTransactionEH",
|
||||
BT_FN_VOID_PTR, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_ABORT, "_ITM_abortTransaction",
|
||||
BT_FN_VOID_INT, ATTR_TM_NORETURN_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_IRREVOCABLE, "_ITM_changeTransactionMode",
|
||||
BT_FN_VOID_INT, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_MEMCPY, "_ITM_memcpyRtWt",
|
||||
BT_FN_VOID_PTR_CONST_PTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_MEMMOVE, "_ITM_memmoveRtWt",
|
||||
BT_FN_VOID_PTR_CONST_PTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_MEMSET, "_ITM_memsetW",
|
||||
BT_FN_VOID_PTR_INT_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_GETTMCLONE_IRR, "_ITM_getTMCloneOrIrrevocable",
|
||||
BT_FN_PTR_PTR, ATTR_TM_CONST_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_GETTMCLONE_SAFE, "_ITM_getTMCloneSafe",
|
||||
BT_FN_PTR_PTR, ATTR_TM_CONST_NOTHROW_LIST)
|
||||
|
||||
/* Memory allocation builtins. */
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_MALLOC, "_ITM_malloc",
|
||||
BT_FN_PTR_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_CALLOC, "_ITM_calloc",
|
||||
BT_FN_PTR_SIZE_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_FREE, "_ITM_free",
|
||||
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LIST)
|
||||
|
||||
/* Logging builtins. */
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_1, "_ITM_LU1",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_2, "_ITM_LU2",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_4, "_ITM_LU4",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_8, "_ITM_LU8",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_FLOAT, "_ITM_LF",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_DOUBLE, "_ITM_LD",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_LDOUBLE, "_ITM_LE",
|
||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG, "_ITM_LB",
|
||||
BT_FN_VOID_VPTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||
|
||||
/* These stubs should get defined in the backend if applicable. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M64, "__builtin__ITM_LM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M128, "__builtin__ITM_LM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M256, "__builtin__ITM_LM256")
|
||||
|
||||
/* Writes.
|
||||
|
||||
Note: The writes must follow the following order: STORE, WAR, WAW.
|
||||
The TM optimizations depend on this order.
|
||||
|
||||
BUILT_IN_TM_STORE_1 must be the first builtin.
|
||||
BUILTIN_TM_LOAD_STORE_P depends on this. */
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_1, "_ITM_WU1",
|
||||
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_1, "_ITM_WaRU1",
|
||||
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_1, "_ITM_WaWU1",
|
||||
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_2, "_ITM_WU2",
|
||||
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_2, "_ITM_WaRU2",
|
||||
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_2, "_ITM_WaWU2",
|
||||
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_4, "_ITM_WU4",
|
||||
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_4, "_ITM_WaRU4",
|
||||
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_4, "_ITM_WaWU4",
|
||||
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_8, "_ITM_WU8",
|
||||
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_8, "_ITM_WaRU8",
|
||||
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_8, "_ITM_WaWU8",
|
||||
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_FLOAT, "_ITM_WF",
|
||||
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_FLOAT, "_ITM_WaRF",
|
||||
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_FLOAT, "_ITM_WaWF",
|
||||
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_DOUBLE, "_ITM_WD",
|
||||
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_DOUBLE, "_ITM_WaRD",
|
||||
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_DOUBLE, "_ITM_WaWD",
|
||||
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||
|
||||
/* These stubs should get defined in the backend if applicable. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M64, "__builtin__ITM_WM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M64, "__builtin__ITM_WaRM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M64, "__builtin__ITM_WaWM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M128, "__builtin__ITM_WM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M128, "__builtin__ITM_WaRM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M128, "__builtin__ITM_WaWM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M256, "__builtin__ITM_WM256")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M256, "__builtin__ITM_WaRM256")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M256, "__builtin__ITM_WaWM256")
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_LDOUBLE, "_ITM_WE",
|
||||
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_LDOUBLE, "_ITM_WaRE",
|
||||
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_LDOUBLE, "_ITM_WaWE",
|
||||
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||
/* Note: BUILT_IN_TM_STORE_WAW_LDOUBLE must be the last TM store.
|
||||
BUILTIN_TM_STORE_P depends on this. */
|
||||
|
||||
/* Reads.
|
||||
|
||||
Note: The reads must follow the following order: LOAD, RAR, RAW, RFW.
|
||||
The TM optimizations depend on this order. */
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_1, "_ITM_RU1",
|
||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_1, "_ITM_RaRU1",
|
||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_1, "_ITM_RaWU1",
|
||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_1, "_ITM_RfWU1",
|
||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_2, "_ITM_RU2",
|
||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_2, "_ITM_RaRU2",
|
||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_2, "_ITM_RaWU2",
|
||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_2, "_ITM_RfWU2",
|
||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_4, "_ITM_RU4",
|
||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_4, "_ITM_RaRU4",
|
||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_4, "_ITM_RaWU4",
|
||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_4, "_ITM_RfWU4",
|
||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_8, "_ITM_RU8",
|
||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_8, "_ITM_RaRU8",
|
||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_8, "_ITM_RaWU8",
|
||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_8, "_ITM_RfWU8",
|
||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_FLOAT, "_ITM_RF",
|
||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_FLOAT, "_ITM_RaRF",
|
||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_FLOAT, "_ITM_RaWF",
|
||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_FLOAT, "_ITM_RfWF",
|
||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_DOUBLE, "_ITM_RD",
|
||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_DOUBLE, "_ITM_RaRD",
|
||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_DOUBLE, "_ITM_RaWD",
|
||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_DOUBLE, "_ITM_RfWD",
|
||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
/* These stubs should get defined in the backend if applicable. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M64, "__builtin__ITM_RM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M64, "__builtin__ITM_RaRM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M64, "__builtin__ITM_RaRM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M64, "__builtin__ITM_RfWM64")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M128, "__builtin__ITM_RM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M128, "__builtin__ITM_RaRM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M128, "__builtin__ITM_RaRM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M128, "__builtin__ITM_RfWM128")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M256, "__builtin__ITM_RM256")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M256, "__builtin__ITM_RaRM256")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M256, "__builtin__ITM_RaRM256")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M256, "__builtin__ITM_RfWM256")
|
||||
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_LDOUBLE, "_ITM_RE",
|
||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_LDOUBLE, "_ITM_RaRE",
|
||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_LDOUBLE, "_ITM_RaWE",
|
||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_LDOUBLE, "_ITM_RfWE",
|
||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||
|
||||
/* Note: BUILT_IN_TM_LOAD_RFW_LDOUBLE must be the last TM load as well
|
||||
as the last builtin. BUILTIN_TM_LOAD_STORE_P and BUILTIN_TM_LOAD_P
|
||||
depend on this. */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,724 @@
|
|||
/* Sets (bit vectors) of hard registers, and operations on them.
|
||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_HARD_REG_SET_H
|
||||
#define GCC_HARD_REG_SET_H
|
||||
|
||||
/* Define the type of a set of hard registers. */
|
||||
|
||||
/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
|
||||
will be used for hard reg sets, either alone or in an array.
|
||||
|
||||
If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE,
|
||||
and it has enough bits to represent all the target machine's hard
|
||||
registers. Otherwise, it is a typedef for a suitably sized array
|
||||
of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many.
|
||||
|
||||
Note that lots of code assumes that the first part of a regset is
|
||||
the same format as a HARD_REG_SET. To help make sure this is true,
|
||||
we only try the widest fast integer mode (HOST_WIDEST_FAST_INT)
|
||||
instead of all the smaller types. This approach loses only if
|
||||
there are very few registers and then only in the few cases where
|
||||
we have an array of HARD_REG_SETs, so it needn't be as complex as
|
||||
it used to be. */
|
||||
|
||||
typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;
|
||||
|
||||
#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
|
||||
|
||||
#define HARD_REG_SET HARD_REG_ELT_TYPE
|
||||
|
||||
#else
|
||||
|
||||
#define HARD_REG_SET_LONGS \
|
||||
((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \
|
||||
/ HOST_BITS_PER_WIDEST_FAST_INT)
|
||||
typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
|
||||
|
||||
#endif
|
||||
|
||||
/* HARD_REG_SET wrapped into a structure, to make it possible to
|
||||
use HARD_REG_SET even in APIs that should not include
|
||||
hard-reg-set.h. */
|
||||
struct hard_reg_set_container
|
||||
{
|
||||
HARD_REG_SET set;
|
||||
};
|
||||
|
||||
/* HARD_CONST is used to cast a constant to the appropriate type
|
||||
for use with a HARD_REG_SET. */
|
||||
|
||||
#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X))
|
||||
|
||||
/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT
|
||||
to set, clear or test one bit in a hard reg set of type HARD_REG_SET.
|
||||
All three take two arguments: the set and the register number.
|
||||
|
||||
In the case where sets are arrays of longs, the first argument
|
||||
is actually a pointer to a long.
|
||||
|
||||
Define two macros for initializing a set:
|
||||
CLEAR_HARD_REG_SET and SET_HARD_REG_SET.
|
||||
These take just one argument.
|
||||
|
||||
Also define macros for copying hard reg sets:
|
||||
COPY_HARD_REG_SET and COMPL_HARD_REG_SET.
|
||||
These take two arguments TO and FROM; they read from FROM
|
||||
and store into TO. COMPL_HARD_REG_SET complements each bit.
|
||||
|
||||
Also define macros for combining hard reg sets:
|
||||
IOR_HARD_REG_SET and AND_HARD_REG_SET.
|
||||
These take two arguments TO and FROM; they read from FROM
|
||||
and combine bitwise into TO. Define also two variants
|
||||
IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET
|
||||
which use the complement of the set FROM.
|
||||
|
||||
Also define:
|
||||
|
||||
hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
|
||||
hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal.
|
||||
hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
|
||||
hard_reg_set_empty_p (X), which returns true if X is empty. */
|
||||
|
||||
#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
|
||||
|
||||
#ifdef HARD_REG_SET
|
||||
|
||||
#define SET_HARD_REG_BIT(SET, BIT) \
|
||||
((SET) |= HARD_CONST (1) << (BIT))
|
||||
#define CLEAR_HARD_REG_BIT(SET, BIT) \
|
||||
((SET) &= ~(HARD_CONST (1) << (BIT)))
|
||||
#define TEST_HARD_REG_BIT(SET, BIT) \
|
||||
(!!((SET) & (HARD_CONST (1) << (BIT))))
|
||||
|
||||
#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
|
||||
#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
|
||||
|
||||
#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM))
|
||||
#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM))
|
||||
|
||||
#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM))
|
||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM))
|
||||
#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))
|
||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return (x & ~y) == HARD_CONST (0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return (x & y) != HARD_CONST (0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||
{
|
||||
return x == HARD_CONST (0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define SET_HARD_REG_BIT(SET, BIT) \
|
||||
((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
||||
|= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))
|
||||
|
||||
#define CLEAR_HARD_REG_BIT(SET, BIT) \
|
||||
((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
||||
&= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
|
||||
|
||||
#define TEST_HARD_REG_BIT(SET, BIT) \
|
||||
(!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
||||
& (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
|
||||
|
||||
#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
|
||||
#define CLEAR_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
scan_tp_[0] = 0; \
|
||||
scan_tp_[1] = 0; } while (0)
|
||||
|
||||
#define SET_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
scan_tp_[0] = -1; \
|
||||
scan_tp_[1] = -1; } while (0)
|
||||
|
||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] = scan_fp_[0]; \
|
||||
scan_tp_[1] = scan_fp_[1]; } while (0)
|
||||
|
||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] = ~ scan_fp_[0]; \
|
||||
scan_tp_[1] = ~ scan_fp_[1]; } while (0)
|
||||
|
||||
#define AND_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] &= scan_fp_[0]; \
|
||||
scan_tp_[1] &= scan_fp_[1]; } while (0)
|
||||
|
||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] &= ~ scan_fp_[0]; \
|
||||
scan_tp_[1] &= ~ scan_fp_[1]; } while (0)
|
||||
|
||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] |= scan_fp_[0]; \
|
||||
scan_tp_[1] |= scan_fp_[1]; } while (0)
|
||||
|
||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] |= ~ scan_fp_[0]; \
|
||||
scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return x[0] == y[0] && x[1] == y[1];
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||
{
|
||||
return x[0] == 0 && x[1] == 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
|
||||
#define CLEAR_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
scan_tp_[0] = 0; \
|
||||
scan_tp_[1] = 0; \
|
||||
scan_tp_[2] = 0; } while (0)
|
||||
|
||||
#define SET_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
scan_tp_[0] = -1; \
|
||||
scan_tp_[1] = -1; \
|
||||
scan_tp_[2] = -1; } while (0)
|
||||
|
||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] = scan_fp_[0]; \
|
||||
scan_tp_[1] = scan_fp_[1]; \
|
||||
scan_tp_[2] = scan_fp_[2]; } while (0)
|
||||
|
||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] = ~ scan_fp_[0]; \
|
||||
scan_tp_[1] = ~ scan_fp_[1]; \
|
||||
scan_tp_[2] = ~ scan_fp_[2]; } while (0)
|
||||
|
||||
#define AND_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] &= scan_fp_[0]; \
|
||||
scan_tp_[1] &= scan_fp_[1]; \
|
||||
scan_tp_[2] &= scan_fp_[2]; } while (0)
|
||||
|
||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] &= ~ scan_fp_[0]; \
|
||||
scan_tp_[1] &= ~ scan_fp_[1]; \
|
||||
scan_tp_[2] &= ~ scan_fp_[2]; } while (0)
|
||||
|
||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] |= scan_fp_[0]; \
|
||||
scan_tp_[1] |= scan_fp_[1]; \
|
||||
scan_tp_[2] |= scan_fp_[2]; } while (0)
|
||||
|
||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] |= ~ scan_fp_[0]; \
|
||||
scan_tp_[1] |= ~ scan_fp_[1]; \
|
||||
scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return ((x[0] & ~y[0]) == 0
|
||||
&& (x[1] & ~y[1]) == 0
|
||||
&& (x[2] & ~y[2]) == 0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return ((x[0] & y[0]) != 0
|
||||
|| (x[1] & y[1]) != 0
|
||||
|| (x[2] & y[2]) != 0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||
{
|
||||
return x[0] == 0 && x[1] == 0 && x[2] == 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
|
||||
#define CLEAR_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
scan_tp_[0] = 0; \
|
||||
scan_tp_[1] = 0; \
|
||||
scan_tp_[2] = 0; \
|
||||
scan_tp_[3] = 0; } while (0)
|
||||
|
||||
#define SET_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
scan_tp_[0] = -1; \
|
||||
scan_tp_[1] = -1; \
|
||||
scan_tp_[2] = -1; \
|
||||
scan_tp_[3] = -1; } while (0)
|
||||
|
||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] = scan_fp_[0]; \
|
||||
scan_tp_[1] = scan_fp_[1]; \
|
||||
scan_tp_[2] = scan_fp_[2]; \
|
||||
scan_tp_[3] = scan_fp_[3]; } while (0)
|
||||
|
||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] = ~ scan_fp_[0]; \
|
||||
scan_tp_[1] = ~ scan_fp_[1]; \
|
||||
scan_tp_[2] = ~ scan_fp_[2]; \
|
||||
scan_tp_[3] = ~ scan_fp_[3]; } while (0)
|
||||
|
||||
#define AND_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] &= scan_fp_[0]; \
|
||||
scan_tp_[1] &= scan_fp_[1]; \
|
||||
scan_tp_[2] &= scan_fp_[2]; \
|
||||
scan_tp_[3] &= scan_fp_[3]; } while (0)
|
||||
|
||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] &= ~ scan_fp_[0]; \
|
||||
scan_tp_[1] &= ~ scan_fp_[1]; \
|
||||
scan_tp_[2] &= ~ scan_fp_[2]; \
|
||||
scan_tp_[3] &= ~ scan_fp_[3]; } while (0)
|
||||
|
||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] |= scan_fp_[0]; \
|
||||
scan_tp_[1] |= scan_fp_[1]; \
|
||||
scan_tp_[2] |= scan_fp_[2]; \
|
||||
scan_tp_[3] |= scan_fp_[3]; } while (0)
|
||||
|
||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
scan_tp_[0] |= ~ scan_fp_[0]; \
|
||||
scan_tp_[1] |= ~ scan_fp_[1]; \
|
||||
scan_tp_[2] |= ~ scan_fp_[2]; \
|
||||
scan_tp_[3] |= ~ scan_fp_[3]; } while (0)
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return ((x[0] & ~y[0]) == 0
|
||||
&& (x[1] & ~y[1]) == 0
|
||||
&& (x[2] & ~y[2]) == 0
|
||||
&& (x[3] & ~y[3]) == 0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
return ((x[0] & y[0]) != 0
|
||||
|| (x[1] & y[1]) != 0
|
||||
|| (x[2] & y[2]) != 0
|
||||
|| (x[3] & y[3]) != 0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||
{
|
||||
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
|
||||
}
|
||||
|
||||
#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
|
||||
|
||||
#define CLEAR_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ = 0; } while (0)
|
||||
|
||||
#define SET_HARD_REG_SET(TO) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ = -1; } while (0)
|
||||
|
||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ = *scan_fp_++; } while (0)
|
||||
|
||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ = ~ *scan_fp_++; } while (0)
|
||||
|
||||
#define AND_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ &= *scan_fp_++; } while (0)
|
||||
|
||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ &= ~ *scan_fp_++; } while (0)
|
||||
|
||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ |= *scan_fp_++; } while (0)
|
||||
|
||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||
int i; \
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||
*scan_tp_++ |= ~ *scan_fp_++; } while (0)
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||
if ((x[i] & ~y[i]) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||
if (x[i] != y[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||
if ((x[i] & y[i]) != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||
if (x[i] != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Iterator for hard register sets. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Pointer to the current element. */
|
||||
HARD_REG_ELT_TYPE *pelt;
|
||||
|
||||
/* The length of the set. */
|
||||
unsigned short length;
|
||||
|
||||
/* Word within the current element. */
|
||||
unsigned short word_no;
|
||||
|
||||
/* Contents of the actually processed word. When finding next bit
|
||||
it is shifted right, so that the actual bit is always the least
|
||||
significant bit of ACTUAL. */
|
||||
HARD_REG_ELT_TYPE bits;
|
||||
} hard_reg_set_iterator;
|
||||
|
||||
#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT
|
||||
|
||||
/* The implementation of the iterator functions is fully analogous to
|
||||
the bitmap iterators. */
|
||||
static inline void
|
||||
hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,
|
||||
unsigned min, unsigned *regno)
|
||||
{
|
||||
#ifdef HARD_REG_SET_LONGS
|
||||
iter->pelt = set;
|
||||
iter->length = HARD_REG_SET_LONGS;
|
||||
#else
|
||||
iter->pelt = &set;
|
||||
iter->length = 1;
|
||||
#endif
|
||||
iter->word_no = min / HARD_REG_ELT_BITS;
|
||||
if (iter->word_no < iter->length)
|
||||
{
|
||||
iter->bits = iter->pelt[iter->word_no];
|
||||
iter->bits >>= min % HARD_REG_ELT_BITS;
|
||||
|
||||
/* This is required for correct search of the next bit. */
|
||||
min += !iter->bits;
|
||||
}
|
||||
*regno = min;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
/* Return false when we're advanced past the end of the set. */
|
||||
if (iter->word_no >= iter->length)
|
||||
return false;
|
||||
|
||||
if (iter->bits)
|
||||
{
|
||||
/* Find the correct bit and return it. */
|
||||
while (!(iter->bits & 1))
|
||||
{
|
||||
iter->bits >>= 1;
|
||||
*regno += 1;
|
||||
}
|
||||
return (*regno < FIRST_PSEUDO_REGISTER);
|
||||
}
|
||||
|
||||
/* Round to the beginning of the next word. */
|
||||
*regno = (*regno + HARD_REG_ELT_BITS - 1);
|
||||
*regno -= *regno % HARD_REG_ELT_BITS;
|
||||
|
||||
/* Find the next non-zero word. */
|
||||
while (++iter->word_no < iter->length)
|
||||
{
|
||||
iter->bits = iter->pelt[iter->word_no];
|
||||
if (iter->bits)
|
||||
break;
|
||||
*regno += HARD_REG_ELT_BITS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
|
||||
{
|
||||
iter->bits >>= 1;
|
||||
*regno += 1;
|
||||
}
|
||||
|
||||
#define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER) \
|
||||
for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM)); \
|
||||
hard_reg_set_iter_set (&(ITER), &(REGNUM)); \
|
||||
hard_reg_set_iter_next (&(ITER), &(REGNUM)))
|
||||
|
||||
|
||||
/* Define some standard sets of registers. */
|
||||
|
||||
/* Indexed by hard register number, contains 1 for registers
|
||||
that are being used for global register decls.
|
||||
These must be exempt from ordinary flow analysis
|
||||
and are also considered fixed. */
|
||||
|
||||
extern char global_regs[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
struct target_hard_regs {
|
||||
/* The set of registers that actually exist on the current target. */
|
||||
HARD_REG_SET x_accessible_reg_set;
|
||||
|
||||
/* The set of registers that should be considered to be register
|
||||
operands. It is a subset of x_accessible_reg_set. */
|
||||
HARD_REG_SET x_operand_reg_set;
|
||||
|
||||
/* Indexed by hard register number, contains 1 for registers
|
||||
that are fixed use (stack pointer, pc, frame pointer, etc.;.
|
||||
These are the registers that cannot be used to allocate
|
||||
a pseudo reg whose life does not cross calls. */
|
||||
char x_fixed_regs[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* The same info as a HARD_REG_SET. */
|
||||
HARD_REG_SET x_fixed_reg_set;
|
||||
|
||||
/* Indexed by hard register number, contains 1 for registers
|
||||
that are fixed use or are clobbered by function calls.
|
||||
These are the registers that cannot be used to allocate
|
||||
a pseudo reg whose life crosses calls. */
|
||||
char x_call_used_regs[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
char x_call_really_used_regs[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* The same info as a HARD_REG_SET. */
|
||||
HARD_REG_SET x_call_used_reg_set;
|
||||
|
||||
/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
|
||||
a function value return register or TARGET_STRUCT_VALUE_RTX or
|
||||
STATIC_CHAIN_REGNUM. These are the registers that cannot hold quantities
|
||||
across calls even if we are willing to save and restore them. */
|
||||
HARD_REG_SET x_call_fixed_reg_set;
|
||||
|
||||
/* Contains 1 for registers that are set or clobbered by calls. */
|
||||
/* ??? Ideally, this would be just call_used_regs plus global_regs, but
|
||||
for someone's bright idea to have call_used_regs strictly include
|
||||
fixed_regs. Which leaves us guessing as to the set of fixed_regs
|
||||
that are actually preserved. We know for sure that those associated
|
||||
with the local stack frame are safe, but scant others. */
|
||||
HARD_REG_SET x_regs_invalidated_by_call;
|
||||
|
||||
/* Call used hard registers which can not be saved because there is no
|
||||
insn for this. */
|
||||
HARD_REG_SET x_no_caller_save_reg_set;
|
||||
|
||||
/* Table of register numbers in the order in which to try to use them. */
|
||||
int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* The inverse of reg_alloc_order. */
|
||||
int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* For each reg class, a HARD_REG_SET saying which registers are in it. */
|
||||
HARD_REG_SET x_reg_class_contents[N_REG_CLASSES];
|
||||
|
||||
/* For each reg class, a boolean saying whether the class contains only
|
||||
fixed registers. */
|
||||
bool x_class_only_fixed_regs[N_REG_CLASSES];
|
||||
|
||||
/* For each reg class, number of regs it contains. */
|
||||
unsigned int x_reg_class_size[N_REG_CLASSES];
|
||||
|
||||
/* For each reg class, table listing all the classes contained in it. */
|
||||
enum reg_class x_reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
|
||||
|
||||
/* For each pair of reg classes,
|
||||
a largest reg class contained in their union. */
|
||||
enum reg_class x_reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
|
||||
|
||||
/* For each pair of reg classes,
|
||||
the smallest reg class that contains their union. */
|
||||
enum reg_class x_reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
|
||||
|
||||
/* Vector indexed by hardware reg giving its name. */
|
||||
const char *x_reg_names[FIRST_PSEUDO_REGISTER];
|
||||
};
|
||||
|
||||
extern struct target_hard_regs default_target_hard_regs;
|
||||
#if SWITCHABLE_TARGET
|
||||
extern struct target_hard_regs *this_target_hard_regs;
|
||||
#else
|
||||
#define this_target_hard_regs (&default_target_hard_regs)
|
||||
#endif
|
||||
|
||||
#define accessible_reg_set \
|
||||
(this_target_hard_regs->x_accessible_reg_set)
|
||||
#define operand_reg_set \
|
||||
(this_target_hard_regs->x_operand_reg_set)
|
||||
#define fixed_regs \
|
||||
(this_target_hard_regs->x_fixed_regs)
|
||||
#define fixed_reg_set \
|
||||
(this_target_hard_regs->x_fixed_reg_set)
|
||||
#define call_used_regs \
|
||||
(this_target_hard_regs->x_call_used_regs)
|
||||
#define call_really_used_regs \
|
||||
(this_target_hard_regs->x_call_really_used_regs)
|
||||
#define call_used_reg_set \
|
||||
(this_target_hard_regs->x_call_used_reg_set)
|
||||
#define call_fixed_reg_set \
|
||||
(this_target_hard_regs->x_call_fixed_reg_set)
|
||||
#define regs_invalidated_by_call \
|
||||
(this_target_hard_regs->x_regs_invalidated_by_call)
|
||||
#define no_caller_save_reg_set \
|
||||
(this_target_hard_regs->x_no_caller_save_reg_set)
|
||||
#define reg_alloc_order \
|
||||
(this_target_hard_regs->x_reg_alloc_order)
|
||||
#define inv_reg_alloc_order \
|
||||
(this_target_hard_regs->x_inv_reg_alloc_order)
|
||||
#define reg_class_contents \
|
||||
(this_target_hard_regs->x_reg_class_contents)
|
||||
#define class_only_fixed_regs \
|
||||
(this_target_hard_regs->x_class_only_fixed_regs)
|
||||
#define reg_class_size \
|
||||
(this_target_hard_regs->x_reg_class_size)
|
||||
#define reg_class_subclasses \
|
||||
(this_target_hard_regs->x_reg_class_subclasses)
|
||||
#define reg_class_subunion \
|
||||
(this_target_hard_regs->x_reg_class_subunion)
|
||||
#define reg_class_superunion \
|
||||
(this_target_hard_regs->x_reg_class_superunion)
|
||||
#define reg_names \
|
||||
(this_target_hard_regs->x_reg_names)
|
||||
|
||||
/* Vector indexed by reg class giving its name. */
|
||||
|
||||
extern const char * reg_class_names[];
|
||||
|
||||
/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
|
||||
REGN cannot change modes between the specified modes. */
|
||||
#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO) \
|
||||
CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
|
||||
|
||||
#endif /* ! GCC_HARD_REG_SET_H */
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
/* An expandable hash tables datatype.
|
||||
Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2009, 2010
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* This package implements basic hash table functionality. It is possible
|
||||
to search for an entry, create an entry and destroy an entry.
|
||||
|
||||
Elements in the table are generic pointers.
|
||||
|
||||
The size of the table is not fixed; if the occupancy of the table
|
||||
grows too high the hash table will be expanded.
|
||||
|
||||
The abstract data implementation is based on generalized Algorithm D
|
||||
from Knuth's book "The art of computer programming". Hash table is
|
||||
expanded by creation of new hash table and transferring elements from
|
||||
the old table to the new table. */
|
||||
|
||||
#ifndef __HASHTAB_H__
|
||||
#define __HASHTAB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "ansidecl.h"
|
||||
|
||||
#ifndef GTY
|
||||
#define GTY(X)
|
||||
#endif
|
||||
|
||||
/* The type for a hash code. */
|
||||
typedef unsigned int hashval_t;
|
||||
|
||||
/* Callback function pointer types. */
|
||||
|
||||
/* Calculate hash of a table entry. */
|
||||
typedef hashval_t (*htab_hash) (const void *);
|
||||
|
||||
/* Compare a table entry with a possible entry. The entry already in
|
||||
the table always comes first, so the second element can be of a
|
||||
different type (but in this case htab_find and htab_find_slot
|
||||
cannot be used; instead the variants that accept a hash value
|
||||
must be used). */
|
||||
typedef int (*htab_eq) (const void *, const void *);
|
||||
|
||||
/* Cleanup function called whenever a live element is removed from
|
||||
the hash table. */
|
||||
typedef void (*htab_del) (void *);
|
||||
|
||||
/* Function called by htab_traverse for each live element. The first
|
||||
arg is the slot of the element (which can be passed to htab_clear_slot
|
||||
if desired), the second arg is the auxiliary pointer handed to
|
||||
htab_traverse. Return 1 to continue scan, 0 to stop. */
|
||||
typedef int (*htab_trav) (void **, void *);
|
||||
|
||||
/* Memory-allocation function, with the same functionality as calloc().
|
||||
Iff it returns NULL, the hash table implementation will pass an error
|
||||
code back to the user, so if your code doesn't handle errors,
|
||||
best if you use xcalloc instead. */
|
||||
typedef void *(*htab_alloc) (size_t, size_t);
|
||||
|
||||
/* We also need a free() routine. */
|
||||
typedef void (*htab_free) (void *);
|
||||
|
||||
/* Memory allocation and deallocation; variants which take an extra
|
||||
argument. */
|
||||
typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t);
|
||||
typedef void (*htab_free_with_arg) (void *, void *);
|
||||
|
||||
/* This macro defines reserved value for empty table entry. */
|
||||
|
||||
#define HTAB_EMPTY_ENTRY ((PTR) 0)
|
||||
|
||||
/* This macro defines reserved value for table entry which contained
|
||||
a deleted element. */
|
||||
|
||||
#define HTAB_DELETED_ENTRY ((PTR) 1)
|
||||
|
||||
/* Hash tables are of the following type. The structure
|
||||
(implementation) of this type is not needed for using the hash
|
||||
tables. All work with hash table should be executed only through
|
||||
functions mentioned below. The size of this structure is subject to
|
||||
change. */
|
||||
|
||||
struct GTY(()) htab {
|
||||
/* Pointer to hash function. */
|
||||
htab_hash hash_f;
|
||||
|
||||
/* Pointer to comparison function. */
|
||||
htab_eq eq_f;
|
||||
|
||||
/* Pointer to cleanup function. */
|
||||
htab_del del_f;
|
||||
|
||||
/* Table itself. */
|
||||
void ** GTY ((use_param, length ("%h.size"))) entries;
|
||||
|
||||
/* Current size (in entries) of the hash table. */
|
||||
size_t size;
|
||||
|
||||
/* Current number of elements including also deleted elements. */
|
||||
size_t n_elements;
|
||||
|
||||
/* Current number of deleted elements in the table. */
|
||||
size_t n_deleted;
|
||||
|
||||
/* The following member is used for debugging. Its value is number
|
||||
of all calls of `htab_find_slot' for the hash table. */
|
||||
unsigned int searches;
|
||||
|
||||
/* The following member is used for debugging. Its value is number
|
||||
of collisions fixed for time of work with the hash table. */
|
||||
unsigned int collisions;
|
||||
|
||||
/* Pointers to allocate/free functions. */
|
||||
htab_alloc alloc_f;
|
||||
htab_free free_f;
|
||||
|
||||
/* Alternate allocate/free functions, which take an extra argument. */
|
||||
void * GTY((skip)) alloc_arg;
|
||||
htab_alloc_with_arg alloc_with_arg_f;
|
||||
htab_free_with_arg free_with_arg_f;
|
||||
|
||||
/* Current size (in entries) of the hash table, as an index into the
|
||||
table of primes. */
|
||||
unsigned int size_prime_index;
|
||||
};
|
||||
|
||||
typedef struct htab *htab_t;
|
||||
|
||||
/* An enum saying whether we insert into the hash table or not. */
|
||||
enum insert_option {NO_INSERT, INSERT};
|
||||
|
||||
/* The prototypes of the package functions. */
|
||||
|
||||
extern htab_t htab_create_alloc (size_t, htab_hash,
|
||||
htab_eq, htab_del,
|
||||
htab_alloc, htab_free);
|
||||
|
||||
extern htab_t htab_create_alloc_ex (size_t, htab_hash,
|
||||
htab_eq, htab_del,
|
||||
void *, htab_alloc_with_arg,
|
||||
htab_free_with_arg);
|
||||
|
||||
extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del,
|
||||
htab_alloc, htab_alloc, htab_free);
|
||||
|
||||
/* Backward-compatibility functions. */
|
||||
extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del);
|
||||
extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del);
|
||||
|
||||
extern void htab_set_functions_ex (htab_t, htab_hash,
|
||||
htab_eq, htab_del,
|
||||
void *, htab_alloc_with_arg,
|
||||
htab_free_with_arg);
|
||||
|
||||
extern void htab_delete (htab_t);
|
||||
extern void htab_empty (htab_t);
|
||||
|
||||
extern void * htab_find (htab_t, const void *);
|
||||
extern void ** htab_find_slot (htab_t, const void *, enum insert_option);
|
||||
extern void * htab_find_with_hash (htab_t, const void *, hashval_t);
|
||||
extern void ** htab_find_slot_with_hash (htab_t, const void *,
|
||||
hashval_t, enum insert_option);
|
||||
extern void htab_clear_slot (htab_t, void **);
|
||||
extern void htab_remove_elt (htab_t, void *);
|
||||
extern void htab_remove_elt_with_hash (htab_t, void *, hashval_t);
|
||||
|
||||
extern void htab_traverse (htab_t, htab_trav, void *);
|
||||
extern void htab_traverse_noresize (htab_t, htab_trav, void *);
|
||||
|
||||
extern size_t htab_size (htab_t);
|
||||
extern size_t htab_elements (htab_t);
|
||||
extern double htab_collisions (htab_t);
|
||||
|
||||
/* A hash function for pointers. */
|
||||
extern htab_hash htab_hash_pointer;
|
||||
|
||||
/* An equality function for pointers. */
|
||||
extern htab_eq htab_eq_pointer;
|
||||
|
||||
/* A hash function for null-terminated strings. */
|
||||
extern hashval_t htab_hash_string (const void *);
|
||||
|
||||
/* An iterative hash function for arbitrary data. */
|
||||
extern hashval_t iterative_hash (const void *, size_t, hashval_t);
|
||||
/* Shorthand for hashing something with an intrinsic size. */
|
||||
#define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __HASHTAB_H */
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/* Interface for high-level plugins in GCC - Parts common between GCC,
|
||||
ICI and high-level plugins.
|
||||
|
||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by INRIA.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef HIGHLEV_PLUGIN_COMMON_H
|
||||
#define HIGHLEV_PLUGIN_COMMON_H
|
||||
|
||||
/* Return codes for invoke_plugin_callbacks / call_plugin_event . */
|
||||
#define PLUGEVT_SUCCESS 0
|
||||
#define PLUGEVT_NO_EVENTS 1
|
||||
#define PLUGEVT_NO_SUCH_EVENT 2
|
||||
#define PLUGEVT_NO_CALLBACK 3
|
||||
|
||||
#endif /* HIGHLEV_PLUGIN_COMMON_H */
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
/* HOST_WIDE_INT definitions for the GNU compiler.
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
Provide definitions for macros which depend on HOST_BITS_PER_INT
|
||||
and HOST_BITS_PER_LONG. */
|
||||
|
||||
#ifndef GCC_HWINT_H
|
||||
#define GCC_HWINT_H
|
||||
|
||||
/* This describes the machine the compiler is hosted on. */
|
||||
#define HOST_BITS_PER_CHAR CHAR_BIT
|
||||
#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
|
||||
#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT)
|
||||
#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
|
||||
|
||||
/* The string that should be inserted into a printf style format to
|
||||
indicate a "long" operand. */
|
||||
#ifndef HOST_LONG_FORMAT
|
||||
#define HOST_LONG_FORMAT "l"
|
||||
#endif
|
||||
|
||||
/* The string that should be inserted into a printf style format to
|
||||
indicate a "long long" operand. */
|
||||
#ifndef HOST_LONG_LONG_FORMAT
|
||||
#define HOST_LONG_LONG_FORMAT "ll"
|
||||
#endif
|
||||
|
||||
/* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but
|
||||
GCC_VERSION >= 3000, assume this is the second or later stage of a
|
||||
bootstrap, we do have long long, and it's 64 bits. (This is
|
||||
required by C99; we do have some ports that violate that assumption
|
||||
but they're all cross-compile-only.) Just in case, force a
|
||||
constraint violation if that assumption is incorrect. */
|
||||
#if !defined HAVE_LONG_LONG
|
||||
# if GCC_VERSION >= 3000
|
||||
# define HAVE_LONG_LONG 1
|
||||
# define SIZEOF_LONG_LONG 8
|
||||
extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
|
||||
#endif
|
||||
#ifdef HAVE___INT64
|
||||
# define HOST_BITS_PER___INT64 (CHAR_BIT * SIZEOF___INT64)
|
||||
#endif
|
||||
|
||||
/* Set HOST_WIDE_INT. This should be the widest efficient host
|
||||
integer type. It can be 32 or 64 bits, except that if we are
|
||||
targeting a machine with 64-bit size_t then it has to be 64 bits.
|
||||
|
||||
With a sane ABI, 'long' is the largest efficient host integer type.
|
||||
Thus, we use that unless we have to use 'long long' or '__int64'
|
||||
because we're targeting a 64-bit machine from a 32-bit host. */
|
||||
|
||||
#if HOST_BITS_PER_LONG >= 64 || !defined NEED_64BIT_HOST_WIDE_INT
|
||||
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
|
||||
# define HOST_WIDE_INT long
|
||||
# define HOST_WIDE_INT_C(X) X ## L
|
||||
#else
|
||||
# if HOST_BITS_PER_LONGLONG >= 64
|
||||
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
|
||||
# define HOST_WIDE_INT long long
|
||||
# define HOST_WIDE_INT_C(X) X ## LL
|
||||
# else
|
||||
# if HOST_BITS_PER___INT64 >= 64
|
||||
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER___INT64
|
||||
# define HOST_WIDE_INT __int64
|
||||
# define HOST_WIDE_INT_C(X) X ## i64
|
||||
# else
|
||||
#error "Unable to find a suitable type for HOST_WIDE_INT"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1)
|
||||
|
||||
/* This is a magic identifier which allows GCC to figure out the type
|
||||
of HOST_WIDE_INT for %wd specifier checks. You must issue this
|
||||
typedef before using the __asm_fprintf__ format attribute. */
|
||||
typedef HOST_WIDE_INT __gcc_host_wide_int__;
|
||||
|
||||
/* Various printf format strings for HOST_WIDE_INT. */
|
||||
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
# define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
|
||||
# define HOST_WIDE_INT_PRINT_C "L"
|
||||
/* 'long' might be 32 or 64 bits, and the number of leading zeroes
|
||||
must be tweaked accordingly. */
|
||||
# if HOST_BITS_PER_WIDE_INT == 64
|
||||
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
|
||||
"0x%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x"
|
||||
# else
|
||||
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
|
||||
"0x%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x"
|
||||
# endif
|
||||
#else
|
||||
# define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
|
||||
# define HOST_WIDE_INT_PRINT_C "LL"
|
||||
/* We can assume that 'long long' is at least 64 bits. */
|
||||
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
|
||||
"0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
|
||||
#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
|
||||
|
||||
#define HOST_WIDE_INT_PRINT_DEC "%" HOST_WIDE_INT_PRINT "d"
|
||||
#define HOST_WIDE_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_C
|
||||
#define HOST_WIDE_INT_PRINT_UNSIGNED "%" HOST_WIDE_INT_PRINT "u"
|
||||
#define HOST_WIDE_INT_PRINT_HEX "%#" HOST_WIDE_INT_PRINT "x"
|
||||
#define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x"
|
||||
|
||||
/* Set HOST_WIDEST_INT. This is a 64-bit type unless the compiler
|
||||
in use has no 64-bit type at all; in that case it's 32 bits. */
|
||||
|
||||
#if HOST_BITS_PER_WIDE_INT >= 64 \
|
||||
|| (HOST_BITS_PER_LONGLONG < 64 && HOST_BITS_PER___INT64 < 64)
|
||||
# define HOST_WIDEST_INT HOST_WIDE_INT
|
||||
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_WIDE_INT
|
||||
# define HOST_WIDEST_INT_PRINT HOST_WIDE_INT_PRINT
|
||||
# define HOST_WIDEST_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC
|
||||
# define HOST_WIDEST_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC_C
|
||||
# define HOST_WIDEST_INT_PRINT_UNSIGNED HOST_WIDE_INT_PRINT_UNSIGNED
|
||||
# define HOST_WIDEST_INT_PRINT_HEX HOST_WIDE_INT_PRINT_HEX
|
||||
# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX HOST_WIDE_INT_PRINT_DOUBLE_HEX
|
||||
# define HOST_WIDEST_INT_C(X) HOST_WIDE_INT(X)
|
||||
#else
|
||||
# if HOST_BITS_PER_LONGLONG >= 64
|
||||
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
|
||||
# define HOST_WIDEST_INT long long
|
||||
# define HOST_WIDEST_INT_C(X) X ## LL
|
||||
# else
|
||||
# if HOST_BITS_PER___INT64 >= 64
|
||||
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER___INT64
|
||||
# define HOST_WIDEST_INT __int64
|
||||
# define HOST_WIDEST_INT_C(X) X ## i64
|
||||
# else
|
||||
#error "This line should be impossible to reach"
|
||||
# endif
|
||||
# endif
|
||||
# define HOST_WIDEST_INT_PRINT HOST_LONG_LONG_FORMAT
|
||||
# define HOST_WIDEST_INT_PRINT_DEC "%" HOST_LONG_LONG_FORMAT "d"
|
||||
# define HOST_WIDEST_INT_PRINT_DEC_C "%" HOST_LONG_LONG_FORMAT "dLL"
|
||||
# define HOST_WIDEST_INT_PRINT_UNSIGNED "%" HOST_LONG_LONG_FORMAT "u"
|
||||
# define HOST_WIDEST_INT_PRINT_HEX "%#" HOST_LONG_LONG_FORMAT "x"
|
||||
# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX \
|
||||
"0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
|
||||
#endif
|
||||
|
||||
/* Define HOST_WIDEST_FAST_INT to the widest integer type supported
|
||||
efficiently in hardware. (That is, the widest integer type that fits
|
||||
in a hardware register.) Normally this is "long" but on some hosts it
|
||||
should be "long long" or "__int64". This is no convenient way to
|
||||
autodetect this, so such systems must set a flag in config.host; see there
|
||||
for details. */
|
||||
|
||||
#ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT
|
||||
# ifdef HAVE_LONG_LONG
|
||||
# define HOST_WIDEST_FAST_INT long long
|
||||
# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG
|
||||
# elif defined (HAVE___INT64)
|
||||
# define HOST_WIDEST_FAST_INT __int64
|
||||
# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER___INT64
|
||||
# else
|
||||
# error "Your host said it wanted to use long long or __int64 but neither"
|
||||
# error "exist"
|
||||
# endif
|
||||
#else
|
||||
# define HOST_WIDEST_FAST_INT long
|
||||
# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG
|
||||
#endif
|
||||
|
||||
/* Inline functions operating on HOST_WIDE_INT. */
|
||||
#if GCC_VERSION < 3004
|
||||
|
||||
extern int clz_hwi (unsigned HOST_WIDE_INT x);
|
||||
extern int ctz_hwi (unsigned HOST_WIDE_INT x);
|
||||
extern int ffs_hwi (unsigned HOST_WIDE_INT x);
|
||||
|
||||
/* Return the number of set bits in X. */
|
||||
extern int popcount_hwi (unsigned HOST_WIDE_INT x);
|
||||
|
||||
/* Return log2, or -1 if not exact. */
|
||||
extern int exact_log2 (unsigned HOST_WIDE_INT);
|
||||
|
||||
/* Return floor of log2, with -1 for zero. */
|
||||
extern int floor_log2 (unsigned HOST_WIDE_INT);
|
||||
|
||||
/* Return the smallest n such that 2**n >= X. */
|
||||
extern int ceil_log2 (unsigned HOST_WIDE_INT);
|
||||
|
||||
#else /* GCC_VERSION >= 3004 */
|
||||
|
||||
/* For convenience, define 0 -> word_size. */
|
||||
static inline int
|
||||
clz_hwi (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
if (x == 0)
|
||||
return HOST_BITS_PER_WIDE_INT;
|
||||
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
return __builtin_clzl (x);
|
||||
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||
return __builtin_clzll (x);
|
||||
# else
|
||||
return __builtin_clz (x);
|
||||
# endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
ctz_hwi (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
if (x == 0)
|
||||
return HOST_BITS_PER_WIDE_INT;
|
||||
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
return __builtin_ctzl (x);
|
||||
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||
return __builtin_ctzll (x);
|
||||
# else
|
||||
return __builtin_ctz (x);
|
||||
# endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
ffs_hwi (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
return __builtin_ffsl (x);
|
||||
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||
return __builtin_ffsll (x);
|
||||
# else
|
||||
return __builtin_ffs (x);
|
||||
# endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
popcount_hwi (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
return __builtin_popcountl (x);
|
||||
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||
return __builtin_popcountll (x);
|
||||
# else
|
||||
return __builtin_popcount (x);
|
||||
# endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
floor_log2 (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ceil_log2 (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
return floor_log2 (x - 1) + 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
exact_log2 (unsigned HOST_WIDE_INT x)
|
||||
{
|
||||
return x == (x & -x) && x ? ctz_hwi (x) : -1;
|
||||
}
|
||||
|
||||
#endif /* GCC_VERSION >= 3004 */
|
||||
|
||||
#define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \
|
||||
((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
|
||||
#define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN))
|
||||
|
||||
extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT);
|
||||
extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT);
|
||||
extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||
extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||
extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||
extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||
|
||||
#endif /* ! GCC_HWINT_H */
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/* Set up combined include path for the preprocessor.
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
extern void split_quote_chain (void);
|
||||
extern void add_path (char *, int, int, bool);
|
||||
extern void register_include_chains (cpp_reader *, const char *,
|
||||
const char *, const char *,
|
||||
int, int, int);
|
||||
extern void add_cpp_dir_path (struct cpp_dir *, int);
|
||||
extern struct cpp_dir *get_added_cpp_dirs (int);
|
||||
|
||||
struct target_c_incpath_s {
|
||||
/* Do extra includes processing. STDINC is false iff -nostdinc was given. */
|
||||
void (*extra_pre_includes) (const char *, const char *, int);
|
||||
void (*extra_includes) (const char *, const char *, int);
|
||||
};
|
||||
|
||||
extern struct target_c_incpath_s target_c_incpath;
|
||||
|
||||
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* Declarations for variables relating to reading the source file.
|
||||
Used by parsers, lexical analyzers, and error message routines.
|
||||
Copyright (C) 1993-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_INPUT_H
|
||||
#define GCC_INPUT_H
|
||||
|
||||
#include "line-map.h"
|
||||
|
||||
extern GTY(()) struct line_maps *line_table;
|
||||
|
||||
/* A value which will never be used to represent a real location. */
|
||||
#define UNKNOWN_LOCATION ((source_location) 0)
|
||||
|
||||
/* The location for declarations in "<built-in>" */
|
||||
#define BUILTINS_LOCATION ((source_location) 1)
|
||||
|
||||
/* line-map.c reserves RESERVED_LOCATION_COUNT to the user. Ensure
|
||||
both UNKNOWN_LOCATION and BUILTINS_LOCATION fit into that. */
|
||||
extern char builtins_location_check[(BUILTINS_LOCATION
|
||||
< RESERVED_LOCATION_COUNT) ? 1 : -1];
|
||||
|
||||
extern expanded_location expand_location (source_location);
|
||||
extern const char * location_get_source_line(expanded_location xloc);
|
||||
extern expanded_location expand_location_to_spelling_point (source_location);
|
||||
extern source_location expansion_point_location_if_in_system_header (source_location);
|
||||
|
||||
/* Historically GCC used location_t, while cpp used source_location.
|
||||
This could be removed but it hardly seems worth the effort. */
|
||||
typedef source_location location_t;
|
||||
|
||||
extern location_t input_location;
|
||||
|
||||
#define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
|
||||
#define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
|
||||
#define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
|
||||
#define LOCATION_LOCUS(LOC) \
|
||||
((IS_ADHOC_LOC(LOC)) ? get_location_from_adhoc_loc (line_table, LOC) : (LOC))
|
||||
#define LOCATION_BLOCK(LOC) \
|
||||
((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (line_table, (LOC)) \
|
||||
: NULL))
|
||||
|
||||
#define input_line LOCATION_LINE (input_location)
|
||||
#define input_filename LOCATION_FILE (input_location)
|
||||
#define in_system_header_at(LOC) \
|
||||
((linemap_location_in_system_header_p (line_table, LOC)))
|
||||
#define in_system_header (in_system_header_at (input_location))
|
||||
|
||||
void dump_line_table_statistics (void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
/* Generated automatically by the program `genconstants'
|
||||
from the machine description file `md'. */
|
||||
|
||||
#ifndef GCC_INSN_CONSTANTS_H
|
||||
#define GCC_INSN_CONSTANTS_H
|
||||
|
||||
#define CMP_CMP 0
|
||||
#define DOM_CC_NX_OR_Y 1
|
||||
#define DOM_CC_X_OR_Y 2
|
||||
#define CC_REGNUM 100
|
||||
#define WCGR3 46
|
||||
#define SP_REGNUM 13
|
||||
#define R1_REGNUM 1
|
||||
#define PC_REGNUM 15
|
||||
#define WCGR0 43
|
||||
#define VFPCC_REGNUM 101
|
||||
#define CMP_CMN 2
|
||||
#define NUM_OF_COND_CMP 4
|
||||
#define WCGR2 45
|
||||
#define R0_REGNUM 0
|
||||
#define WCGR1 44
|
||||
#define CMN_CMP 1
|
||||
#define LR_REGNUM 14
|
||||
#define DOM_CC_X_AND_Y 0
|
||||
#define CMN_CMN 3
|
||||
#define IP_REGNUM 12
|
||||
#define LAST_ARM_REGNUM 15
|
||||
|
||||
enum unspec {
|
||||
UNSPEC_PUSH_MULT = 0,
|
||||
UNSPEC_PIC_SYM = 1,
|
||||
UNSPEC_PIC_BASE = 2,
|
||||
UNSPEC_PRLG_STK = 3,
|
||||
UNSPEC_REGISTER_USE = 4,
|
||||
UNSPEC_CHECK_ARCH = 5,
|
||||
UNSPEC_WSHUFH = 6,
|
||||
UNSPEC_WACC = 7,
|
||||
UNSPEC_TMOVMSK = 8,
|
||||
UNSPEC_WSAD = 9,
|
||||
UNSPEC_WSADZ = 10,
|
||||
UNSPEC_WMACS = 11,
|
||||
UNSPEC_WMACU = 12,
|
||||
UNSPEC_WMACSZ = 13,
|
||||
UNSPEC_WMACUZ = 14,
|
||||
UNSPEC_CLRDI = 15,
|
||||
UNSPEC_WALIGNI = 16,
|
||||
UNSPEC_TLS = 17,
|
||||
UNSPEC_PIC_LABEL = 18,
|
||||
UNSPEC_PIC_OFFSET = 19,
|
||||
UNSPEC_GOTSYM_OFF = 20,
|
||||
UNSPEC_THUMB1_CASESI = 21,
|
||||
UNSPEC_RBIT = 22,
|
||||
UNSPEC_SYMBOL_OFFSET = 23,
|
||||
UNSPEC_MEMORY_BARRIER = 24,
|
||||
UNSPEC_UNALIGNED_LOAD = 25,
|
||||
UNSPEC_UNALIGNED_STORE = 26,
|
||||
UNSPEC_PIC_UNIFIED = 27,
|
||||
UNSPEC_LL = 28,
|
||||
UNSPEC_VRINTZ = 29,
|
||||
UNSPEC_VRINTP = 30,
|
||||
UNSPEC_VRINTM = 31,
|
||||
UNSPEC_VRINTR = 32,
|
||||
UNSPEC_VRINTX = 33,
|
||||
UNSPEC_VRINTA = 34,
|
||||
UNSPEC_WADDC = 35,
|
||||
UNSPEC_WABS = 36,
|
||||
UNSPEC_WQMULWMR = 37,
|
||||
UNSPEC_WQMULMR = 38,
|
||||
UNSPEC_WQMULWM = 39,
|
||||
UNSPEC_WQMULM = 40,
|
||||
UNSPEC_WQMIAxyn = 41,
|
||||
UNSPEC_WQMIAxy = 42,
|
||||
UNSPEC_TANDC = 43,
|
||||
UNSPEC_TORC = 44,
|
||||
UNSPEC_TORVSC = 45,
|
||||
UNSPEC_TEXTRC = 46,
|
||||
UNSPEC_ASHIFT_SIGNED = 47,
|
||||
UNSPEC_ASHIFT_UNSIGNED = 48,
|
||||
UNSPEC_LOAD_COUNT = 49,
|
||||
UNSPEC_VABD = 50,
|
||||
UNSPEC_VABDL = 51,
|
||||
UNSPEC_VADD = 52,
|
||||
UNSPEC_VADDHN = 53,
|
||||
UNSPEC_VADDL = 54,
|
||||
UNSPEC_VADDW = 55,
|
||||
UNSPEC_VBSL = 56,
|
||||
UNSPEC_VCAGE = 57,
|
||||
UNSPEC_VCAGT = 58,
|
||||
UNSPEC_VCEQ = 59,
|
||||
UNSPEC_VCGE = 60,
|
||||
UNSPEC_VCGEU = 61,
|
||||
UNSPEC_VCGT = 62,
|
||||
UNSPEC_VCGTU = 63,
|
||||
UNSPEC_VCLS = 64,
|
||||
UNSPEC_VCONCAT = 65,
|
||||
UNSPEC_VCVT = 66,
|
||||
UNSPEC_VCVT_N = 67,
|
||||
UNSPEC_VEXT = 68,
|
||||
UNSPEC_VHADD = 69,
|
||||
UNSPEC_VHSUB = 70,
|
||||
UNSPEC_VLD1 = 71,
|
||||
UNSPEC_VLD1_LANE = 72,
|
||||
UNSPEC_VLD2 = 73,
|
||||
UNSPEC_VLD2_DUP = 74,
|
||||
UNSPEC_VLD2_LANE = 75,
|
||||
UNSPEC_VLD3 = 76,
|
||||
UNSPEC_VLD3A = 77,
|
||||
UNSPEC_VLD3B = 78,
|
||||
UNSPEC_VLD3_DUP = 79,
|
||||
UNSPEC_VLD3_LANE = 80,
|
||||
UNSPEC_VLD4 = 81,
|
||||
UNSPEC_VLD4A = 82,
|
||||
UNSPEC_VLD4B = 83,
|
||||
UNSPEC_VLD4_DUP = 84,
|
||||
UNSPEC_VLD4_LANE = 85,
|
||||
UNSPEC_VMAX = 86,
|
||||
UNSPEC_VMIN = 87,
|
||||
UNSPEC_VMLA = 88,
|
||||
UNSPEC_VMLAL = 89,
|
||||
UNSPEC_VMLA_LANE = 90,
|
||||
UNSPEC_VMLAL_LANE = 91,
|
||||
UNSPEC_VMLS = 92,
|
||||
UNSPEC_VMLSL = 93,
|
||||
UNSPEC_VMLS_LANE = 94,
|
||||
UNSPEC_VMLSL_LANE = 95,
|
||||
UNSPEC_VMOVL = 96,
|
||||
UNSPEC_VMOVN = 97,
|
||||
UNSPEC_VMUL = 98,
|
||||
UNSPEC_VMULL = 99,
|
||||
UNSPEC_VMUL_LANE = 100,
|
||||
UNSPEC_VMULL_LANE = 101,
|
||||
UNSPEC_VPADAL = 102,
|
||||
UNSPEC_VPADD = 103,
|
||||
UNSPEC_VPADDL = 104,
|
||||
UNSPEC_VPMAX = 105,
|
||||
UNSPEC_VPMIN = 106,
|
||||
UNSPEC_VPSMAX = 107,
|
||||
UNSPEC_VPSMIN = 108,
|
||||
UNSPEC_VPUMAX = 109,
|
||||
UNSPEC_VPUMIN = 110,
|
||||
UNSPEC_VQABS = 111,
|
||||
UNSPEC_VQADD = 112,
|
||||
UNSPEC_VQDMLAL = 113,
|
||||
UNSPEC_VQDMLAL_LANE = 114,
|
||||
UNSPEC_VQDMLSL = 115,
|
||||
UNSPEC_VQDMLSL_LANE = 116,
|
||||
UNSPEC_VQDMULH = 117,
|
||||
UNSPEC_VQDMULH_LANE = 118,
|
||||
UNSPEC_VQDMULL = 119,
|
||||
UNSPEC_VQDMULL_LANE = 120,
|
||||
UNSPEC_VQMOVN = 121,
|
||||
UNSPEC_VQMOVUN = 122,
|
||||
UNSPEC_VQNEG = 123,
|
||||
UNSPEC_VQSHL = 124,
|
||||
UNSPEC_VQSHL_N = 125,
|
||||
UNSPEC_VQSHLU_N = 126,
|
||||
UNSPEC_VQSHRN_N = 127,
|
||||
UNSPEC_VQSHRUN_N = 128,
|
||||
UNSPEC_VQSUB = 129,
|
||||
UNSPEC_VRECPE = 130,
|
||||
UNSPEC_VRECPS = 131,
|
||||
UNSPEC_VREV16 = 132,
|
||||
UNSPEC_VREV32 = 133,
|
||||
UNSPEC_VREV64 = 134,
|
||||
UNSPEC_VRSQRTE = 135,
|
||||
UNSPEC_VRSQRTS = 136,
|
||||
UNSPEC_VSHL = 137,
|
||||
UNSPEC_VSHLL_N = 138,
|
||||
UNSPEC_VSHL_N = 139,
|
||||
UNSPEC_VSHR_N = 140,
|
||||
UNSPEC_VSHRN_N = 141,
|
||||
UNSPEC_VSLI = 142,
|
||||
UNSPEC_VSRA_N = 143,
|
||||
UNSPEC_VSRI = 144,
|
||||
UNSPEC_VST1 = 145,
|
||||
UNSPEC_VST1_LANE = 146,
|
||||
UNSPEC_VST2 = 147,
|
||||
UNSPEC_VST2_LANE = 148,
|
||||
UNSPEC_VST3 = 149,
|
||||
UNSPEC_VST3A = 150,
|
||||
UNSPEC_VST3B = 151,
|
||||
UNSPEC_VST3_LANE = 152,
|
||||
UNSPEC_VST4 = 153,
|
||||
UNSPEC_VST4A = 154,
|
||||
UNSPEC_VST4B = 155,
|
||||
UNSPEC_VST4_LANE = 156,
|
||||
UNSPEC_VSTRUCTDUMMY = 157,
|
||||
UNSPEC_VSUB = 158,
|
||||
UNSPEC_VSUBHN = 159,
|
||||
UNSPEC_VSUBL = 160,
|
||||
UNSPEC_VSUBW = 161,
|
||||
UNSPEC_VTBL = 162,
|
||||
UNSPEC_VTBX = 163,
|
||||
UNSPEC_VTRN1 = 164,
|
||||
UNSPEC_VTRN2 = 165,
|
||||
UNSPEC_VTST = 166,
|
||||
UNSPEC_VUZP1 = 167,
|
||||
UNSPEC_VUZP2 = 168,
|
||||
UNSPEC_VZIP1 = 169,
|
||||
UNSPEC_VZIP2 = 170,
|
||||
UNSPEC_MISALIGNED_ACCESS = 171,
|
||||
UNSPEC_VCLE = 172,
|
||||
UNSPEC_VCLT = 173,
|
||||
UNSPEC_NVRINTZ = 174,
|
||||
UNSPEC_NVRINTP = 175,
|
||||
UNSPEC_NVRINTM = 176,
|
||||
UNSPEC_NVRINTX = 177,
|
||||
UNSPEC_NVRINTA = 178,
|
||||
UNSPEC_NVRINTN = 179
|
||||
};
|
||||
#define NUM_UNSPEC_VALUES 180
|
||||
extern const char *const unspec_strings[];
|
||||
|
||||
enum unspecv {
|
||||
VUNSPEC_BLOCKAGE = 0,
|
||||
VUNSPEC_EPILOGUE = 1,
|
||||
VUNSPEC_THUMB1_INTERWORK = 2,
|
||||
VUNSPEC_ALIGN = 3,
|
||||
VUNSPEC_POOL_END = 4,
|
||||
VUNSPEC_POOL_1 = 5,
|
||||
VUNSPEC_POOL_2 = 6,
|
||||
VUNSPEC_POOL_4 = 7,
|
||||
VUNSPEC_POOL_8 = 8,
|
||||
VUNSPEC_POOL_16 = 9,
|
||||
VUNSPEC_TMRC = 10,
|
||||
VUNSPEC_TMCR = 11,
|
||||
VUNSPEC_ALIGN8 = 12,
|
||||
VUNSPEC_WCMP_EQ = 13,
|
||||
VUNSPEC_WCMP_GTU = 14,
|
||||
VUNSPEC_WCMP_GT = 15,
|
||||
VUNSPEC_EH_RETURN = 16,
|
||||
VUNSPEC_ATOMIC_CAS = 17,
|
||||
VUNSPEC_ATOMIC_XCHG = 18,
|
||||
VUNSPEC_ATOMIC_OP = 19,
|
||||
VUNSPEC_LL = 20,
|
||||
VUNSPEC_SC = 21
|
||||
};
|
||||
#define NUM_UNSPECV_VALUES 22
|
||||
extern const char *const unspecv_strings[];
|
||||
|
||||
#endif /* GCC_INSN_CONSTANTS_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,163 @@
|
|||
/* Generated automatically from machmode.def and config/arm/arm-modes.def
|
||||
by genmodes. */
|
||||
|
||||
#ifndef GCC_INSN_MODES_H
|
||||
#define GCC_INSN_MODES_H
|
||||
|
||||
enum machine_mode
|
||||
{
|
||||
VOIDmode, /* machmode.def:172 */
|
||||
BLKmode, /* machmode.def:176 */
|
||||
CCmode, /* machmode.def:204 */
|
||||
CC_NOOVmode, /* config/arm/arm-modes.def:46 */
|
||||
CC_Zmode, /* config/arm/arm-modes.def:47 */
|
||||
CC_CZmode, /* config/arm/arm-modes.def:48 */
|
||||
CC_NCVmode, /* config/arm/arm-modes.def:49 */
|
||||
CC_SWPmode, /* config/arm/arm-modes.def:50 */
|
||||
CCFPmode, /* config/arm/arm-modes.def:51 */
|
||||
CCFPEmode, /* config/arm/arm-modes.def:52 */
|
||||
CC_DNEmode, /* config/arm/arm-modes.def:53 */
|
||||
CC_DEQmode, /* config/arm/arm-modes.def:54 */
|
||||
CC_DLEmode, /* config/arm/arm-modes.def:55 */
|
||||
CC_DLTmode, /* config/arm/arm-modes.def:56 */
|
||||
CC_DGEmode, /* config/arm/arm-modes.def:57 */
|
||||
CC_DGTmode, /* config/arm/arm-modes.def:58 */
|
||||
CC_DLEUmode, /* config/arm/arm-modes.def:59 */
|
||||
CC_DLTUmode, /* config/arm/arm-modes.def:60 */
|
||||
CC_DGEUmode, /* config/arm/arm-modes.def:61 */
|
||||
CC_DGTUmode, /* config/arm/arm-modes.def:62 */
|
||||
CC_Cmode, /* config/arm/arm-modes.def:63 */
|
||||
CC_Nmode, /* config/arm/arm-modes.def:64 */
|
||||
BImode, /* machmode.def:179 */
|
||||
QImode, /* machmode.def:184 */
|
||||
HImode, /* machmode.def:185 */
|
||||
SImode, /* machmode.def:186 */
|
||||
DImode, /* machmode.def:187 */
|
||||
TImode, /* machmode.def:188 */
|
||||
EImode, /* config/arm/arm-modes.def:81 */
|
||||
OImode, /* config/arm/arm-modes.def:82 */
|
||||
CImode, /* config/arm/arm-modes.def:83 */
|
||||
XImode, /* config/arm/arm-modes.def:84 */
|
||||
QQmode, /* machmode.def:207 */
|
||||
HQmode, /* machmode.def:208 */
|
||||
SQmode, /* machmode.def:209 */
|
||||
DQmode, /* machmode.def:210 */
|
||||
TQmode, /* machmode.def:211 */
|
||||
UQQmode, /* machmode.def:213 */
|
||||
UHQmode, /* machmode.def:214 */
|
||||
USQmode, /* machmode.def:215 */
|
||||
UDQmode, /* machmode.def:216 */
|
||||
UTQmode, /* machmode.def:217 */
|
||||
HAmode, /* machmode.def:219 */
|
||||
SAmode, /* machmode.def:220 */
|
||||
DAmode, /* machmode.def:221 */
|
||||
TAmode, /* machmode.def:222 */
|
||||
UHAmode, /* machmode.def:224 */
|
||||
USAmode, /* machmode.def:225 */
|
||||
UDAmode, /* machmode.def:226 */
|
||||
UTAmode, /* machmode.def:227 */
|
||||
HFmode, /* config/arm/arm-modes.def:29 */
|
||||
SFmode, /* machmode.def:199 */
|
||||
DFmode, /* machmode.def:200 */
|
||||
XFmode, /* config/arm/arm-modes.def:26 */
|
||||
SDmode, /* machmode.def:239 */
|
||||
DDmode, /* machmode.def:240 */
|
||||
TDmode, /* machmode.def:241 */
|
||||
CQImode, /* machmode.def:235 */
|
||||
CHImode, /* machmode.def:235 */
|
||||
CSImode, /* machmode.def:235 */
|
||||
CDImode, /* machmode.def:235 */
|
||||
CTImode, /* machmode.def:235 */
|
||||
CEImode, /* machmode.def:235 */
|
||||
COImode, /* machmode.def:235 */
|
||||
CCImode, /* machmode.def:235 */
|
||||
CXImode, /* machmode.def:235 */
|
||||
HCmode, /* machmode.def:236 */
|
||||
SCmode, /* machmode.def:236 */
|
||||
DCmode, /* machmode.def:236 */
|
||||
XCmode, /* machmode.def:236 */
|
||||
V4QImode, /* config/arm/arm-modes.def:67 */
|
||||
V2HImode, /* config/arm/arm-modes.def:67 */
|
||||
V8QImode, /* config/arm/arm-modes.def:68 */
|
||||
V4HImode, /* config/arm/arm-modes.def:68 */
|
||||
V2SImode, /* config/arm/arm-modes.def:68 */
|
||||
V16QImode, /* config/arm/arm-modes.def:69 */
|
||||
V8HImode, /* config/arm/arm-modes.def:69 */
|
||||
V4SImode, /* config/arm/arm-modes.def:69 */
|
||||
V2DImode, /* config/arm/arm-modes.def:69 */
|
||||
V4QQmode, /* config/arm/arm-modes.def:74 */
|
||||
V2HQmode, /* config/arm/arm-modes.def:74 */
|
||||
V4UQQmode, /* config/arm/arm-modes.def:75 */
|
||||
V2UHQmode, /* config/arm/arm-modes.def:75 */
|
||||
V2HAmode, /* config/arm/arm-modes.def:76 */
|
||||
V2UHAmode, /* config/arm/arm-modes.def:77 */
|
||||
V4HFmode, /* config/arm/arm-modes.def:70 */
|
||||
V2SFmode, /* config/arm/arm-modes.def:70 */
|
||||
V8HFmode, /* config/arm/arm-modes.def:71 */
|
||||
V4SFmode, /* config/arm/arm-modes.def:71 */
|
||||
V2DFmode, /* config/arm/arm-modes.def:71 */
|
||||
MAX_MACHINE_MODE,
|
||||
|
||||
MIN_MODE_RANDOM = VOIDmode,
|
||||
MAX_MODE_RANDOM = BLKmode,
|
||||
|
||||
MIN_MODE_CC = CCmode,
|
||||
MAX_MODE_CC = CC_Nmode,
|
||||
|
||||
MIN_MODE_INT = QImode,
|
||||
MAX_MODE_INT = XImode,
|
||||
|
||||
MIN_MODE_PARTIAL_INT = VOIDmode,
|
||||
MAX_MODE_PARTIAL_INT = VOIDmode,
|
||||
|
||||
MIN_MODE_FRACT = QQmode,
|
||||
MAX_MODE_FRACT = TQmode,
|
||||
|
||||
MIN_MODE_UFRACT = UQQmode,
|
||||
MAX_MODE_UFRACT = UTQmode,
|
||||
|
||||
MIN_MODE_ACCUM = HAmode,
|
||||
MAX_MODE_ACCUM = TAmode,
|
||||
|
||||
MIN_MODE_UACCUM = UHAmode,
|
||||
MAX_MODE_UACCUM = UTAmode,
|
||||
|
||||
MIN_MODE_FLOAT = HFmode,
|
||||
MAX_MODE_FLOAT = XFmode,
|
||||
|
||||
MIN_MODE_DECIMAL_FLOAT = SDmode,
|
||||
MAX_MODE_DECIMAL_FLOAT = TDmode,
|
||||
|
||||
MIN_MODE_COMPLEX_INT = CQImode,
|
||||
MAX_MODE_COMPLEX_INT = CXImode,
|
||||
|
||||
MIN_MODE_COMPLEX_FLOAT = HCmode,
|
||||
MAX_MODE_COMPLEX_FLOAT = XCmode,
|
||||
|
||||
MIN_MODE_VECTOR_INT = V4QImode,
|
||||
MAX_MODE_VECTOR_INT = V2DImode,
|
||||
|
||||
MIN_MODE_VECTOR_FRACT = V4QQmode,
|
||||
MAX_MODE_VECTOR_FRACT = V2HQmode,
|
||||
|
||||
MIN_MODE_VECTOR_UFRACT = V4UQQmode,
|
||||
MAX_MODE_VECTOR_UFRACT = V2UHQmode,
|
||||
|
||||
MIN_MODE_VECTOR_ACCUM = V2HAmode,
|
||||
MAX_MODE_VECTOR_ACCUM = V2HAmode,
|
||||
|
||||
MIN_MODE_VECTOR_UACCUM = V2UHAmode,
|
||||
MAX_MODE_VECTOR_UACCUM = V2UHAmode,
|
||||
|
||||
MIN_MODE_VECTOR_FLOAT = V4HFmode,
|
||||
MAX_MODE_VECTOR_FLOAT = V2DFmode,
|
||||
|
||||
NUM_MACHINE_MODES = MAX_MACHINE_MODE
|
||||
};
|
||||
|
||||
#define CONST_MODE_SIZE const
|
||||
#define CONST_MODE_BASE_ALIGN const
|
||||
#define CONST_MODE_IBIT const
|
||||
#define CONST_MODE_FBIT const
|
||||
|
||||
#endif /* insn-modes.h */
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/* Insn note definitions.
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This file defines all the codes that may appear in the
|
||||
NOTE_LINE_NUMBER field of a NOTE insn for kinds of notes that are
|
||||
not line numbers. Source files define DEF_INSN_NOTE appropriately
|
||||
before including this file.
|
||||
|
||||
We are slowly removing the concept of insn-chain notes from the
|
||||
compiler. Adding new codes to this file is STRONGLY DISCOURAGED.
|
||||
If you think you need one, look for other ways to express what you
|
||||
mean, such as register notes or bits in the basic-block structure. */
|
||||
|
||||
/* Shorthand. */
|
||||
#define INSN_NOTE(NAME) DEF_INSN_NOTE (NOTE_INSN_##NAME)
|
||||
|
||||
/* This note is used to get rid of an insn when it isn't safe to patch
|
||||
the insn out of the chain. */
|
||||
INSN_NOTE (DELETED)
|
||||
|
||||
/* Generated in place of user-declared labels when they are deleted. */
|
||||
INSN_NOTE (DELETED_LABEL)
|
||||
/* Similarly, but for labels that have been present in debug stmts
|
||||
earlier and thus will only appear with -g. These must use different
|
||||
label namespace. */
|
||||
INSN_NOTE (DELETED_DEBUG_LABEL)
|
||||
|
||||
/* These are used to mark the beginning and end of a lexical block.
|
||||
See NOTE_BLOCK and reorder_blocks. */
|
||||
INSN_NOTE (BLOCK_BEG)
|
||||
INSN_NOTE (BLOCK_END)
|
||||
|
||||
/* This note indicates the start of the real body of the function,
|
||||
i.e. the point just after all of the parms have been moved into
|
||||
their homes, etc. */
|
||||
INSN_NOTE (FUNCTION_BEG)
|
||||
|
||||
/* This marks the point immediately after the last prologue insn. */
|
||||
INSN_NOTE (PROLOGUE_END)
|
||||
|
||||
/* This marks the point immediately prior to the first epilogue insn. */
|
||||
INSN_NOTE (EPILOGUE_BEG)
|
||||
|
||||
/* These note where exception handling regions begin and end.
|
||||
Uses NOTE_EH_HANDLER to identify the region in question. */
|
||||
INSN_NOTE (EH_REGION_BEG)
|
||||
INSN_NOTE (EH_REGION_END)
|
||||
|
||||
/* The location of a variable. */
|
||||
INSN_NOTE (VAR_LOCATION)
|
||||
|
||||
/* The values passed to callee. */
|
||||
INSN_NOTE (CALL_ARG_LOCATION)
|
||||
|
||||
/* Record the struct for the following basic block. Uses
|
||||
NOTE_BASIC_BLOCK. FIXME: Redundant with the basic block pointer
|
||||
now included in every insn. NOTE: If there's no CFG anymore, in other words,
|
||||
if BLOCK_FOR_INSN () == NULL, NOTE_BASIC_BLOCK cannot be considered reliable
|
||||
anymore. */
|
||||
INSN_NOTE (BASIC_BLOCK)
|
||||
|
||||
/* Mark the inflection point in the instruction stream where we switch
|
||||
between hot and cold text sections. */
|
||||
INSN_NOTE (SWITCH_TEXT_SECTIONS)
|
||||
|
||||
/* When emitting dwarf2 frame information, contains a directive that
|
||||
should be emitted. */
|
||||
INSN_NOTE (CFI)
|
||||
|
||||
/* When emitting dwarf2 frame information, contains the number of a debug
|
||||
label that should be emitted. */
|
||||
INSN_NOTE (CFI_LABEL)
|
||||
|
||||
#undef INSN_NOTE
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* Internal functions.
|
||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This file specifies a list of internal "functions". These functions
|
||||
differ from built-in functions in that they have no linkage and cannot
|
||||
be called directly by the user. They represent operations that are only
|
||||
synthesised by GCC itself.
|
||||
|
||||
Internal functions are used instead of tree codes if the operation
|
||||
and its operands are more naturally represented as a GIMPLE_CALL
|
||||
than a GIMPLE_ASSIGN.
|
||||
|
||||
Each entry in this file has the form:
|
||||
|
||||
DEF_INTERNAL_FN (NAME, FLAGS)
|
||||
|
||||
where NAME is the name of the function and FLAGS is a set of
|
||||
ECF_* flags. Each entry must have a corresponding expander
|
||||
of the form:
|
||||
|
||||
void expand_NAME (gimple stmt)
|
||||
|
||||
where STMT is the statement that performs the call. */
|
||||
|
||||
DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF)
|
||||
DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* Internal functions.
|
||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_INTERNAL_FN_H
|
||||
#define GCC_INTERNAL_FN_H
|
||||
|
||||
enum internal_fn {
|
||||
#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE,
|
||||
#include "internal-fn.def"
|
||||
#undef DEF_INTERNAL_FN
|
||||
IFN_LAST
|
||||
};
|
||||
|
||||
/* Return the name of internal function FN. The name is only meaningful
|
||||
for dumps; it has no linkage. */
|
||||
|
||||
extern const char *const internal_fn_name_array[];
|
||||
|
||||
static inline const char *
|
||||
internal_fn_name (enum internal_fn fn)
|
||||
{
|
||||
return internal_fn_name_array[(int) fn];
|
||||
}
|
||||
|
||||
/* Return the ECF_* flags for function FN. */
|
||||
|
||||
extern const int internal_fn_flags_array[];
|
||||
|
||||
static inline int
|
||||
internal_fn_flags (enum internal_fn fn)
|
||||
{
|
||||
return internal_fn_flags_array[(int) fn];
|
||||
}
|
||||
|
||||
extern void expand_internal_call (gimple);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* intl.h - internationalization
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_INTL_H
|
||||
#define GCC_INTL_H
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETLOCALE
|
||||
# define setlocale(category, locale) (locale)
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
#include <libintl.h>
|
||||
extern void gcc_init_libintl (void);
|
||||
extern size_t gcc_gettext_width (const char *);
|
||||
#else
|
||||
/* Stubs. */
|
||||
# undef textdomain
|
||||
# define textdomain(domain) (domain)
|
||||
# undef bindtextdomain
|
||||
# define bindtextdomain(domain, directory) (domain)
|
||||
# undef gettext
|
||||
# define gettext(msgid) (msgid)
|
||||
# define ngettext(singular,plural,n) fake_ngettext(singular,plural,n)
|
||||
# define gcc_init_libintl() /* nothing */
|
||||
# define gcc_gettext_width(s) strlen(s)
|
||||
|
||||
extern const char *fake_ngettext(const char *singular,const char *plural,
|
||||
unsigned long int n);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
# define _(msgid) gettext (msgid)
|
||||
#endif
|
||||
|
||||
#ifndef N_
|
||||
# define N_(msgid) msgid
|
||||
#endif
|
||||
|
||||
#ifndef G_
|
||||
# define G_(gmsgid) gmsgid
|
||||
#endif
|
||||
|
||||
extern char *get_spaces (const char *);
|
||||
|
||||
extern const char *open_quote;
|
||||
extern const char *close_quote;
|
||||
extern const char *locale_encoding;
|
||||
extern bool locale_utf8;
|
||||
|
||||
#endif /* intl.h */
|
||||
|
|
@ -0,0 +1,619 @@
|
|||
/* Interprocedural analyses.
|
||||
Copyright (C) 2005-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef IPA_PROP_H
|
||||
#define IPA_PROP_H
|
||||
|
||||
#include "tree.h"
|
||||
#include "vec.h"
|
||||
#include "cgraph.h"
|
||||
#include "gimple.h"
|
||||
#include "alloc-pool.h"
|
||||
|
||||
/* The following definitions and interfaces are used by
|
||||
interprocedural analyses or parameters. */
|
||||
|
||||
/* ipa-prop.c stuff (ipa-cp, indirect inlining): */
|
||||
|
||||
/* A jump function for a callsite represents the values passed as actual
|
||||
arguments of the callsite. They were originally proposed in a paper called
|
||||
"Interprocedural Constant Propagation", by David Callahan, Keith D Cooper,
|
||||
Ken Kennedy, Linda Torczon in Comp86, pg 152-161. There are three main
|
||||
types of values :
|
||||
|
||||
Pass-through - the caller's formal parameter is passed as an actual
|
||||
argument, possibly one simple operation performed on it.
|
||||
Constant - a constant (is_gimple_ip_invariant)is passed as an actual
|
||||
argument.
|
||||
Unknown - neither of the above.
|
||||
|
||||
IPA_JF_ANCESTOR is a special pass-through jump function, which means that
|
||||
the result is an address of a part of the object pointed to by the formal
|
||||
parameter to which the function refers. It is mainly intended to represent
|
||||
getting addresses of of ancestor fields in C++
|
||||
(e.g. &this_1(D)->D.1766.D.1756). Note that if the original pointer is
|
||||
NULL, ancestor jump function must behave like a simple pass-through.
|
||||
|
||||
Other pass-through functions can either simply pass on an unchanged formal
|
||||
parameter or can apply one simple binary operation to it (such jump
|
||||
functions are called polynomial).
|
||||
|
||||
IPA_JF_KNOWN_TYPE is a special type of an "unknown" function that applies
|
||||
only to pointer parameters. It means that even though we cannot prove that
|
||||
the passed value is an interprocedural constant, we still know the exact
|
||||
type of the containing object which may be valuable for devirtualization.
|
||||
|
||||
Jump functions are computed in ipa-prop.c by function
|
||||
update_call_notes_after_inlining. Some information can be lost and jump
|
||||
functions degraded accordingly when inlining, see
|
||||
update_call_notes_after_inlining in the same file. */
|
||||
|
||||
enum jump_func_type
|
||||
{
|
||||
IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
|
||||
IPA_JF_KNOWN_TYPE, /* represented by field known_type */
|
||||
IPA_JF_CONST, /* represented by field costant */
|
||||
IPA_JF_PASS_THROUGH, /* represented by field pass_through */
|
||||
IPA_JF_ANCESTOR /* represented by field ancestor */
|
||||
};
|
||||
|
||||
/* Structure holding data required to describe a known type jump function. */
|
||||
struct GTY(()) ipa_known_type_data
|
||||
{
|
||||
/* Offset of the component of the base_type being described. */
|
||||
HOST_WIDE_INT offset;
|
||||
/* Type of the whole object. */
|
||||
tree base_type;
|
||||
/* Type of the component of the object that is being described. */
|
||||
tree component_type;
|
||||
};
|
||||
|
||||
/* Structure holding data required to describe a pass-through jump function. */
|
||||
|
||||
struct GTY(()) ipa_pass_through_data
|
||||
{
|
||||
/* If an operation is to be performed on the original parameter, this is the
|
||||
second (constant) operand. */
|
||||
tree operand;
|
||||
/* Number of the caller's formal parameter being passed. */
|
||||
int formal_id;
|
||||
/* Operation that is performed on the argument before it is passed on.
|
||||
NOP_EXPR means no operation. Otherwise oper must be a simple binary
|
||||
arithmetic operation where the caller's parameter is the first operand and
|
||||
operand field from this structure is the second one. */
|
||||
enum tree_code operation;
|
||||
/* When the passed value is a pointer, it is set to true only when we are
|
||||
certain that no write to the object it points to has occurred since the
|
||||
caller functions started execution, except for changes noted in the
|
||||
aggregate part of the jump function (see description of
|
||||
ipa_agg_jump_function). The flag is used only when the operation is
|
||||
NOP_EXPR. */
|
||||
bool agg_preserved;
|
||||
};
|
||||
|
||||
/* Structure holding data required to describe an ancestor pass-through
|
||||
jump function. */
|
||||
|
||||
struct GTY(()) ipa_ancestor_jf_data
|
||||
{
|
||||
/* Offset of the field representing the ancestor. */
|
||||
HOST_WIDE_INT offset;
|
||||
/* Type of the result. */
|
||||
tree type;
|
||||
/* Number of the caller's formal parameter being passed. */
|
||||
int formal_id;
|
||||
/* Flag with the same meaning like agg_preserve in ipa_pass_through_data. */
|
||||
bool agg_preserved;
|
||||
};
|
||||
|
||||
/* An element in an aggegate part of a jump function describing a known value
|
||||
at a given offset. When it is part of a pass-through jump function with
|
||||
agg_preserved set or an ancestor jump function with agg_preserved set, all
|
||||
unlisted positions are assumed to be preserved but the value can be a type
|
||||
node, which means that the particular piece (starting at offset and having
|
||||
the size of the type) is clobbered with an unknown value. When
|
||||
agg_preserved is false or the type of the containing jump function is
|
||||
different, all unlisted parts are assumed to be unknown and all values must
|
||||
fullfill is_gimple_ip_invariant. */
|
||||
|
||||
typedef struct GTY(()) ipa_agg_jf_item
|
||||
{
|
||||
/* The offset at which the known value is located within the aggregate. */
|
||||
HOST_WIDE_INT offset;
|
||||
|
||||
/* The known constant or type if this is a clobber. */
|
||||
tree value;
|
||||
} ipa_agg_jf_item_t;
|
||||
|
||||
|
||||
/* Aggregate jump function - i.e. description of contents of aggregates passed
|
||||
either by reference or value. */
|
||||
|
||||
struct GTY(()) ipa_agg_jump_function
|
||||
{
|
||||
/* Description of the individual items. */
|
||||
vec<ipa_agg_jf_item_t, va_gc> *items;
|
||||
/* True if the data was passed by reference (as opposed to by value). */
|
||||
bool by_ref;
|
||||
};
|
||||
|
||||
typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
|
||||
typedef struct ipa_agg_jump_function ipa_agg_jump_function_t;
|
||||
|
||||
/* A jump function for a callsite represents the values passed as actual
|
||||
arguments of the callsite. See enum jump_func_type for the various
|
||||
types of jump functions supported. */
|
||||
typedef struct GTY (()) ipa_jump_func
|
||||
{
|
||||
/* Aggregate contants description. See struct ipa_agg_jump_function and its
|
||||
description. */
|
||||
struct ipa_agg_jump_function agg;
|
||||
|
||||
enum jump_func_type type;
|
||||
/* Represents a value of a jump function. pass_through is used only in jump
|
||||
function context. constant represents the actual constant in constant jump
|
||||
functions and member_cst holds constant c++ member functions. */
|
||||
union jump_func_value
|
||||
{
|
||||
struct ipa_known_type_data GTY ((tag ("IPA_JF_KNOWN_TYPE"))) known_type;
|
||||
tree GTY ((tag ("IPA_JF_CONST"))) constant;
|
||||
struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
|
||||
struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
|
||||
} GTY ((desc ("%1.type"))) value;
|
||||
} ipa_jump_func_t;
|
||||
|
||||
|
||||
/* Return the offset of the component that is decribed by a known type jump
|
||||
function JFUNC. */
|
||||
|
||||
static inline HOST_WIDE_INT
|
||||
ipa_get_jf_known_type_offset (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
|
||||
return jfunc->value.known_type.offset;
|
||||
}
|
||||
|
||||
/* Return the base type of a known type jump function JFUNC. */
|
||||
|
||||
static inline tree
|
||||
ipa_get_jf_known_type_base_type (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
|
||||
return jfunc->value.known_type.base_type;
|
||||
}
|
||||
|
||||
/* Return the component type of a known type jump function JFUNC. */
|
||||
|
||||
static inline tree
|
||||
ipa_get_jf_known_type_component_type (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
|
||||
return jfunc->value.known_type.component_type;
|
||||
}
|
||||
|
||||
/* Return the constant stored in a constant jump functin JFUNC. */
|
||||
|
||||
static inline tree
|
||||
ipa_get_jf_constant (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_CONST);
|
||||
return jfunc->value.constant;
|
||||
}
|
||||
|
||||
/* Return the operand of a pass through jmp function JFUNC. */
|
||||
|
||||
static inline tree
|
||||
ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||
return jfunc->value.pass_through.operand;
|
||||
}
|
||||
|
||||
/* Return the number of the caller's formal parameter that a pass through jump
|
||||
function JFUNC refers to. */
|
||||
|
||||
static inline int
|
||||
ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||
return jfunc->value.pass_through.formal_id;
|
||||
}
|
||||
|
||||
/* Return operation of a pass through jump function JFUNC. */
|
||||
|
||||
static inline enum tree_code
|
||||
ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||
return jfunc->value.pass_through.operation;
|
||||
}
|
||||
|
||||
/* Return the agg_preserved flag of a pass through jump functin JFUNC. */
|
||||
|
||||
static inline bool
|
||||
ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||
return jfunc->value.pass_through.agg_preserved;
|
||||
}
|
||||
|
||||
/* Return the offset of an ancestor jump function JFUNC. */
|
||||
|
||||
static inline HOST_WIDE_INT
|
||||
ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||
return jfunc->value.ancestor.offset;
|
||||
}
|
||||
|
||||
/* Return the result type of an ancestor jump function JFUNC. */
|
||||
|
||||
static inline tree
|
||||
ipa_get_jf_ancestor_type (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||
return jfunc->value.ancestor.type;
|
||||
}
|
||||
|
||||
/* Return the number of the caller's formal parameter that an ancestor jump
|
||||
function JFUNC refers to. */
|
||||
|
||||
static inline int
|
||||
ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||
return jfunc->value.ancestor.formal_id;
|
||||
}
|
||||
|
||||
/* Return the agg_preserved flag of an ancestor jump functin JFUNC. */
|
||||
|
||||
static inline bool
|
||||
ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
|
||||
{
|
||||
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||
return jfunc->value.ancestor.agg_preserved;
|
||||
}
|
||||
|
||||
/* Summary describing a single formal parameter. */
|
||||
|
||||
struct ipa_param_descriptor
|
||||
{
|
||||
/* PARAM_DECL of this parameter. */
|
||||
tree decl;
|
||||
/* The parameter is used. */
|
||||
unsigned used : 1;
|
||||
};
|
||||
|
||||
typedef struct ipa_param_descriptor ipa_param_descriptor_t;
|
||||
struct ipcp_lattice;
|
||||
|
||||
/* ipa_node_params stores information related to formal parameters of functions
|
||||
and some other information for interprocedural passes that operate on
|
||||
parameters (such as ipa-cp). */
|
||||
|
||||
struct ipa_node_params
|
||||
{
|
||||
/* Information about individual formal parameters that are gathered when
|
||||
summaries are generated. */
|
||||
vec<ipa_param_descriptor_t> descriptors;
|
||||
/* Pointer to an array of structures describing individual formal
|
||||
parameters. */
|
||||
struct ipcp_param_lattices *lattices;
|
||||
/* Only for versioned nodes this field would not be NULL,
|
||||
it points to the node that IPA cp cloned from. */
|
||||
struct cgraph_node *ipcp_orig_node;
|
||||
/* If this node is an ipa-cp clone, these are the known values that describe
|
||||
what it has been specialized for. */
|
||||
vec<tree> known_vals;
|
||||
/* Whether the param uses analysis has already been performed. */
|
||||
unsigned uses_analysis_done : 1;
|
||||
/* Whether the function is enqueued in ipa-cp propagation stack. */
|
||||
unsigned node_enqueued : 1;
|
||||
/* Whether we should create a specialized version based on values that are
|
||||
known to be constant in all contexts. */
|
||||
unsigned do_clone_for_all_contexts : 1;
|
||||
/* Set if this is an IPA-CP clone for all contexts. */
|
||||
unsigned is_all_contexts_clone : 1;
|
||||
/* Node has been completely replaced by clones and will be removed after
|
||||
ipa-cp is finished. */
|
||||
unsigned node_dead : 1;
|
||||
};
|
||||
|
||||
/* ipa_node_params access functions. Please use these to access fields that
|
||||
are or will be shared among various passes. */
|
||||
|
||||
/* Return the number of formal parameters. */
|
||||
|
||||
static inline int
|
||||
ipa_get_param_count (struct ipa_node_params *info)
|
||||
{
|
||||
return info->descriptors.length ();
|
||||
}
|
||||
|
||||
/* Return the declaration of Ith formal parameter of the function corresponding
|
||||
to INFO. Note there is no setter function as this array is built just once
|
||||
using ipa_initialize_node_params. */
|
||||
|
||||
static inline tree
|
||||
ipa_get_param (struct ipa_node_params *info, int i)
|
||||
{
|
||||
return info->descriptors[i].decl;
|
||||
}
|
||||
|
||||
/* Set the used flag corresponding to the Ith formal parameter of the function
|
||||
associated with INFO to VAL. */
|
||||
|
||||
static inline void
|
||||
ipa_set_param_used (struct ipa_node_params *info, int i, bool val)
|
||||
{
|
||||
info->descriptors[i].used = val;
|
||||
}
|
||||
|
||||
/* Return the used flag corresponding to the Ith formal parameter of the
|
||||
function associated with INFO. */
|
||||
|
||||
static inline bool
|
||||
ipa_is_param_used (struct ipa_node_params *info, int i)
|
||||
{
|
||||
return info->descriptors[i].used;
|
||||
}
|
||||
|
||||
/* Information about replacements done in aggregates for a given node (each
|
||||
node has its linked list). */
|
||||
struct GTY(()) ipa_agg_replacement_value
|
||||
{
|
||||
/* Next item in the linked list. */
|
||||
struct ipa_agg_replacement_value *next;
|
||||
/* Offset within the aggregate. */
|
||||
HOST_WIDE_INT offset;
|
||||
/* The constant value. */
|
||||
tree value;
|
||||
/* The paramter index. */
|
||||
int index;
|
||||
/* Whether the value was passed by reference. */
|
||||
bool by_ref;
|
||||
};
|
||||
|
||||
typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
|
||||
|
||||
void ipa_set_node_agg_value_chain (struct cgraph_node *node,
|
||||
struct ipa_agg_replacement_value *aggvals);
|
||||
|
||||
/* ipa_edge_args stores information related to a callsite and particularly its
|
||||
arguments. It can be accessed by the IPA_EDGE_REF macro. */
|
||||
typedef struct GTY(()) ipa_edge_args
|
||||
{
|
||||
/* Vector of the callsite's jump function of each parameter. */
|
||||
vec<ipa_jump_func_t, va_gc> *jump_functions;
|
||||
} ipa_edge_args_t;
|
||||
|
||||
/* ipa_edge_args access functions. Please use these to access fields that
|
||||
are or will be shared among various passes. */
|
||||
|
||||
/* Return the number of actual arguments. */
|
||||
|
||||
static inline int
|
||||
ipa_get_cs_argument_count (struct ipa_edge_args *args)
|
||||
{
|
||||
return vec_safe_length (args->jump_functions);
|
||||
}
|
||||
|
||||
/* Returns a pointer to the jump function for the ith argument. Please note
|
||||
there is no setter function as jump functions are all set up in
|
||||
ipa_compute_jump_functions. */
|
||||
|
||||
static inline struct ipa_jump_func *
|
||||
ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
|
||||
{
|
||||
return &(*args->jump_functions)[i];
|
||||
}
|
||||
|
||||
/* Vectors need to have typedefs of structures. */
|
||||
typedef struct ipa_node_params ipa_node_params_t;
|
||||
|
||||
/* Types of vectors holding the infos. */
|
||||
|
||||
/* Vector where the parameter infos are actually stored. */
|
||||
extern vec<ipa_node_params_t> ipa_node_params_vector;
|
||||
/* Vector of known aggregate values in cloned nodes. */
|
||||
extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
|
||||
/* Vector where the parameter infos are actually stored. */
|
||||
extern GTY(()) vec<ipa_edge_args_t, va_gc> *ipa_edge_args_vector;
|
||||
|
||||
/* Return the associated parameter/argument info corresponding to the given
|
||||
node/edge. */
|
||||
#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
|
||||
#define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
|
||||
/* This macro checks validity of index returned by
|
||||
ipa_get_param_decl_index function. */
|
||||
#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
|
||||
|
||||
/* Creating and freeing ipa_node_params and ipa_edge_args. */
|
||||
void ipa_create_all_node_params (void);
|
||||
void ipa_create_all_edge_args (void);
|
||||
void ipa_free_edge_args_substructures (struct ipa_edge_args *);
|
||||
void ipa_free_node_params_substructures (struct ipa_node_params *);
|
||||
void ipa_free_all_node_params (void);
|
||||
void ipa_free_all_edge_args (void);
|
||||
void ipa_free_all_structures_after_ipa_cp (void);
|
||||
void ipa_free_all_structures_after_iinln (void);
|
||||
void ipa_register_cgraph_hooks (void);
|
||||
|
||||
/* This function ensures the array of node param infos is big enough to
|
||||
accommodate a structure for all nodes and reallocates it if not. */
|
||||
|
||||
static inline void
|
||||
ipa_check_create_node_params (void)
|
||||
{
|
||||
if (!ipa_node_params_vector.exists ())
|
||||
ipa_node_params_vector.create (cgraph_max_uid);
|
||||
|
||||
if (ipa_node_params_vector.length () <= (unsigned) cgraph_max_uid)
|
||||
ipa_node_params_vector.safe_grow_cleared (cgraph_max_uid + 1);
|
||||
}
|
||||
|
||||
/* This function ensures the array of edge arguments infos is big enough to
|
||||
accommodate a structure for all edges and reallocates it if not. */
|
||||
|
||||
static inline void
|
||||
ipa_check_create_edge_args (void)
|
||||
{
|
||||
if (vec_safe_length (ipa_edge_args_vector) <= (unsigned) cgraph_edge_max_uid)
|
||||
vec_safe_grow_cleared (ipa_edge_args_vector, cgraph_edge_max_uid + 1);
|
||||
}
|
||||
|
||||
/* Returns true if the array of edge infos is large enough to accommodate an
|
||||
info for EDGE. The main purpose of this function is that debug dumping
|
||||
function can check info availability without causing reallocations. */
|
||||
|
||||
static inline bool
|
||||
ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
|
||||
{
|
||||
return ((unsigned) edge->uid < vec_safe_length (ipa_edge_args_vector));
|
||||
}
|
||||
|
||||
/* Return the aggregate replacements for NODE, if there are any. */
|
||||
|
||||
static inline struct ipa_agg_replacement_value *
|
||||
ipa_get_agg_replacements_for_node (struct cgraph_node *node)
|
||||
{
|
||||
if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
|
||||
return NULL;
|
||||
return (*ipa_node_agg_replacements)[node->uid];
|
||||
}
|
||||
|
||||
/* Function formal parameters related computations. */
|
||||
void ipa_initialize_node_params (struct cgraph_node *node);
|
||||
bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
|
||||
vec<cgraph_edge_p> *new_edges);
|
||||
|
||||
/* Indirect edge and binfo processing. */
|
||||
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
|
||||
vec<tree> ,
|
||||
vec<tree> ,
|
||||
vec<ipa_agg_jump_function_p> );
|
||||
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree);
|
||||
|
||||
/* Functions related to both. */
|
||||
void ipa_analyze_node (struct cgraph_node *);
|
||||
|
||||
/* Aggregate jump function related functions. */
|
||||
tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
|
||||
bool);
|
||||
bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
|
||||
HOST_WIDE_INT *, bool *);
|
||||
|
||||
/* Debugging interface. */
|
||||
void ipa_print_node_params (FILE *, struct cgraph_node *node);
|
||||
void ipa_print_all_params (FILE *);
|
||||
void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
|
||||
void ipa_print_all_jump_functions (FILE * f);
|
||||
void ipcp_verify_propagated_values (void);
|
||||
|
||||
extern alloc_pool ipcp_values_pool;
|
||||
extern alloc_pool ipcp_sources_pool;
|
||||
extern alloc_pool ipcp_agg_lattice_pool;
|
||||
|
||||
/* Structure to describe transformations of formal parameters and actual
|
||||
arguments. Each instance describes one new parameter and they are meant to
|
||||
be stored in a vector. Additionally, most users will probably want to store
|
||||
adjustments about parameters that are being removed altogether so that SSA
|
||||
names belonging to them can be replaced by SSA names of an artificial
|
||||
variable. */
|
||||
struct ipa_parm_adjustment
|
||||
{
|
||||
/* The original PARM_DECL itself, helpful for processing of the body of the
|
||||
function itself. Intended for traversing function bodies.
|
||||
ipa_modify_formal_parameters, ipa_modify_call_arguments and
|
||||
ipa_combine_adjustments ignore this and use base_index.
|
||||
ipa_modify_formal_parameters actually sets this. */
|
||||
tree base;
|
||||
|
||||
/* Type of the new parameter. However, if by_ref is true, the real type will
|
||||
be a pointer to this type. */
|
||||
tree type;
|
||||
|
||||
/* Alias refrerence type to be used in MEM_REFs when adjusting caller
|
||||
arguments. */
|
||||
tree alias_ptr_type;
|
||||
|
||||
/* The new declaration when creating/replacing a parameter. Created by
|
||||
ipa_modify_formal_parameters, useful for functions modifying the body
|
||||
accordingly. */
|
||||
tree reduction;
|
||||
|
||||
/* New declaration of a substitute variable that we may use to replace all
|
||||
non-default-def ssa names when a parm decl is going away. */
|
||||
tree new_ssa_base;
|
||||
|
||||
/* If non-NULL and the original parameter is to be removed (copy_param below
|
||||
is NULL), this is going to be its nonlocalized vars value. */
|
||||
tree nonlocal_value;
|
||||
|
||||
/* Offset into the original parameter (for the cases when the new parameter
|
||||
is a component of an original one). */
|
||||
HOST_WIDE_INT offset;
|
||||
|
||||
/* Zero based index of the original parameter this one is based on. (ATM
|
||||
there is no way to insert a new parameter out of the blue because there is
|
||||
no need but if it arises the code can be easily exteded to do so.) */
|
||||
int base_index;
|
||||
|
||||
/* This new parameter is an unmodified parameter at index base_index. */
|
||||
unsigned copy_param : 1;
|
||||
|
||||
/* This adjustment describes a parameter that is about to be removed
|
||||
completely. Most users will probably need to book keep those so that they
|
||||
don't leave behinfd any non default def ssa names belonging to them. */
|
||||
unsigned remove_param : 1;
|
||||
|
||||
/* The parameter is to be passed by reference. */
|
||||
unsigned by_ref : 1;
|
||||
};
|
||||
|
||||
typedef struct ipa_parm_adjustment ipa_parm_adjustment_t;
|
||||
|
||||
typedef vec<ipa_parm_adjustment_t> ipa_parm_adjustment_vec;
|
||||
|
||||
vec<tree> ipa_get_vector_of_formal_parms (tree fndecl);
|
||||
void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec,
|
||||
const char *);
|
||||
void ipa_modify_call_arguments (struct cgraph_edge *, gimple,
|
||||
ipa_parm_adjustment_vec);
|
||||
ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
|
||||
ipa_parm_adjustment_vec);
|
||||
void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree);
|
||||
void ipa_dump_agg_replacement_values (FILE *f,
|
||||
struct ipa_agg_replacement_value *av);
|
||||
void ipa_prop_write_jump_functions (void);
|
||||
void ipa_prop_read_jump_functions (void);
|
||||
void ipa_prop_write_all_agg_replacement (void);
|
||||
void ipa_prop_read_all_agg_replacement (void);
|
||||
void ipa_update_after_lto_read (void);
|
||||
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
|
||||
tree ipa_value_from_jfunc (struct ipa_node_params *info,
|
||||
struct ipa_jump_func *jfunc);
|
||||
unsigned int ipcp_transform_function (struct cgraph_node *node);
|
||||
|
||||
|
||||
/* From tree-sra.c: */
|
||||
tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
|
||||
gimple_stmt_iterator *, bool);
|
||||
|
||||
#endif /* IPA_PROP_H */
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/* IPA reference lists.
|
||||
Copyright (C) 2010-2013 Free Software Foundation, Inc.
|
||||
Contributed by Jan Hubicka
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Return callgraph node REF is referring. */
|
||||
static inline struct cgraph_node *
|
||||
ipa_ref_node (struct ipa_ref *ref)
|
||||
{
|
||||
return cgraph (ref->referred);
|
||||
}
|
||||
|
||||
/* Return varpool node REF is referring. */
|
||||
|
||||
static inline struct varpool_node *
|
||||
ipa_ref_varpool_node (struct ipa_ref *ref)
|
||||
{
|
||||
return varpool (ref->referred);
|
||||
}
|
||||
|
||||
/* Return cgraph node REF is in. */
|
||||
|
||||
static inline struct cgraph_node *
|
||||
ipa_ref_referring_node (struct ipa_ref *ref)
|
||||
{
|
||||
return cgraph (ref->referring);
|
||||
}
|
||||
|
||||
/* Return varpool node REF is in. */
|
||||
|
||||
static inline struct varpool_node *
|
||||
ipa_ref_referring_varpool_node (struct ipa_ref *ref)
|
||||
{
|
||||
return varpool (ref->referring);
|
||||
}
|
||||
|
||||
/* Return reference list REF is in. */
|
||||
|
||||
static inline struct ipa_ref_list *
|
||||
ipa_ref_referring_ref_list (struct ipa_ref *ref)
|
||||
{
|
||||
return &ref->referring->symbol.ref_list;
|
||||
}
|
||||
|
||||
/* Return reference list REF is in. */
|
||||
|
||||
static inline struct ipa_ref_list *
|
||||
ipa_ref_referred_ref_list (struct ipa_ref *ref)
|
||||
{
|
||||
return &ref->referred->symbol.ref_list;
|
||||
}
|
||||
|
||||
/* Return first reference in LIST or NULL if empty. */
|
||||
|
||||
static inline struct ipa_ref *
|
||||
ipa_ref_list_first_reference (struct ipa_ref_list *list)
|
||||
{
|
||||
if (!vec_safe_length (list->references))
|
||||
return NULL;
|
||||
return &(*list->references)[0];
|
||||
}
|
||||
|
||||
/* Return first referring ref in LIST or NULL if empty. */
|
||||
|
||||
static inline struct ipa_ref *
|
||||
ipa_ref_list_first_referring (struct ipa_ref_list *list)
|
||||
{
|
||||
if (!list->referring.length ())
|
||||
return NULL;
|
||||
return list->referring[0];
|
||||
}
|
||||
|
||||
/* Clear reference list. */
|
||||
|
||||
static inline void
|
||||
ipa_empty_ref_list (struct ipa_ref_list *list)
|
||||
{
|
||||
list->referring.create (0);
|
||||
list->references = NULL;
|
||||
}
|
||||
|
||||
/* Clear reference list. */
|
||||
|
||||
static inline unsigned int
|
||||
ipa_ref_list_nreferences (struct ipa_ref_list *list)
|
||||
{
|
||||
return vec_safe_length (list->references);
|
||||
}
|
||||
|
||||
#define ipa_ref_list_reference_iterate(L,I,P) \
|
||||
vec_safe_iterate ((L)->references, (I), &(P))
|
||||
#define ipa_ref_list_referring_iterate(L,I,P) \
|
||||
(L)->referring.iterate ((I), &(P))
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* IPA reference lists.
|
||||
Copyright (C) 2010-2013 Free Software Foundation, Inc.
|
||||
Contributed by Jan Hubicka
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
struct cgraph_node;
|
||||
struct varpool_node;
|
||||
union symtab_node_def;
|
||||
typedef union symtab_node_def *symtab_node;
|
||||
typedef const union symtab_node_def *const_symtab_node;
|
||||
|
||||
|
||||
/* How the reference is done. */
|
||||
enum GTY(()) ipa_ref_use
|
||||
{
|
||||
IPA_REF_LOAD,
|
||||
IPA_REF_STORE,
|
||||
IPA_REF_ADDR,
|
||||
IPA_REF_ALIAS
|
||||
};
|
||||
|
||||
/* Record of reference in callgraph or varpool. */
|
||||
struct GTY(()) ipa_ref
|
||||
{
|
||||
symtab_node referring;
|
||||
symtab_node referred;
|
||||
gimple stmt;
|
||||
unsigned int referred_index;
|
||||
ENUM_BITFIELD (ipa_ref_use) use:2;
|
||||
};
|
||||
|
||||
typedef struct ipa_ref ipa_ref_t;
|
||||
typedef struct ipa_ref *ipa_ref_ptr;
|
||||
|
||||
|
||||
/* List of references. This is stored in both callgraph and varpool nodes. */
|
||||
struct GTY(()) ipa_ref_list
|
||||
{
|
||||
/* Store actual references in references vector. */
|
||||
vec<ipa_ref_t, va_gc> *references;
|
||||
/* Referring is vector of pointers to references. It must not live in GGC space
|
||||
or GGC will try to mark middle of references vectors. */
|
||||
vec<ipa_ref_ptr> GTY((skip)) referring;
|
||||
};
|
||||
|
||||
struct ipa_ref * ipa_record_reference (symtab_node,
|
||||
symtab_node,
|
||||
enum ipa_ref_use, gimple);
|
||||
|
||||
void ipa_remove_reference (struct ipa_ref *);
|
||||
void ipa_remove_all_references (struct ipa_ref_list *);
|
||||
void ipa_remove_all_referring (struct ipa_ref_list *);
|
||||
void ipa_dump_references (FILE *, struct ipa_ref_list *);
|
||||
void ipa_dump_referring (FILE *, struct ipa_ref_list *);
|
||||
void ipa_clone_references (symtab_node, struct ipa_ref_list *);
|
||||
void ipa_clone_referring (symtab_node, struct ipa_ref_list *);
|
||||
bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
|
||||
bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* IPA handling of references.
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_IPA_REFERENCE_H
|
||||
#define GCC_IPA_REFERENCE_H
|
||||
#include "bitmap.h"
|
||||
#include "tree.h"
|
||||
|
||||
/* In ipa-reference.c */
|
||||
bitmap ipa_reference_get_not_read_global (struct cgraph_node *fn);
|
||||
bitmap ipa_reference_get_not_written_global (struct cgraph_node *fn);
|
||||
|
||||
#endif /* GCC_IPA_REFERENCE_H */
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* Utilities for ipa analysis.
|
||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_IPA_UTILS_H
|
||||
#define GCC_IPA_UTILS_H
|
||||
#include "tree.h"
|
||||
#include "cgraph.h"
|
||||
|
||||
struct ipa_dfs_info {
|
||||
int dfn_number;
|
||||
int low_link;
|
||||
/* This field will have the samy value for any two nodes in the same strongly
|
||||
connected component. */
|
||||
int scc_no;
|
||||
bool new_node;
|
||||
bool on_stack;
|
||||
struct cgraph_node* next_cycle;
|
||||
PTR aux;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* In ipa-utils.c */
|
||||
void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);
|
||||
int ipa_reduced_postorder (struct cgraph_node **, bool, bool,
|
||||
bool (*ignore_edge) (struct cgraph_edge *));
|
||||
void ipa_free_postorder_info (void);
|
||||
vec<cgraph_node_ptr> ipa_get_nodes_in_cycle (struct cgraph_node *);
|
||||
int ipa_reverse_postorder (struct cgraph_node **);
|
||||
tree get_base_var (tree);
|
||||
|
||||
|
||||
#endif /* GCC_IPA_UTILS_H */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
/* Dynamic testing for abstract is-a relationships.
|
||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
Contributed by Lawrence Crowl.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* This header generic type query and conversion functions.
|
||||
|
||||
|
||||
USING THE GENERIC TYPE FACILITY
|
||||
|
||||
|
||||
The user functions are:
|
||||
|
||||
bool is_a <TYPE> (pointer)
|
||||
|
||||
Tests whether the pointer actually points to a more derived TYPE.
|
||||
|
||||
Suppose you have a symtab_node_def *ptr, AKA symtab_node ptr. You can test
|
||||
whether it points to a 'derived' cgraph_node as follows.
|
||||
|
||||
if (is_a <cgraph_node> (ptr))
|
||||
....
|
||||
|
||||
|
||||
TYPE *as_a <TYPE> (pointer)
|
||||
|
||||
Converts pointer to a TYPE*.
|
||||
|
||||
You can just assume that it is such a node.
|
||||
|
||||
do_something_with (as_a <cgraph_node> *ptr);
|
||||
|
||||
TYPE *dyn_cast <TYPE> (pointer)
|
||||
|
||||
Converts pointer to TYPE* if and only if "is_a <TYPE> pointer". Otherwise,
|
||||
returns NULL. This function is essentially a checked down cast.
|
||||
|
||||
This functions reduce compile time and increase type safety when treating a
|
||||
generic item as a more specific item.
|
||||
|
||||
You can test and obtain a pointer to the 'derived' type in one indivisible
|
||||
operation.
|
||||
|
||||
if (cgraph_node *cptr = dyn_cast <cgraph_node> (ptr))
|
||||
....
|
||||
|
||||
As an example, the code change is from
|
||||
|
||||
if (symtab_function_p (node))
|
||||
{
|
||||
struct cgraph_node *cnode = cgraph (node);
|
||||
....
|
||||
}
|
||||
|
||||
to
|
||||
|
||||
if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
|
||||
{
|
||||
....
|
||||
}
|
||||
|
||||
The necessary conditional test defines a variable that holds a known good
|
||||
pointer to the specific item and avoids subsequent conversion calls and
|
||||
the assertion checks that may come with them.
|
||||
|
||||
When, the property test is embedded within a larger condition, the
|
||||
variable declaration gets pulled out of the condition. (This approach
|
||||
leaves some room for using the variable inappropriately.)
|
||||
|
||||
if (symtab_variable_p (node) && varpool (node)->finalized)
|
||||
varpool_analyze_node (varpool (node));
|
||||
|
||||
becomes
|
||||
|
||||
varpool_node *vnode = dyn_cast <varpool_node> (node);
|
||||
if (vnode && vnode->finalized)
|
||||
varpool_analyze_node (vnode);
|
||||
|
||||
Note that we have converted two sets of assertions in the calls to varpool
|
||||
into safe and efficient use of a variable.
|
||||
|
||||
|
||||
If you use these functions and get a 'inline function not defined' or a
|
||||
'missing symbol' error message for 'is_a_helper<....>::test', it means that
|
||||
the connection between the types has not been made. See below.
|
||||
|
||||
|
||||
EXTENDING THE GENERIC TYPE FACILITY
|
||||
|
||||
Each connection between types must be made by defining a specialization of the
|
||||
template member function 'test' of the template class 'is_a_helper'. For
|
||||
example,
|
||||
|
||||
template <>
|
||||
template <>
|
||||
inline bool
|
||||
is_a_helper <cgraph_node>::test (symtab_node_def *p)
|
||||
{
|
||||
return p->symbol.type == SYMTAB_FUNCTION;
|
||||
}
|
||||
|
||||
If a simple reinterpret_cast between the pointer types is incorrect, then you
|
||||
must also specialize the template member function 'cast'. Failure to do so
|
||||
when needed may result in a crash. For example,
|
||||
|
||||
template <>
|
||||
template <>
|
||||
inline bool
|
||||
is_a_helper <cgraph_node>::cast (symtab_node_def *p)
|
||||
{
|
||||
return &p->x_function;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GCC_IS_A_H
|
||||
#define GCC_IS_A_H
|
||||
|
||||
/* A generic type conversion internal helper class. */
|
||||
|
||||
template <typename T>
|
||||
struct is_a_helper
|
||||
{
|
||||
template <typename U>
|
||||
static inline bool test (U *p);
|
||||
template <typename U>
|
||||
static inline T *cast (U *p);
|
||||
};
|
||||
|
||||
/* Note that we deliberately do not define the 'test' member template. Not
|
||||
doing so will result in a build-time error for type relationships that have
|
||||
not been defined, rather than a run-time error. See the discussion above
|
||||
for when to define this member. */
|
||||
|
||||
/* This is the generic implementation for casting from one type to another.
|
||||
Do not use this routine directly; it is an internal function. See the
|
||||
discussion above for when to define this member. */
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
inline T *
|
||||
is_a_helper <T>::cast (U *p)
|
||||
{
|
||||
return reinterpret_cast <T *> (p);
|
||||
}
|
||||
|
||||
|
||||
/* The public interface. */
|
||||
|
||||
/* A generic test for a type relationship. See the discussion above for when
|
||||
to use this function. The question answered is "Is type T a derived type of
|
||||
type U?". */
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
is_a (U *p)
|
||||
{
|
||||
return is_a_helper<T>::test (p);
|
||||
}
|
||||
|
||||
/* A generic conversion from a base type U to a derived type T. See the
|
||||
discussion above for when to use this function. */
|
||||
|
||||
template <typename T, typename U>
|
||||
inline T *
|
||||
as_a (U *p)
|
||||
{
|
||||
gcc_assert (is_a <T> (p));
|
||||
return is_a_helper <T>::cast (p);
|
||||
}
|
||||
|
||||
/* A generic checked conversion from a base type U to a derived type T. See
|
||||
the discussion above for when to use this function. */
|
||||
|
||||
template <typename T, typename U>
|
||||
inline T *
|
||||
dyn_cast (U *p)
|
||||
{
|
||||
if (is_a <T> (p))
|
||||
return is_a_helper <T>::cast (p);
|
||||
else
|
||||
return static_cast <T *> (0);
|
||||
}
|
||||
|
||||
#endif /* GCC_IS_A_H */
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
extra tree codes used by gcj.
|
||||
Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* Shift right, logical. */
|
||||
DEFTREECODE (URSHIFT_EXPR, "urshift_expr", tcc_binary, 2)
|
||||
|
||||
/* Return -1, 0, 1 depending on whether the first argument is
|
||||
less, equal, or greater to the second argument. */
|
||||
DEFTREECODE (COMPARE_EXPR, "compare_expr", tcc_binary, 2)
|
||||
|
||||
/* Same as COMPARE_EXPR, but if either value is NaN, the result is -1. */
|
||||
DEFTREECODE (COMPARE_L_EXPR, "compare_l_expr", tcc_binary, 2)
|
||||
/* Same as COMPARE_EXPR, but if either value is NaN, the result is 1. */
|
||||
DEFTREECODE (COMPARE_G_EXPR, "compare_g_expr", tcc_binary, 2)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
End:
|
||||
*/
|
||||
|
|
@ -0,0 +1,489 @@
|
|||
/* The lang_hooks data structure.
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_LANG_HOOKS_H
|
||||
#define GCC_LANG_HOOKS_H
|
||||
|
||||
/* FIXME: This file should be #include-d after tree.h (for enum tree_code). */
|
||||
|
||||
struct diagnostic_info;
|
||||
|
||||
struct gimplify_omp_ctx;
|
||||
|
||||
struct array_descr_info;
|
||||
|
||||
/* A print hook for print_tree (). */
|
||||
typedef void (*lang_print_tree_hook) (FILE *, tree, int indent);
|
||||
|
||||
enum classify_record
|
||||
{ RECORD_IS_STRUCT, RECORD_IS_CLASS, RECORD_IS_INTERFACE };
|
||||
|
||||
/* The following hooks are documented in langhooks.c. Must not be
|
||||
NULL. */
|
||||
|
||||
struct lang_hooks_for_tree_inlining
|
||||
{
|
||||
bool (*var_mod_type_p) (tree, tree);
|
||||
};
|
||||
|
||||
/* The following hooks are used by tree-dump.c. */
|
||||
|
||||
struct lang_hooks_for_tree_dump
|
||||
{
|
||||
/* Dump language-specific parts of tree nodes. Returns nonzero if it
|
||||
does not want the usual dumping of the second argument. */
|
||||
bool (*dump_tree) (void *, tree);
|
||||
|
||||
/* Determine type qualifiers in a language-specific way. */
|
||||
int (*type_quals) (const_tree);
|
||||
};
|
||||
|
||||
/* Hooks related to types. */
|
||||
|
||||
struct lang_hooks_for_types
|
||||
{
|
||||
/* Return a new type (with the indicated CODE), doing whatever
|
||||
language-specific processing is required. */
|
||||
tree (*make_type) (enum tree_code);
|
||||
|
||||
/* Return what kind of RECORD_TYPE this is, mainly for purposes of
|
||||
debug information. If not defined, record types are assumed to
|
||||
be structures. */
|
||||
enum classify_record (*classify_record) (tree);
|
||||
|
||||
/* Given MODE and UNSIGNEDP, return a suitable type-tree with that
|
||||
mode. */
|
||||
tree (*type_for_mode) (enum machine_mode, int);
|
||||
|
||||
/* Given PRECISION and UNSIGNEDP, return a suitable type-tree for an
|
||||
integer type with at least that precision. */
|
||||
tree (*type_for_size) (unsigned, int);
|
||||
|
||||
/* True if the type is an instantiation of a generic type,
|
||||
e.g. C++ template implicit specializations. */
|
||||
bool (*generic_p) (const_tree);
|
||||
|
||||
/* Returns the TREE_VEC of elements of a given generic argument pack. */
|
||||
tree (*get_argument_pack_elems) (const_tree);
|
||||
|
||||
/* Given a type, apply default promotions to unnamed function
|
||||
arguments and return the new type. Return the same type if no
|
||||
change. Required by any language that supports variadic
|
||||
arguments. The default hook dies. */
|
||||
tree (*type_promotes_to) (tree);
|
||||
|
||||
/* Register TYPE as a builtin type with the indicated NAME. The
|
||||
TYPE is placed in the outermost lexical scope. The semantics
|
||||
should be analogous to:
|
||||
|
||||
typedef TYPE NAME;
|
||||
|
||||
in C. The default hook ignores the declaration. */
|
||||
void (*register_builtin_type) (tree, const char *);
|
||||
|
||||
/* This routine is called in tree.c to print an error message for
|
||||
invalid use of an incomplete type. VALUE is the expression that
|
||||
was used (or 0 if that isn't known) and TYPE is the type that was
|
||||
invalid. */
|
||||
void (*incomplete_type_error) (const_tree value, const_tree type);
|
||||
|
||||
/* Called from assign_temp to return the maximum size, if there is one,
|
||||
for a type. */
|
||||
tree (*max_size) (const_tree);
|
||||
|
||||
/* Register language specific type size variables as potentially OpenMP
|
||||
firstprivate variables. */
|
||||
void (*omp_firstprivatize_type_sizes) (struct gimplify_omp_ctx *, tree);
|
||||
|
||||
/* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
|
||||
Called only after doing all language independent checks.
|
||||
At present, this function is only called when both TYPE1 and TYPE2 are
|
||||
FUNCTION_TYPEs. */
|
||||
bool (*type_hash_eq) (const_tree, const_tree);
|
||||
|
||||
/* Return TRUE if TYPE uses a hidden descriptor and fills in information
|
||||
for the debugger about the array bounds, strides, etc. */
|
||||
bool (*get_array_descr_info) (const_tree, struct array_descr_info *);
|
||||
|
||||
/* Fill in information for the debugger about the bounds of TYPE. */
|
||||
void (*get_subrange_bounds) (const_tree, tree *, tree *);
|
||||
|
||||
/* A type descriptive of TYPE's complex layout generated to help the
|
||||
debugger to decode variable-length or self-referential constructs.
|
||||
This is only used for the AT_GNAT_descriptive_type DWARF attribute. */
|
||||
tree (*descriptive_type) (const_tree);
|
||||
|
||||
/* If we requested a pointer to a vector, build up the pointers that
|
||||
we stripped off while looking for the inner type. Similarly for
|
||||
return values from functions. The argument TYPE is the top of the
|
||||
chain, and BOTTOM is the new type which we will point to. */
|
||||
tree (*reconstruct_complex_type) (tree, tree);
|
||||
};
|
||||
|
||||
/* Language hooks related to decls and the symbol table. */
|
||||
|
||||
struct lang_hooks_for_decls
|
||||
{
|
||||
/* Return true if we are in the global binding level. This hook is really
|
||||
needed only if the language supports variable-sized types at the global
|
||||
level, i.e. declared outside subprograms. */
|
||||
bool (*global_bindings_p) (void);
|
||||
|
||||
/* Function to add a decl to the current scope level. Takes one
|
||||
argument, a decl to add. Returns that decl, or, if the same
|
||||
symbol is already declared, may return a different decl for that
|
||||
name. */
|
||||
tree (*pushdecl) (tree);
|
||||
|
||||
/* Returns the chain of decls so far in the current scope level. */
|
||||
tree (*getdecls) (void);
|
||||
|
||||
/* Returns true if DECL is explicit member function. */
|
||||
bool (*function_decl_explicit_p) (tree);
|
||||
|
||||
/* Returns True if the parameter is a generic parameter decl
|
||||
of a generic type, e.g a template template parameter for the C++ FE. */
|
||||
bool (*generic_generic_parameter_decl_p) (const_tree);
|
||||
|
||||
/* Determine if a function parameter got expanded from a
|
||||
function parameter pack. */
|
||||
bool (*function_parm_expanded_from_pack_p) (tree, tree);
|
||||
|
||||
/* Returns the generic declaration of a generic function instantiations. */
|
||||
tree (*get_generic_function_decl) (const_tree);
|
||||
|
||||
/* Returns true when we should warn for an unused global DECL.
|
||||
We will already have checked that it has static binding. */
|
||||
bool (*warn_unused_global) (const_tree);
|
||||
|
||||
/* Obtain a list of globals and do final output on them at end
|
||||
of compilation */
|
||||
void (*final_write_globals) (void);
|
||||
|
||||
/* True if this decl may be called via a sibcall. */
|
||||
bool (*ok_for_sibcall) (const_tree);
|
||||
|
||||
/* True if OpenMP should privatize what this DECL points to rather
|
||||
than the DECL itself. */
|
||||
bool (*omp_privatize_by_reference) (const_tree);
|
||||
|
||||
/* Return sharing kind if OpenMP sharing attribute of DECL is
|
||||
predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise. */
|
||||
enum omp_clause_default_kind (*omp_predetermined_sharing) (tree);
|
||||
|
||||
/* Return decl that should be reported for DEFAULT(NONE) failure
|
||||
diagnostics. Usually the DECL passed in. */
|
||||
tree (*omp_report_decl) (tree);
|
||||
|
||||
/* Return true if DECL's DECL_VALUE_EXPR (if any) should be
|
||||
disregarded in OpenMP construct, because it is going to be
|
||||
remapped during OpenMP lowering. SHARED is true if DECL
|
||||
is going to be shared, false if it is going to be privatized. */
|
||||
bool (*omp_disregard_value_expr) (tree, bool);
|
||||
|
||||
/* Return true if DECL that is shared iff SHARED is true should
|
||||
be put into OMP_CLAUSE_PRIVATE_DEBUG. */
|
||||
bool (*omp_private_debug_clause) (tree, bool);
|
||||
|
||||
/* Return true if DECL in private clause needs
|
||||
OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
|
||||
bool (*omp_private_outer_ref) (tree);
|
||||
|
||||
/* Build and return code for a default constructor for DECL in
|
||||
response to CLAUSE. OUTER is corresponding outer region's
|
||||
variable if needed. Return NULL if nothing to be done. */
|
||||
tree (*omp_clause_default_ctor) (tree clause, tree decl, tree outer);
|
||||
|
||||
/* Build and return code for a copy constructor from SRC to DST. */
|
||||
tree (*omp_clause_copy_ctor) (tree clause, tree dst, tree src);
|
||||
|
||||
/* Similarly, except use an assignment operator instead. */
|
||||
tree (*omp_clause_assign_op) (tree clause, tree dst, tree src);
|
||||
|
||||
/* Build and return code destructing DECL. Return NULL if nothing
|
||||
to be done. */
|
||||
tree (*omp_clause_dtor) (tree clause, tree decl);
|
||||
|
||||
/* Do language specific checking on an implicitly determined clause. */
|
||||
void (*omp_finish_clause) (tree clause);
|
||||
};
|
||||
|
||||
/* Language hooks related to LTO serialization. */
|
||||
|
||||
struct lang_hooks_for_lto
|
||||
{
|
||||
/* Begin a new LTO section named NAME. */
|
||||
void (*begin_section) (const char *name);
|
||||
|
||||
/* Write DATA of length LEN to the currently open LTO section. BLOCK is a
|
||||
pointer to the dynamically allocated memory containing DATA. The
|
||||
append_data function is responsible for freeing it when it is no longer
|
||||
needed. */
|
||||
void (*append_data) (const void *data, size_t len, void *block);
|
||||
|
||||
/* End the previously begun LTO section. */
|
||||
void (*end_section) (void);
|
||||
};
|
||||
|
||||
/* Language-specific hooks. See langhooks-def.h for defaults. */
|
||||
|
||||
struct lang_hooks
|
||||
{
|
||||
/* String identifying the front end. e.g. "GNU C++". */
|
||||
const char *name;
|
||||
|
||||
/* sizeof (struct lang_identifier), so make_node () creates
|
||||
identifier nodes long enough for the language-specific slots. */
|
||||
size_t identifier_size;
|
||||
|
||||
/* Remove any parts of the tree that are used only by the FE. */
|
||||
void (*free_lang_data) (tree);
|
||||
|
||||
/* Determines the size of any language-specific tcc_constant or
|
||||
tcc_exceptional nodes. Since it is called from make_node, the
|
||||
only information available is the tree code. Expected to die
|
||||
on unrecognized codes. */
|
||||
size_t (*tree_size) (enum tree_code);
|
||||
|
||||
/* Return the language mask used for converting argv into a sequence
|
||||
of options. */
|
||||
unsigned int (*option_lang_mask) (void);
|
||||
|
||||
/* Initialize variables in an options structure. */
|
||||
void (*init_options_struct) (struct gcc_options *opts);
|
||||
|
||||
/* After the initialize_diagnostics hook is called, do any simple
|
||||
initialization needed before any calls to handle_option, other
|
||||
than that done by the init_options_struct hook. */
|
||||
void (*init_options) (unsigned int decoded_options_count,
|
||||
struct cl_decoded_option *decoded_options);
|
||||
|
||||
/* Callback used to perform language-specific initialization for the
|
||||
global diagnostic context structure. */
|
||||
void (*initialize_diagnostics) (diagnostic_context *);
|
||||
|
||||
/* Return true if a warning should be given about option OPTION,
|
||||
which is for the wrong language, false if it should be quietly
|
||||
ignored. */
|
||||
bool (*complain_wrong_lang_p) (const struct cl_option *option);
|
||||
|
||||
/* Handle the switch CODE, which has real type enum opt_code from
|
||||
options.h. If the switch takes an argument, it is passed in ARG
|
||||
which points to permanent storage. The handler is responsible for
|
||||
checking whether ARG is NULL, which indicates that no argument
|
||||
was in fact supplied. For -f and -W switches, VALUE is 1 or 0
|
||||
for the positive and negative forms respectively. HANDLERS should
|
||||
be passed to any recursive handle_option calls. LOC is the
|
||||
location of the option.
|
||||
|
||||
Return true if the switch is valid, false if invalid. */
|
||||
bool (*handle_option) (size_t code, const char *arg, int value, int kind,
|
||||
location_t loc,
|
||||
const struct cl_option_handlers *handlers);
|
||||
|
||||
/* Called when all command line options have been parsed to allow
|
||||
further processing and initialization
|
||||
|
||||
Should return true to indicate that a compiler back-end is
|
||||
not required, such as with the -E option.
|
||||
|
||||
If errorcount is nonzero after this call the compiler exits
|
||||
immediately and the finish hook is not called. */
|
||||
bool (*post_options) (const char **);
|
||||
|
||||
/* Called after post_options to initialize the front end. Return
|
||||
false to indicate that no further compilation be performed, in
|
||||
which case the finish hook is called immediately. */
|
||||
bool (*init) (void);
|
||||
|
||||
/* Called at the end of compilation, as a finalizer. */
|
||||
void (*finish) (void);
|
||||
|
||||
/* Parses the entire file. */
|
||||
void (*parse_file) (void);
|
||||
|
||||
/* Determines if it's ok for a function to have no noreturn attribute. */
|
||||
bool (*missing_noreturn_ok_p) (tree);
|
||||
|
||||
/* Called to obtain the alias set to be used for an expression or type.
|
||||
Returns -1 if the language does nothing special for it. */
|
||||
alias_set_type (*get_alias_set) (tree);
|
||||
|
||||
/* Function to finish handling an incomplete decl at the end of
|
||||
compilation. Default hook is does nothing. */
|
||||
void (*finish_incomplete_decl) (tree);
|
||||
|
||||
/* Replace the DECL_LANG_SPECIFIC data, which may be NULL, of the
|
||||
DECL_NODE with a newly GC-allocated copy. */
|
||||
void (*dup_lang_specific_decl) (tree);
|
||||
|
||||
/* Set the DECL_ASSEMBLER_NAME for a node. If it is the sort of
|
||||
thing that the assembler should talk about, set
|
||||
DECL_ASSEMBLER_NAME to an appropriate IDENTIFIER_NODE.
|
||||
Otherwise, set it to the ERROR_MARK_NODE to ensure that the
|
||||
assembler does not talk about it. */
|
||||
void (*set_decl_assembler_name) (tree);
|
||||
|
||||
/* The front end can add its own statistics to -fmem-report with
|
||||
this hook. It should output to stderr. */
|
||||
void (*print_statistics) (void);
|
||||
|
||||
/* Called by print_tree when there is a tree of class tcc_exceptional
|
||||
that it doesn't know how to display. */
|
||||
lang_print_tree_hook print_xnode;
|
||||
|
||||
/* Called to print language-dependent parts of tcc_decl, tcc_type,
|
||||
and IDENTIFIER_NODE nodes. */
|
||||
lang_print_tree_hook print_decl;
|
||||
lang_print_tree_hook print_type;
|
||||
lang_print_tree_hook print_identifier;
|
||||
|
||||
/* Computes the name to use to print a declaration. DECL is the
|
||||
non-NULL declaration in question. VERBOSITY determines what
|
||||
information will be printed: 0: DECL_NAME, demangled as
|
||||
necessary. 1: and scope information. 2: and any other
|
||||
information that might be interesting, such as function parameter
|
||||
types in C++. The name is in the internal character set and
|
||||
needs to be converted to the locale character set of diagnostics,
|
||||
or to the execution character set for strings such as
|
||||
__PRETTY_FUNCTION__. */
|
||||
const char *(*decl_printable_name) (tree decl, int verbosity);
|
||||
|
||||
/* Computes the dwarf-2/3 name for a tree. VERBOSITY determines what
|
||||
information will be printed: 0: DECL_NAME, demangled as
|
||||
necessary. 1: and scope information. */
|
||||
const char *(*dwarf_name) (tree, int verbosity);
|
||||
|
||||
/* This compares two types for equivalence ("compatible" in C-based languages).
|
||||
This routine should only return 1 if it is sure. It should not be used
|
||||
in contexts where erroneously returning 0 causes problems. */
|
||||
int (*types_compatible_p) (tree x, tree y);
|
||||
|
||||
/* Called by report_error_function to print out function name. */
|
||||
void (*print_error_function) (diagnostic_context *, const char *,
|
||||
struct diagnostic_info *);
|
||||
|
||||
/* Convert a character from the host's to the target's character
|
||||
set. The character should be in what C calls the "basic source
|
||||
character set" (roughly, the set of characters defined by plain
|
||||
old ASCII). The default is to return the character unchanged,
|
||||
which is correct in most circumstances. Note that both argument
|
||||
and result should be sign-extended under -fsigned-char,
|
||||
zero-extended under -fno-signed-char. */
|
||||
HOST_WIDE_INT (*to_target_charset) (HOST_WIDE_INT);
|
||||
|
||||
/* Pointers to machine-independent attribute tables, for front ends
|
||||
using attribs.c. If one is NULL, it is ignored. Respectively, a
|
||||
table of attributes specific to the language, a table of
|
||||
attributes common to two or more languages (to allow easy
|
||||
sharing), and a table of attributes for checking formats. */
|
||||
const struct attribute_spec *attribute_table;
|
||||
const struct attribute_spec *common_attribute_table;
|
||||
const struct attribute_spec *format_attribute_table;
|
||||
|
||||
struct lang_hooks_for_tree_inlining tree_inlining;
|
||||
|
||||
struct lang_hooks_for_tree_dump tree_dump;
|
||||
|
||||
struct lang_hooks_for_decls decls;
|
||||
|
||||
struct lang_hooks_for_types types;
|
||||
|
||||
struct lang_hooks_for_lto lto;
|
||||
|
||||
/* Returns the generic parameters of an instantiation of
|
||||
a generic type or decl, e.g. C++ template instantiation. */
|
||||
tree (*get_innermost_generic_parms) (const_tree);
|
||||
|
||||
/* Returns the TREE_VEC of arguments of an instantiation
|
||||
of a generic type of decl, e.g. C++ template instantiation. */
|
||||
tree (*get_innermost_generic_args) (const_tree);
|
||||
|
||||
/* Determine if a tree is a function parameter pack. */
|
||||
bool (*function_parameter_pack_p) (const_tree);
|
||||
|
||||
/* Perform language-specific gimplification on the argument. Returns an
|
||||
enum gimplify_status, though we can't see that type here. */
|
||||
int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *);
|
||||
|
||||
/* Do language specific processing in the builtin function DECL */
|
||||
tree (*builtin_function) (tree decl);
|
||||
|
||||
/* Like builtin_function, but make sure the scope is the external scope.
|
||||
This is used to delay putting in back end builtin functions until the ISA
|
||||
that defines the builtin is declared via function specific target options,
|
||||
which can save memory for machines like the x86_64 that have multiple
|
||||
ISAs. If this points to the same function as builtin_function, the
|
||||
backend must add all of the builtins at program initialization time. */
|
||||
tree (*builtin_function_ext_scope) (tree decl);
|
||||
|
||||
/* Used to set up the tree_contains_structure array for a frontend. */
|
||||
void (*init_ts) (void);
|
||||
|
||||
/* Called by recompute_tree_invariant_for_addr_expr to go from EXPR
|
||||
to a contained expression or DECL, possibly updating *TC or *SE
|
||||
if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating. */
|
||||
tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
|
||||
|
||||
/* The EH personality function decl. */
|
||||
tree (*eh_personality) (void);
|
||||
|
||||
/* Map a type to a runtime object to match type. */
|
||||
tree (*eh_runtime_type) (tree);
|
||||
|
||||
/* If non-NULL, this is a function that returns a function decl to be
|
||||
executed if an unhandled exception is propagated out of a cleanup
|
||||
region. For example, in C++, an exception thrown by a destructor
|
||||
during stack unwinding is required to result in a call to
|
||||
`std::terminate', so the C++ version of this function returns a
|
||||
FUNCTION_DECL for `std::terminate'. */
|
||||
tree (*eh_protect_cleanup_actions) (void);
|
||||
|
||||
/* Return true if a stmt can fallthru. Used by block_may_fallthru
|
||||
to possibly handle language trees. */
|
||||
bool (*block_may_fallthru) (const_tree);
|
||||
|
||||
/* True if this language uses __cxa_end_cleanup when the ARM EABI
|
||||
is enabled. */
|
||||
bool eh_use_cxa_end_cleanup;
|
||||
|
||||
/* True if this language requires deep unsharing of tree nodes prior to
|
||||
gimplification. */
|
||||
bool deep_unsharing;
|
||||
|
||||
/* Whenever you add entries here, make sure you adjust langhooks-def.h
|
||||
and langhooks.c accordingly. */
|
||||
};
|
||||
|
||||
/* Each front end provides its own. */
|
||||
extern struct lang_hooks lang_hooks;
|
||||
|
||||
extern tree add_builtin_function (const char *name, tree type,
|
||||
int function_code, enum built_in_class cl,
|
||||
const char *library_name,
|
||||
tree attrs);
|
||||
|
||||
extern tree add_builtin_function_ext_scope (const char *name, tree type,
|
||||
int function_code,
|
||||
enum built_in_class cl,
|
||||
const char *library_name,
|
||||
tree attrs);
|
||||
extern tree add_builtin_type (const char *name, tree type);
|
||||
|
||||
#endif /* GCC_LANG_HOOKS_H */
|
||||
|
|
@ -0,0 +1,686 @@
|
|||
/* Function declarations for libiberty.
|
||||
|
||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
Note - certain prototypes declared in this header file are for
|
||||
functions whoes implementation copyright does not belong to the
|
||||
FSF. Those prototypes are present in this file for reference
|
||||
purposes only and their presence in this file should not construed
|
||||
as an indication of ownership by the FSF of the implementation of
|
||||
those functions in any way or form whatsoever.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
Written by Cygnus Support, 1994.
|
||||
|
||||
The libiberty library provides a number of functions which are
|
||||
missing on some operating systems. We do not declare those here,
|
||||
to avoid conflicts with the system header files on operating
|
||||
systems that do support those functions. In this file we only
|
||||
declare those functions which are specific to libiberty. */
|
||||
|
||||
#ifndef LIBIBERTY_H
|
||||
#define LIBIBERTY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ansidecl.h"
|
||||
|
||||
/* Get a definition for size_t. */
|
||||
#include <stddef.h>
|
||||
/* Get a definition for va_list. */
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* If the OS supports it, ensure that the supplied stream is setup to
|
||||
avoid any multi-threaded locking. Otherwise leave the FILE pointer
|
||||
unchanged. If the stream is NULL do nothing. */
|
||||
|
||||
extern void unlock_stream (FILE *);
|
||||
|
||||
/* If the OS supports it, ensure that the standard I/O streams, stdin,
|
||||
stdout and stderr are setup to avoid any multi-threaded locking.
|
||||
Otherwise do nothing. */
|
||||
|
||||
extern void unlock_std_streams (void);
|
||||
|
||||
/* Open and return a FILE pointer. If the OS supports it, ensure that
|
||||
the stream is setup to avoid any multi-threaded locking. Otherwise
|
||||
return the FILE pointer unchanged. */
|
||||
|
||||
extern FILE *fopen_unlocked (const char *, const char *);
|
||||
extern FILE *fdopen_unlocked (int, const char *);
|
||||
extern FILE *freopen_unlocked (const char *, const char *, FILE *);
|
||||
|
||||
/* Build an argument vector from a string. Allocates memory using
|
||||
malloc. Use freeargv to free the vector. */
|
||||
|
||||
extern char **buildargv (const char *) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Free a vector returned by buildargv. */
|
||||
|
||||
extern void freeargv (char **);
|
||||
|
||||
/* Duplicate an argument vector. Allocates memory using malloc. Use
|
||||
freeargv to free the vector. */
|
||||
|
||||
extern char **dupargv (char **) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Expand "@file" arguments in argv. */
|
||||
|
||||
extern void expandargv PARAMS ((int *, char ***));
|
||||
|
||||
/* Write argv to an @-file, inserting necessary quoting. */
|
||||
|
||||
extern int writeargv PARAMS ((char **, FILE *));
|
||||
|
||||
/* Return the number of elements in argv. */
|
||||
|
||||
extern int countargv (char**);
|
||||
|
||||
/* Return the last component of a path name. Note that we can't use a
|
||||
prototype here because the parameter is declared inconsistently
|
||||
across different systems, sometimes as "char *" and sometimes as
|
||||
"const char *" */
|
||||
|
||||
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
|
||||
undefined, we haven't run the autoconf check so provide the
|
||||
declaration without arguments. If it is 0, we checked and failed
|
||||
to find the declaration so provide a fully prototyped one. If it
|
||||
is 1, we found it so don't provide any declaration at all. */
|
||||
#if !HAVE_DECL_BASENAME
|
||||
#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
|
||||
extern char *basename (const char *);
|
||||
#else
|
||||
/* Do not allow basename to be used if there is no prototype seen. We
|
||||
either need to use the above prototype or have one from
|
||||
autoconf which would result in HAVE_DECL_BASENAME being set. */
|
||||
#define basename basename_cannot_be_used_without_a_prototype
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* A well-defined basename () that is always compiled in. */
|
||||
|
||||
extern const char *lbasename (const char *);
|
||||
|
||||
/* Same, but assumes DOS semantics (drive name, backslash is also a
|
||||
dir separator) regardless of host. */
|
||||
|
||||
extern const char *dos_lbasename (const char *);
|
||||
|
||||
/* Same, but assumes Unix semantics (absolute paths always start with
|
||||
a slash, only forward slash is accepted as dir separator)
|
||||
regardless of host. */
|
||||
|
||||
extern const char *unix_lbasename (const char *);
|
||||
|
||||
/* A well-defined realpath () that is always compiled in. */
|
||||
|
||||
extern char *lrealpath (const char *);
|
||||
|
||||
/* Concatenate an arbitrary number of strings. You must pass NULL as
|
||||
the last argument of this function, to terminate the list of
|
||||
strings. Allocates memory using xmalloc. */
|
||||
|
||||
extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
|
||||
|
||||
/* Concatenate an arbitrary number of strings. You must pass NULL as
|
||||
the last argument of this function, to terminate the list of
|
||||
strings. Allocates memory using xmalloc. The first argument is
|
||||
not one of the strings to be concatenated, but if not NULL is a
|
||||
pointer to be freed after the new string is created, similar to the
|
||||
way xrealloc works. */
|
||||
|
||||
extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
|
||||
|
||||
/* Determine the length of concatenating an arbitrary number of
|
||||
strings. You must pass NULL as the last argument of this function,
|
||||
to terminate the list of strings. */
|
||||
|
||||
extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL;
|
||||
|
||||
/* Concatenate an arbitrary number of strings into a SUPPLIED area of
|
||||
memory. You must pass NULL as the last argument of this function,
|
||||
to terminate the list of strings. The supplied memory is assumed
|
||||
to be large enough. */
|
||||
|
||||
extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_SENTINEL;
|
||||
|
||||
/* Concatenate an arbitrary number of strings into a GLOBAL area of
|
||||
memory. You must pass NULL as the last argument of this function,
|
||||
to terminate the list of strings. The supplied memory is assumed
|
||||
to be large enough. */
|
||||
|
||||
extern char *concat_copy2 (const char *, ...) ATTRIBUTE_SENTINEL;
|
||||
|
||||
/* This is the global area used by concat_copy2. */
|
||||
|
||||
extern char *libiberty_concat_ptr;
|
||||
|
||||
/* Concatenate an arbitrary number of strings. You must pass NULL as
|
||||
the last argument of this function, to terminate the list of
|
||||
strings. Allocates memory using alloca. The arguments are
|
||||
evaluated twice! */
|
||||
#define ACONCAT(ACONCAT_PARAMS) \
|
||||
(libiberty_concat_ptr = (char *) alloca (concat_length ACONCAT_PARAMS + 1), \
|
||||
concat_copy2 ACONCAT_PARAMS)
|
||||
|
||||
/* Check whether two file descriptors refer to the same file. */
|
||||
|
||||
extern int fdmatch (int fd1, int fd2);
|
||||
|
||||
/* Return the position of the first bit set in the argument. */
|
||||
/* Prototypes vary from system to system, so we only provide a
|
||||
prototype on systems where we know that we need it. */
|
||||
#if defined (HAVE_DECL_FFS) && !HAVE_DECL_FFS
|
||||
extern int ffs(int);
|
||||
#endif
|
||||
|
||||
/* Get the working directory. The result is cached, so don't call
|
||||
chdir() between calls to getpwd(). */
|
||||
|
||||
extern char * getpwd (void);
|
||||
|
||||
/* Get the current time. */
|
||||
/* Prototypes vary from system to system, so we only provide a
|
||||
prototype on systems where we know that we need it. */
|
||||
#ifdef __MINGW32__
|
||||
/* Forward declaration to avoid #include <sys/time.h>. */
|
||||
struct timeval;
|
||||
extern int gettimeofday (struct timeval *, void *);
|
||||
#endif
|
||||
|
||||
/* Get the amount of time the process has run, in microseconds. */
|
||||
|
||||
extern long get_run_time (void);
|
||||
|
||||
/* Generate a relocated path to some installation directory. Allocates
|
||||
return value using malloc. */
|
||||
|
||||
extern char *make_relative_prefix (const char *, const char *,
|
||||
const char *) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Generate a relocated path to some installation directory without
|
||||
attempting to follow any soft links. Allocates
|
||||
return value using malloc. */
|
||||
|
||||
extern char *make_relative_prefix_ignore_links (const char *, const char *,
|
||||
const char *) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Choose a temporary directory to use for scratch files. */
|
||||
|
||||
extern char *choose_temp_base (void) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Return a temporary file name or NULL if unable to create one. */
|
||||
|
||||
extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Remove a link to a file unless it is special. */
|
||||
|
||||
extern int unlink_if_ordinary (const char *);
|
||||
|
||||
/* Allocate memory filled with spaces. Allocates using malloc. */
|
||||
|
||||
extern const char *spaces (int count);
|
||||
|
||||
/* Return the maximum error number for which strerror will return a
|
||||
string. */
|
||||
|
||||
extern int errno_max (void);
|
||||
|
||||
/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
|
||||
"EINVAL"). */
|
||||
|
||||
extern const char *strerrno (int);
|
||||
|
||||
/* Given the name of an errno value, return the value. */
|
||||
|
||||
extern int strtoerrno (const char *);
|
||||
|
||||
/* ANSI's strerror(), but more robust. */
|
||||
|
||||
extern char *xstrerror (int);
|
||||
|
||||
/* Return the maximum signal number for which strsignal will return a
|
||||
string. */
|
||||
|
||||
extern int signo_max (void);
|
||||
|
||||
/* Return a signal message string for a signal number
|
||||
(e.g., strsignal (SIGHUP) returns something like "Hangup"). */
|
||||
/* This is commented out as it can conflict with one in system headers.
|
||||
We still document its existence though. */
|
||||
|
||||
/*extern const char *strsignal (int);*/
|
||||
|
||||
/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
|
||||
"SIGHUP"). */
|
||||
|
||||
extern const char *strsigno (int);
|
||||
|
||||
/* Given the name of a signal, return its number. */
|
||||
|
||||
extern int strtosigno (const char *);
|
||||
|
||||
/* Register a function to be run by xexit. Returns 0 on success. */
|
||||
|
||||
extern int xatexit (void (*fn) (void));
|
||||
|
||||
/* Exit, calling all the functions registered with xatexit. */
|
||||
|
||||
extern void xexit (int status) ATTRIBUTE_NORETURN;
|
||||
|
||||
/* Set the program name used by xmalloc. */
|
||||
|
||||
extern void xmalloc_set_program_name (const char *);
|
||||
|
||||
/* Report an allocation failure. */
|
||||
extern void xmalloc_failed (size_t) ATTRIBUTE_NORETURN;
|
||||
|
||||
/* Allocate memory without fail. If malloc fails, this will print a
|
||||
message to stderr (using the name set by xmalloc_set_program_name,
|
||||
if any) and then call xexit. */
|
||||
|
||||
extern void *xmalloc (size_t) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Reallocate memory without fail. This works like xmalloc. Note,
|
||||
realloc type functions are not suitable for attribute malloc since
|
||||
they may return the same address across multiple calls. */
|
||||
|
||||
extern void *xrealloc (void *, size_t);
|
||||
|
||||
/* Allocate memory without fail and set it to zero. This works like
|
||||
xmalloc. */
|
||||
|
||||
extern void *xcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Copy a string into a memory buffer without fail. */
|
||||
|
||||
extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Copy at most N characters from string into a buffer without fail. */
|
||||
|
||||
extern char *xstrndup (const char *, size_t) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Copy an existing memory buffer to a new memory buffer without fail. */
|
||||
|
||||
extern void *xmemdup (const void *, size_t, size_t) ATTRIBUTE_MALLOC;
|
||||
|
||||
/* Physical memory routines. Return values are in BYTES. */
|
||||
extern double physmem_total (void);
|
||||
extern double physmem_available (void);
|
||||
|
||||
/* Compute the 32-bit CRC of a block of memory. */
|
||||
extern unsigned int xcrc32 (const unsigned char *, int, unsigned int);
|
||||
|
||||
/* These macros provide a K&R/C89/C++-friendly way of allocating structures
|
||||
with nice encapsulation. The XDELETE*() macros are technically
|
||||
superfluous, but provided here for symmetry. Using them consistently
|
||||
makes it easier to update client code to use different allocators such
|
||||
as new/delete and new[]/delete[]. */
|
||||
|
||||
/* Scalar allocators. */
|
||||
|
||||
#define XALLOCA(T) ((T *) alloca (sizeof (T)))
|
||||
#define XNEW(T) ((T *) xmalloc (sizeof (T)))
|
||||
#define XCNEW(T) ((T *) xcalloc (1, sizeof (T)))
|
||||
#define XDUP(T, P) ((T *) xmemdup ((P), sizeof (T), sizeof (T)))
|
||||
#define XDELETE(P) free ((void*) (P))
|
||||
|
||||
/* Array allocators. */
|
||||
|
||||
#define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N)))
|
||||
#define XNEWVEC(T, N) ((T *) xmalloc (sizeof (T) * (N)))
|
||||
#define XCNEWVEC(T, N) ((T *) xcalloc ((N), sizeof (T)))
|
||||
#define XDUPVEC(T, P, N) ((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N)))
|
||||
#define XRESIZEVEC(T, P, N) ((T *) xrealloc ((void *) (P), sizeof (T) * (N)))
|
||||
#define XDELETEVEC(P) free ((void*) (P))
|
||||
|
||||
/* Allocators for variable-sized structures and raw buffers. */
|
||||
|
||||
#define XALLOCAVAR(T, S) ((T *) alloca ((S)))
|
||||
#define XNEWVAR(T, S) ((T *) xmalloc ((S)))
|
||||
#define XCNEWVAR(T, S) ((T *) xcalloc (1, (S)))
|
||||
#define XDUPVAR(T, P, S1, S2) ((T *) xmemdup ((P), (S1), (S2)))
|
||||
#define XRESIZEVAR(T, P, S) ((T *) xrealloc ((P), (S)))
|
||||
|
||||
/* Type-safe obstack allocator. */
|
||||
|
||||
#define XOBNEW(O, T) ((T *) obstack_alloc ((O), sizeof (T)))
|
||||
#define XOBNEWVEC(O, T, N) ((T *) obstack_alloc ((O), sizeof (T) * (N)))
|
||||
#define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S)))
|
||||
#define XOBFINISH(O, T) ((T) obstack_finish ((O)))
|
||||
|
||||
/* hex character manipulation routines */
|
||||
|
||||
#define _hex_array_size 256
|
||||
#define _hex_bad 99
|
||||
extern const unsigned char _hex_value[_hex_array_size];
|
||||
extern void hex_init (void);
|
||||
#define hex_p(c) (hex_value (c) != _hex_bad)
|
||||
/* If you change this, note well: Some code relies on side effects in
|
||||
the argument being performed exactly once. */
|
||||
#define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)])
|
||||
|
||||
/* Flags for pex_init. These are bits to be or'ed together. */
|
||||
|
||||
/* Record subprocess times, if possible. */
|
||||
#define PEX_RECORD_TIMES 0x1
|
||||
|
||||
/* Use pipes for communication between processes, if possible. */
|
||||
#define PEX_USE_PIPES 0x2
|
||||
|
||||
/* Save files used for communication between processes. */
|
||||
#define PEX_SAVE_TEMPS 0x4
|
||||
|
||||
/* Prepare to execute one or more programs, with standard output of
|
||||
each program fed to standard input of the next.
|
||||
FLAGS As above.
|
||||
PNAME The name of the program to report in error messages.
|
||||
TEMPBASE A base name to use for temporary files; may be NULL to
|
||||
use a random name.
|
||||
Returns NULL on error. */
|
||||
|
||||
extern struct pex_obj *pex_init (int flags, const char *pname,
|
||||
const char *tempbase);
|
||||
|
||||
/* Flags for pex_run. These are bits to be or'ed together. */
|
||||
|
||||
/* Last program in pipeline. Standard output of program goes to
|
||||
OUTNAME, or, if OUTNAME is NULL, to standard output of caller. Do
|
||||
not set this if you want to call pex_read_output. After this is
|
||||
set, pex_run may no longer be called with the same struct
|
||||
pex_obj. */
|
||||
#define PEX_LAST 0x1
|
||||
|
||||
/* Search for program in executable search path. */
|
||||
#define PEX_SEARCH 0x2
|
||||
|
||||
/* OUTNAME is a suffix. */
|
||||
#define PEX_SUFFIX 0x4
|
||||
|
||||
/* Send program's standard error to standard output. */
|
||||
#define PEX_STDERR_TO_STDOUT 0x8
|
||||
|
||||
/* Input file should be opened in binary mode. This flag is ignored
|
||||
on Unix. */
|
||||
#define PEX_BINARY_INPUT 0x10
|
||||
|
||||
/* Output file should be opened in binary mode. This flag is ignored
|
||||
on Unix. For proper behaviour PEX_BINARY_INPUT and
|
||||
PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using
|
||||
PEX_BINARY_OUTPUT should be followed by a call using
|
||||
PEX_BINARY_INPUT. */
|
||||
#define PEX_BINARY_OUTPUT 0x20
|
||||
|
||||
/* Capture stderr to a pipe. The output can be read by
|
||||
calling pex_read_err and reading from the returned
|
||||
FILE object. This flag may be specified only for
|
||||
the last program in a pipeline.
|
||||
|
||||
This flag is supported only on Unix and Windows. */
|
||||
#define PEX_STDERR_TO_PIPE 0x40
|
||||
|
||||
/* Capture stderr in binary mode. This flag is ignored
|
||||
on Unix. */
|
||||
#define PEX_BINARY_ERROR 0x80
|
||||
|
||||
|
||||
/* Execute one program. Returns NULL on success. On error returns an
|
||||
error string (typically just the name of a system call); the error
|
||||
string is statically allocated.
|
||||
|
||||
OBJ Returned by pex_init.
|
||||
|
||||
FLAGS As above.
|
||||
|
||||
EXECUTABLE The program to execute.
|
||||
|
||||
ARGV NULL terminated array of arguments to pass to the program.
|
||||
|
||||
OUTNAME Sets the output file name as follows:
|
||||
|
||||
PEX_SUFFIX set (OUTNAME may not be NULL):
|
||||
TEMPBASE parameter to pex_init not NULL:
|
||||
Output file name is the concatenation of TEMPBASE
|
||||
and OUTNAME.
|
||||
TEMPBASE is NULL:
|
||||
Output file name is a random file name ending in
|
||||
OUTNAME.
|
||||
PEX_SUFFIX not set:
|
||||
OUTNAME not NULL:
|
||||
Output file name is OUTNAME.
|
||||
OUTNAME NULL, TEMPBASE not NULL:
|
||||
Output file name is randomly chosen using
|
||||
TEMPBASE.
|
||||
OUTNAME NULL, TEMPBASE NULL:
|
||||
Output file name is randomly chosen.
|
||||
|
||||
If PEX_LAST is not set, the output file name is the
|
||||
name to use for a temporary file holding stdout, if
|
||||
any (there will not be a file if PEX_USE_PIPES is set
|
||||
and the system supports pipes). If a file is used, it
|
||||
will be removed when no longer needed unless
|
||||
PEX_SAVE_TEMPS is set.
|
||||
|
||||
If PEX_LAST is set, and OUTNAME is not NULL, standard
|
||||
output is written to the output file name. The file
|
||||
will not be removed. If PEX_LAST and PEX_SUFFIX are
|
||||
both set, TEMPBASE may not be NULL.
|
||||
|
||||
ERRNAME If not NULL, this is the name of a file to which
|
||||
standard error is written. If NULL, standard error of
|
||||
the program is standard error of the caller.
|
||||
|
||||
ERR On an error return, *ERR is set to an errno value, or
|
||||
to 0 if there is no relevant errno.
|
||||
*/
|
||||
|
||||
extern const char *pex_run (struct pex_obj *obj, int flags,
|
||||
const char *executable, char * const *argv,
|
||||
const char *outname, const char *errname,
|
||||
int *err);
|
||||
|
||||
/* As for pex_run (), but takes an extra parameter to enable the
|
||||
environment for the child process to be specified.
|
||||
|
||||
ENV The environment for the child process, specified as
|
||||
an array of character pointers. Each element of the
|
||||
array should point to a string of the form VAR=VALUE,
|
||||
with the exception of the last element which must be
|
||||
a null pointer.
|
||||
*/
|
||||
|
||||
extern const char *pex_run_in_environment (struct pex_obj *obj, int flags,
|
||||
const char *executable,
|
||||
char * const *argv,
|
||||
char * const *env,
|
||||
const char *outname,
|
||||
const char *errname, int *err);
|
||||
|
||||
/* Return a stream for a temporary file to pass to the first program
|
||||
in the pipeline as input. The file name is chosen as for pex_run.
|
||||
pex_run closes the file automatically; don't close it yourself. */
|
||||
|
||||
extern FILE *pex_input_file (struct pex_obj *obj, int flags,
|
||||
const char *in_name);
|
||||
|
||||
/* Return a stream for a pipe connected to the standard input of the
|
||||
first program in the pipeline. You must have passed
|
||||
`PEX_USE_PIPES' to `pex_init'. Close the returned stream
|
||||
yourself. */
|
||||
|
||||
extern FILE *pex_input_pipe (struct pex_obj *obj, int binary);
|
||||
|
||||
/* Read the standard output of the last program to be executed.
|
||||
pex_run can not be called after this. BINARY should be non-zero if
|
||||
the file should be opened in binary mode; this is ignored on Unix.
|
||||
Returns NULL on error. Don't call fclose on the returned FILE; it
|
||||
will be closed by pex_free. */
|
||||
|
||||
extern FILE *pex_read_output (struct pex_obj *, int binary);
|
||||
|
||||
/* Read the standard error of the last program to be executed.
|
||||
pex_run can not be called after this. BINARY should be non-zero if
|
||||
the file should be opened in binary mode; this is ignored on Unix.
|
||||
Returns NULL on error. Don't call fclose on the returned FILE; it
|
||||
will be closed by pex_free. */
|
||||
|
||||
extern FILE *pex_read_err (struct pex_obj *, int binary);
|
||||
|
||||
/* Return exit status of all programs in VECTOR. COUNT indicates the
|
||||
size of VECTOR. The status codes in the vector are in the order of
|
||||
the calls to pex_run. Returns 0 on error, 1 on success. */
|
||||
|
||||
extern int pex_get_status (struct pex_obj *, int count, int *vector);
|
||||
|
||||
/* Return times of all programs in VECTOR. COUNT indicates the size
|
||||
of VECTOR. struct pex_time is really just struct timeval, but that
|
||||
is not portable to all systems. Returns 0 on error, 1 on
|
||||
success. */
|
||||
|
||||
struct pex_time
|
||||
{
|
||||
unsigned long user_seconds;
|
||||
unsigned long user_microseconds;
|
||||
unsigned long system_seconds;
|
||||
unsigned long system_microseconds;
|
||||
};
|
||||
|
||||
extern int pex_get_times (struct pex_obj *, int count,
|
||||
struct pex_time *vector);
|
||||
|
||||
/* Clean up a pex_obj. If you have not called pex_get_times or
|
||||
pex_get_status, this will try to kill the subprocesses. */
|
||||
|
||||
extern void pex_free (struct pex_obj *);
|
||||
|
||||
/* Just execute one program. Return value is as for pex_run.
|
||||
FLAGS Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT.
|
||||
EXECUTABLE As for pex_run.
|
||||
ARGV As for pex_run.
|
||||
PNAME As for pex_init.
|
||||
OUTNAME As for pex_run when PEX_LAST is set.
|
||||
ERRNAME As for pex_run.
|
||||
STATUS Set to exit status on success.
|
||||
ERR As for pex_run.
|
||||
*/
|
||||
|
||||
extern const char *pex_one (int flags, const char *executable,
|
||||
char * const *argv, const char *pname,
|
||||
const char *outname, const char *errname,
|
||||
int *status, int *err);
|
||||
|
||||
/* pexecute and pwait are the old pexecute interface, still here for
|
||||
backward compatibility. Don't use these for new code. Instead,
|
||||
use pex_init/pex_run/pex_get_status/pex_free, or pex_one. */
|
||||
|
||||
/* Definitions used by the pexecute routine. */
|
||||
|
||||
#define PEXECUTE_FIRST 1
|
||||
#define PEXECUTE_LAST 2
|
||||
#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
|
||||
#define PEXECUTE_SEARCH 4
|
||||
#define PEXECUTE_VERBOSE 8
|
||||
|
||||
/* Execute a program. */
|
||||
|
||||
extern int pexecute (const char *, char * const *, const char *,
|
||||
const char *, char **, char **, int);
|
||||
|
||||
/* Wait for pexecute to finish. */
|
||||
|
||||
extern int pwait (int, int *, int);
|
||||
|
||||
#if !HAVE_DECL_ASPRINTF
|
||||
/* Like sprintf but provides a pointer to malloc'd storage, which must
|
||||
be freed by the caller. */
|
||||
|
||||
extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_VASPRINTF
|
||||
/* Like vsprintf but provides a pointer to malloc'd storage, which
|
||||
must be freed by the caller. */
|
||||
|
||||
extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
|
||||
/* Like sprintf but prints at most N characters. */
|
||||
extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF
|
||||
/* Like vsprintf but prints at most N characters. */
|
||||
extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
|
||||
/* Compare version strings. */
|
||||
extern int strverscmp (const char *, const char *);
|
||||
#endif
|
||||
|
||||
/* Set the title of a process */
|
||||
extern void setproctitle (const char *name, ...);
|
||||
|
||||
/* Increase stack limit if possible. */
|
||||
extern void stack_limit_increase (unsigned long);
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
/* Drastically simplified alloca configurator. If we're using GCC,
|
||||
we use __builtin_alloca; otherwise we use the C alloca. The C
|
||||
alloca is always available. You can override GCC by defining
|
||||
USE_C_ALLOCA yourself. The canonical autoconf macro C_ALLOCA is
|
||||
also set/unset as it is often used to indicate whether code needs
|
||||
to call alloca(0). */
|
||||
extern void *C_alloca (size_t) ATTRIBUTE_MALLOC;
|
||||
#undef alloca
|
||||
#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA
|
||||
# define alloca(x) __builtin_alloca(x)
|
||||
# undef C_ALLOCA
|
||||
# define ASTRDUP(X) \
|
||||
(__extension__ ({ const char *const libiberty_optr = (X); \
|
||||
const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \
|
||||
char *const libiberty_nptr = (char *const) alloca (libiberty_len); \
|
||||
(char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); }))
|
||||
#else
|
||||
# define alloca(x) C_alloca(x)
|
||||
# undef USE_C_ALLOCA
|
||||
# define USE_C_ALLOCA 1
|
||||
# undef C_ALLOCA
|
||||
# define C_ALLOCA 1
|
||||
extern const char *libiberty_optr;
|
||||
extern char *libiberty_nptr;
|
||||
extern unsigned long libiberty_len;
|
||||
# define ASTRDUP(X) \
|
||||
(libiberty_optr = (X), \
|
||||
libiberty_len = strlen (libiberty_optr) + 1, \
|
||||
libiberty_nptr = (char *) alloca (libiberty_len), \
|
||||
(char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* ! defined (LIBIBERTY_H) */
|
||||
|
|
@ -0,0 +1,777 @@
|
|||
/* Map logical line numbers to (source file, line number) pairs.
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
In other words, you are welcome to use, share and improve this program.
|
||||
You are forbidden to forbid anyone else to use, share and improve
|
||||
what you give them. Help stamp out software-hoarding! */
|
||||
|
||||
#ifndef LIBCPP_LINE_MAP_H
|
||||
#define LIBCPP_LINE_MAP_H
|
||||
|
||||
#ifndef GTY
|
||||
#define GTY(x) /* nothing */
|
||||
#endif
|
||||
|
||||
/* Reason for creating a new line map with linemap_add. LC_ENTER is
|
||||
when including a new file, e.g. a #include directive in C.
|
||||
LC_LEAVE is when reaching a file's end. LC_RENAME is when a file
|
||||
name or line number changes for neither of the above reasons
|
||||
(e.g. a #line directive in C); LC_RENAME_VERBATIM is like LC_RENAME
|
||||
but a filename of "" is not specially interpreted as standard
|
||||
input. LC_ENTER_MACRO is when a macro expansion is about to start. */
|
||||
enum lc_reason
|
||||
{
|
||||
LC_ENTER = 0,
|
||||
LC_LEAVE,
|
||||
LC_RENAME,
|
||||
LC_RENAME_VERBATIM,
|
||||
LC_ENTER_MACRO
|
||||
/* FIXME: add support for stringize and paste. */
|
||||
};
|
||||
|
||||
/* The type of line numbers. */
|
||||
typedef unsigned int linenum_type;
|
||||
|
||||
/* A logical line/column number, i.e. an "index" into a line_map. */
|
||||
typedef unsigned int source_location;
|
||||
|
||||
/* Memory allocation function typedef. Works like xrealloc. */
|
||||
typedef void *(*line_map_realloc) (void *, size_t);
|
||||
|
||||
/* Memory allocator function that returns the actual allocated size,
|
||||
for a given requested allocation. */
|
||||
typedef size_t (*line_map_round_alloc_size_func) (size_t);
|
||||
|
||||
/* An ordinary line map encodes physical source locations. Those
|
||||
physical source locations are called "spelling locations".
|
||||
|
||||
Physical source file TO_FILE at line TO_LINE at column 0 is represented
|
||||
by the logical START_LOCATION. TO_LINE+L at column C is represented by
|
||||
START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
|
||||
and the result_location is less than the next line_map's start_location.
|
||||
(The top line is line 1 and the leftmost column is column 1; line/column 0
|
||||
means "entire file/line" or "unknown line/column" or "not applicable".)
|
||||
|
||||
The highest possible source location is MAX_SOURCE_LOCATION. */
|
||||
struct GTY(()) line_map_ordinary {
|
||||
const char *to_file;
|
||||
linenum_type to_line;
|
||||
|
||||
/* An index into the set that gives the line mapping at whose end
|
||||
the current one was included. File(s) at the bottom of the
|
||||
include stack have this set to -1. */
|
||||
int included_from;
|
||||
|
||||
/* SYSP is one for a system header, two for a C system header file
|
||||
that therefore needs to be extern "C" protected in C++, and zero
|
||||
otherwise. This field isn't really needed now that it's in
|
||||
cpp_buffer. */
|
||||
unsigned char sysp;
|
||||
|
||||
/* Number of the low-order source_location bits used for a column number. */
|
||||
unsigned int column_bits : 8;
|
||||
};
|
||||
|
||||
/* This is the highest possible source location encoded within an
|
||||
ordinary or macro map. */
|
||||
#define MAX_SOURCE_LOCATION 0x7FFFFFFF
|
||||
|
||||
struct cpp_hashnode;
|
||||
|
||||
/* A macro line map encodes location of tokens coming from a macro
|
||||
expansion.
|
||||
|
||||
Please note that this struct line_map_macro is a field of struct
|
||||
line_map below, go read the comments of struct line_map below and
|
||||
then come back here.
|
||||
|
||||
The offset from START_LOCATION is used to index into
|
||||
MACRO_LOCATIONS; this holds the original location of the token. */
|
||||
struct GTY(()) line_map_macro {
|
||||
/* The cpp macro which expansion gave birth to this macro map. */
|
||||
struct cpp_hashnode * GTY ((nested_ptr (union tree_node,
|
||||
"%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
|
||||
"%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL")))
|
||||
macro;
|
||||
|
||||
/* The number of tokens inside the replacement-list of MACRO. */
|
||||
unsigned int n_tokens;
|
||||
|
||||
/* This array of location is actually an array of pairs of
|
||||
locations. The elements inside it thus look like:
|
||||
|
||||
x0,y0, x1,y1, x2,y2, ...., xn,yn.
|
||||
|
||||
where n == n_tokens;
|
||||
|
||||
Remember that these xI,yI are collected when libcpp is about to
|
||||
expand a given macro.
|
||||
|
||||
yI is the location in the macro definition, either of the token
|
||||
itself or of a macro parameter that it replaces.
|
||||
|
||||
Imagine this:
|
||||
|
||||
#define PLUS(A, B) A + B <--- #1
|
||||
|
||||
int a = PLUS (1,2); <--- #2
|
||||
|
||||
There is a macro map for the expansion of PLUS in #2. PLUS is
|
||||
expanded into its expansion-list. The expansion-list is the
|
||||
replacement-list of PLUS where the macro parameters are replaced
|
||||
with their arguments. So the replacement-list of PLUS is made of
|
||||
the tokens:
|
||||
|
||||
A, +, B
|
||||
|
||||
and the expansion-list is made of the tokens:
|
||||
|
||||
1, +, 2
|
||||
|
||||
Let's consider the case of token "+". Its y1 [yI for I == 1] is
|
||||
its spelling location in #1.
|
||||
|
||||
y0 (thus for token "1") is the spelling location of A in #1.
|
||||
|
||||
And y2 (of token "2") is the spelling location of B in #1.
|
||||
|
||||
When the token is /not/ an argument for a macro, xI is the same
|
||||
location as yI. Otherwise, xI is the location of the token
|
||||
outside this macro expansion. If this macro was expanded from
|
||||
another macro expansion, xI is a virtual location representing
|
||||
the token in that macro expansion; otherwise, it is the spelling
|
||||
location of the token.
|
||||
|
||||
Note that a virtual location is a location returned by
|
||||
linemap_add_macro_token. It encodes the relevant locations (x,y
|
||||
pairs) of that token across the macro expansions from which it
|
||||
(the token) might come from.
|
||||
|
||||
In the example above x1 (for token "+") is going to be the same
|
||||
as y1. x0 is the spelling location for the argument token "1",
|
||||
and x2 is the spelling location for the argument token "2". */
|
||||
source_location * GTY((atomic)) macro_locations;
|
||||
|
||||
/* This is the location of the expansion point of the current macro
|
||||
map. It's the location of the macro name. That location is held
|
||||
by the map that was current right before the current one. It
|
||||
could have been either a macro or an ordinary map, depending on
|
||||
if we are in a nested expansion context not. */
|
||||
source_location expansion;
|
||||
};
|
||||
|
||||
/* A line_map encodes a sequence of locations.
|
||||
There are two kinds of maps. Ordinary maps and macro expansion
|
||||
maps, a.k.a macro maps.
|
||||
|
||||
A macro map encodes source locations of tokens that are part of a
|
||||
macro replacement-list, at a macro expansion point. E.g, in:
|
||||
|
||||
#define PLUS(A,B) A + B
|
||||
|
||||
No macro map is going to be created there, because we are not at a
|
||||
macro expansion point. We are at a macro /definition/ point. So the
|
||||
locations of the tokens of the macro replacement-list (i.e, A + B)
|
||||
will be locations in an ordinary map, not a macro map.
|
||||
|
||||
On the other hand, if we later do:
|
||||
|
||||
int a = PLUS (1,2);
|
||||
|
||||
The invocation of PLUS here is a macro expansion. So we are at a
|
||||
macro expansion point. The preprocessor expands PLUS (1,2) and
|
||||
replaces it with the tokens of its replacement-list: 1 + 2. A macro
|
||||
map is going to be created to hold (or rather to map, haha ...) the
|
||||
locations of the tokens 1, + and 2. The macro map also records the
|
||||
location of the expansion point of PLUS. That location is mapped in
|
||||
the map that is active right before the location of the invocation
|
||||
of PLUS. */
|
||||
struct GTY(()) line_map {
|
||||
source_location start_location;
|
||||
|
||||
/* The reason for creation of this line map. */
|
||||
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
|
||||
|
||||
union map_u {
|
||||
struct line_map_ordinary GTY((tag ("0"))) ordinary;
|
||||
struct line_map_macro GTY((tag ("1"))) macro;
|
||||
} GTY((desc ("%1.reason == LC_ENTER_MACRO"))) d;
|
||||
};
|
||||
|
||||
#define MAP_START_LOCATION(MAP) (MAP)->start_location
|
||||
|
||||
#define ORDINARY_MAP_FILE_NAME(MAP) \
|
||||
linemap_check_ordinary (MAP)->d.ordinary.to_file
|
||||
|
||||
#define ORDINARY_MAP_STARTING_LINE_NUMBER(MAP) \
|
||||
linemap_check_ordinary (MAP)->d.ordinary.to_line
|
||||
|
||||
#define ORDINARY_MAP_INCLUDER_FILE_INDEX(MAP) \
|
||||
linemap_check_ordinary (MAP)->d.ordinary.included_from
|
||||
|
||||
#define ORDINARY_MAP_IN_SYSTEM_HEADER_P(MAP) \
|
||||
linemap_check_ordinary (MAP)->d.ordinary.sysp
|
||||
|
||||
#define ORDINARY_MAP_NUMBER_OF_COLUMN_BITS(MAP) \
|
||||
linemap_check_ordinary (MAP)->d.ordinary.column_bits
|
||||
|
||||
#define MACRO_MAP_MACRO(MAP) (MAP)->d.macro.macro
|
||||
|
||||
#define MACRO_MAP_NUM_MACRO_TOKENS(MAP) (MAP)->d.macro.n_tokens
|
||||
|
||||
#define MACRO_MAP_LOCATIONS(MAP) (MAP)->d.macro.macro_locations
|
||||
|
||||
#define MACRO_MAP_EXPANSION_POINT_LOCATION(MAP) (MAP)->d.macro.expansion
|
||||
|
||||
/* The abstraction of a set of location maps. There can be several
|
||||
types of location maps. This abstraction contains the attributes
|
||||
that are independent from the type of the map. */
|
||||
struct GTY(()) maps_info {
|
||||
/* This array contains the different line maps.
|
||||
A line map is created for the following events:
|
||||
- when a new preprocessing unit start.
|
||||
- when a preprocessing unit ends.
|
||||
- when a macro expansion occurs. */
|
||||
struct line_map * GTY ((length ("%h.used"))) maps;
|
||||
|
||||
/* The total number of allocated maps. */
|
||||
unsigned int allocated;
|
||||
|
||||
/* The number of elements used in maps. This number is smaller
|
||||
or equal to ALLOCATED. */
|
||||
unsigned int used;
|
||||
|
||||
unsigned int cache;
|
||||
};
|
||||
|
||||
/* Data structure to associate an arbitrary data to a source location. */
|
||||
struct GTY(()) location_adhoc_data {
|
||||
source_location locus;
|
||||
void * GTY((skip)) data;
|
||||
};
|
||||
|
||||
struct htab;
|
||||
|
||||
/* The following data structure encodes a location with some adhoc data
|
||||
and maps it to a new unsigned integer (called an adhoc location)
|
||||
that replaces the original location to represent the mapping.
|
||||
|
||||
The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the
|
||||
highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as
|
||||
the original location. Once identified as the adhoc_loc, the lower 31
|
||||
bits of the integer is used to index the location_adhoc_data array,
|
||||
in which the locus and associated data is stored. */
|
||||
|
||||
struct GTY(()) location_adhoc_data_map {
|
||||
struct htab * GTY((skip)) htab;
|
||||
source_location curr_loc;
|
||||
unsigned int allocated;
|
||||
struct location_adhoc_data GTY((length ("%h.allocated"))) *data;
|
||||
};
|
||||
|
||||
/* A set of chronological line_map structures. */
|
||||
struct GTY(()) line_maps {
|
||||
|
||||
struct maps_info info_ordinary;
|
||||
|
||||
struct maps_info info_macro;
|
||||
|
||||
/* Depth of the include stack, including the current file. */
|
||||
unsigned int depth;
|
||||
|
||||
/* If true, prints an include trace a la -H. */
|
||||
bool trace_includes;
|
||||
|
||||
/* Highest source_location "given out". */
|
||||
source_location highest_location;
|
||||
|
||||
/* Start of line of highest source_location "given out". */
|
||||
source_location highest_line;
|
||||
|
||||
/* The maximum column number we can quickly allocate. Higher numbers
|
||||
may require allocating a new line_map. */
|
||||
unsigned int max_column_hint;
|
||||
|
||||
/* If non-null, the allocator to use when resizing 'maps'. If null,
|
||||
xrealloc is used. */
|
||||
line_map_realloc reallocator;
|
||||
|
||||
/* The allocators' function used to know the actual size it
|
||||
allocated, for a certain allocation size requested. */
|
||||
line_map_round_alloc_size_func round_alloc_size;
|
||||
|
||||
struct location_adhoc_data_map location_adhoc_data_map;
|
||||
};
|
||||
|
||||
/* Returns the pointer to the memory region where information about
|
||||
maps are stored in the line table SET. MACRO_MAP_P is a flag
|
||||
telling if we want macro or ordinary maps. */
|
||||
#define LINEMAPS_MAP_INFO(SET, MACRO_MAP_P) \
|
||||
((MACRO_MAP_P) \
|
||||
? &((SET)->info_macro) \
|
||||
: &((SET)->info_ordinary))
|
||||
|
||||
/* Returns the pointer to the memory region where maps are stored in
|
||||
the line table SET. MAP_KIND shall be TRUE if we are interested in
|
||||
macro maps false otherwise. */
|
||||
#define LINEMAPS_MAPS(SET, MAP_KIND) \
|
||||
(LINEMAPS_MAP_INFO (SET, MAP_KIND))->maps
|
||||
|
||||
/* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
|
||||
if we are interested in macro maps, FALSE otherwise. */
|
||||
#define LINEMAPS_ALLOCATED(SET, MAP_KIND) \
|
||||
(LINEMAPS_MAP_INFO (SET, MAP_KIND))->allocated
|
||||
|
||||
/* Returns the number of used maps so far. MAP_KIND shall be TRUE if
|
||||
we are interested in macro maps, FALSE otherwise.*/
|
||||
#define LINEMAPS_USED(SET, MAP_KIND) \
|
||||
(LINEMAPS_MAP_INFO (SET, MAP_KIND))->used
|
||||
|
||||
/* Returns the index of the last map that was looked up with
|
||||
linemap_lookup. MAP_KIND shall be TRUE if we are interested in
|
||||
macro maps, FALSE otherwise. */
|
||||
#define LINEMAPS_CACHE(SET, MAP_KIND) \
|
||||
(LINEMAPS_MAP_INFO (SET, MAP_KIND))->cache
|
||||
|
||||
/* Return the map at a given index. */
|
||||
#define LINEMAPS_MAP_AT(SET, MAP_KIND, INDEX) \
|
||||
(&((LINEMAPS_MAPS (SET, MAP_KIND))[(INDEX)]))
|
||||
|
||||
/* Returns the last map used in the line table SET. MAP_KIND
|
||||
shall be TRUE if we are interested in macro maps, FALSE
|
||||
otherwise.*/
|
||||
#define LINEMAPS_LAST_MAP(SET, MAP_KIND) \
|
||||
LINEMAPS_MAP_AT (SET, MAP_KIND, (LINEMAPS_USED (SET, MAP_KIND) - 1))
|
||||
|
||||
/* Returns the last map that was allocated in the line table SET.
|
||||
MAP_KIND shall be TRUE if we are interested in macro maps, FALSE
|
||||
otherwise.*/
|
||||
#define LINEMAPS_LAST_ALLOCATED_MAP(SET, MAP_KIND) \
|
||||
LINEMAPS_MAP_AT (SET, MAP_KIND, LINEMAPS_ALLOCATED (SET, MAP_KIND) - 1)
|
||||
|
||||
/* Returns a pointer to the memory region where ordinary maps are
|
||||
allocated in the line table SET. */
|
||||
#define LINEMAPS_ORDINARY_MAPS(SET) \
|
||||
LINEMAPS_MAPS (SET, false)
|
||||
|
||||
/* Returns the INDEXth ordinary map. */
|
||||
#define LINEMAPS_ORDINARY_MAP_AT(SET, INDEX) \
|
||||
LINEMAPS_MAP_AT (SET, false, INDEX)
|
||||
|
||||
/* Return the number of ordinary maps allocated in the line table
|
||||
SET. */
|
||||
#define LINEMAPS_ORDINARY_ALLOCATED(SET) \
|
||||
LINEMAPS_ALLOCATED(SET, false)
|
||||
|
||||
/* Return the number of ordinary maps used in the line table SET. */
|
||||
#define LINEMAPS_ORDINARY_USED(SET) \
|
||||
LINEMAPS_USED(SET, false)
|
||||
|
||||
/* Return the index of the last ordinary map that was looked up with
|
||||
linemap_lookup. */
|
||||
#define LINEMAPS_ORDINARY_CACHE(SET) \
|
||||
LINEMAPS_CACHE(SET, false)
|
||||
|
||||
/* Returns a pointer to the last ordinary map used in the line table
|
||||
SET. */
|
||||
#define LINEMAPS_LAST_ORDINARY_MAP(SET) \
|
||||
LINEMAPS_LAST_MAP(SET, false)
|
||||
|
||||
/* Returns a pointer to the last ordinary map allocated the line table
|
||||
SET. */
|
||||
#define LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP(SET) \
|
||||
LINEMAPS_LAST_ALLOCATED_MAP(SET, false)
|
||||
|
||||
/* Returns a pointer to the beginning of the region where macro maps
|
||||
are allcoated. */
|
||||
#define LINEMAPS_MACRO_MAPS(SET) \
|
||||
LINEMAPS_MAPS(SET, true)
|
||||
|
||||
/* Returns the INDEXth macro map. */
|
||||
#define LINEMAPS_MACRO_MAP_AT(SET, INDEX) \
|
||||
LINEMAPS_MAP_AT (SET, true, INDEX)
|
||||
|
||||
/* Returns the number of macro maps that were allocated in the line
|
||||
table SET. */
|
||||
#define LINEMAPS_MACRO_ALLOCATED(SET) \
|
||||
LINEMAPS_ALLOCATED(SET, true)
|
||||
|
||||
/* Returns the number of macro maps used in the line table SET. */
|
||||
#define LINEMAPS_MACRO_USED(SET) \
|
||||
LINEMAPS_USED(SET, true)
|
||||
|
||||
/* Returns the index of the last macro map looked up with
|
||||
linemap_lookup. */
|
||||
#define LINEMAPS_MACRO_CACHE(SET) \
|
||||
LINEMAPS_CACHE(SET, true)
|
||||
|
||||
/* Returns the lowest location [of a token resulting from macro
|
||||
expansion] encoded in this line table. */
|
||||
#define LINEMAPS_MACRO_LOWEST_LOCATION(SET) \
|
||||
(LINEMAPS_MACRO_USED (set) \
|
||||
? MAP_START_LOCATION (LINEMAPS_LAST_MACRO_MAP (set)) \
|
||||
: MAX_SOURCE_LOCATION)
|
||||
|
||||
/* Returns the last macro map used in the line table SET. */
|
||||
#define LINEMAPS_LAST_MACRO_MAP(SET) \
|
||||
LINEMAPS_LAST_MAP (SET, true)
|
||||
|
||||
/* Returns the last macro map allocated in the line table SET. */
|
||||
#define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
|
||||
LINEMAPS_LAST_ALLOCATED_MAP (SET, true)
|
||||
|
||||
extern void location_adhoc_data_fini (struct line_maps *);
|
||||
extern source_location get_combined_adhoc_loc (struct line_maps *,
|
||||
source_location, void *);
|
||||
extern void *get_data_from_adhoc_loc (struct line_maps *, source_location);
|
||||
extern source_location get_location_from_adhoc_loc (struct line_maps *,
|
||||
source_location);
|
||||
|
||||
#define IS_ADHOC_LOC(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
|
||||
#define COMBINE_LOCATION_DATA(SET, LOC, BLOCK) \
|
||||
get_combined_adhoc_loc ((SET), (LOC), (BLOCK))
|
||||
|
||||
extern void rebuild_location_adhoc_htab (struct line_maps *);
|
||||
|
||||
/* Initialize a line map set. */
|
||||
extern void linemap_init (struct line_maps *);
|
||||
|
||||
/* Check for and warn about line_maps entered but not exited. */
|
||||
|
||||
extern void linemap_check_files_exited (struct line_maps *);
|
||||
|
||||
/* Return a source_location for the start (i.e. column==0) of
|
||||
(physical) line TO_LINE in the current source file (as in the
|
||||
most recent linemap_add). MAX_COLUMN_HINT is the highest column
|
||||
number we expect to use in this line (but it does not change
|
||||
the highest_location). */
|
||||
|
||||
extern source_location linemap_line_start
|
||||
(struct line_maps *set, linenum_type to_line, unsigned int max_column_hint);
|
||||
|
||||
/* Add a mapping of logical source line to physical source file and
|
||||
line number. This function creates an "ordinary map", which is a
|
||||
map that records locations of tokens that are not part of macro
|
||||
replacement-lists present at a macro expansion point.
|
||||
|
||||
The text pointed to by TO_FILE must have a lifetime
|
||||
at least as long as the lifetime of SET. An empty
|
||||
TO_FILE means standard input. If reason is LC_LEAVE, and
|
||||
TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
|
||||
natural values considering the file we are returning to.
|
||||
|
||||
A call to this function can relocate the previous set of
|
||||
maps, so any stored line_map pointers should not be used. */
|
||||
extern const struct line_map *linemap_add
|
||||
(struct line_maps *, enum lc_reason, unsigned int sysp,
|
||||
const char *to_file, linenum_type to_line);
|
||||
|
||||
/* Given a logical source location, returns the map which the
|
||||
corresponding (source file, line, column) triplet can be deduced
|
||||
from. Since the set is built chronologically, the logical lines are
|
||||
monotonic increasing, and so the list is sorted and we can use a
|
||||
binary search. If no line map have been allocated yet, this
|
||||
function returns NULL. */
|
||||
extern const struct line_map *linemap_lookup
|
||||
(struct line_maps *, source_location);
|
||||
|
||||
/* Returns TRUE if the line table set tracks token locations across
|
||||
macro expansion, FALSE otherwise. */
|
||||
bool linemap_tracks_macro_expansion_locs_p (struct line_maps *);
|
||||
|
||||
/* Return TRUE if MAP encodes locations coming from a macro
|
||||
replacement-list at macro expansion point. */
|
||||
bool linemap_macro_expansion_map_p (const struct line_map *);
|
||||
|
||||
/* Return the name of the macro associated to MACRO_MAP. */
|
||||
const char* linemap_map_get_macro_name (const struct line_map*);
|
||||
|
||||
/* Return a positive value if LOCATION is the locus of a token that is
|
||||
located in a system header, O otherwise. It returns 1 if LOCATION
|
||||
is the locus of a token that is located in a system header, and 2
|
||||
if LOCATION is the locus of a token located in a C system header
|
||||
that therefore needs to be extern "C" protected in C++.
|
||||
|
||||
Note that this function returns 1 if LOCATION belongs to a token
|
||||
that is part of a macro replacement-list defined in a system
|
||||
header, but expanded in a non-system file. */
|
||||
int linemap_location_in_system_header_p (struct line_maps *,
|
||||
source_location);
|
||||
|
||||
/* Return TRUE if LOCATION is a source code location of a token coming
|
||||
from a macro replacement-list at a macro expansion point, FALSE
|
||||
otherwise. */
|
||||
bool linemap_location_from_macro_expansion_p (struct line_maps *,
|
||||
source_location);
|
||||
|
||||
/* source_location values from 0 to RESERVED_LOCATION_COUNT-1 will
|
||||
be reserved for libcpp user as special values, no token from libcpp
|
||||
will contain any of those locations. */
|
||||
#define RESERVED_LOCATION_COUNT 2
|
||||
|
||||
/* Converts a map and a source_location to source line. */
|
||||
#define SOURCE_LINE(MAP, LOC) \
|
||||
(((((LOC) - linemap_check_ordinary (MAP)->start_location) \
|
||||
>> (MAP)->d.ordinary.column_bits) + (MAP)->d.ordinary.to_line))
|
||||
|
||||
/* Convert a map and source_location to source column number. */
|
||||
#define SOURCE_COLUMN(MAP, LOC) \
|
||||
((((LOC) - linemap_check_ordinary (MAP)->start_location) \
|
||||
& ((1 << (MAP)->d.ordinary.column_bits) - 1)))
|
||||
|
||||
/* Returns the last source line number within an ordinary map. This
|
||||
is the (last) line of the #include, or other directive, that caused
|
||||
a map change. */
|
||||
#define LAST_SOURCE_LINE(MAP) \
|
||||
SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
|
||||
|
||||
/* Return the last column number within an ordinary map. */
|
||||
#define LAST_SOURCE_COLUMN(MAP) \
|
||||
SOURCE_COLUMN (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
|
||||
|
||||
/* Return the location of the last source line within an ordinary
|
||||
map. */
|
||||
#define LAST_SOURCE_LINE_LOCATION(MAP) \
|
||||
((((linemap_check_ordinary (MAP)[1].start_location - 1 \
|
||||
- (MAP)->start_location) \
|
||||
& ~((1 << (MAP)->d.ordinary.column_bits) - 1)) \
|
||||
+ (MAP)->start_location))
|
||||
|
||||
/* Returns the map a given map was included from, or NULL if the map
|
||||
belongs to the main file, i.e, a file that wasn't included by
|
||||
another one. */
|
||||
#define INCLUDED_FROM(SET, MAP) \
|
||||
((linemap_check_ordinary (MAP)->d.ordinary.included_from == -1) \
|
||||
? NULL \
|
||||
: (&LINEMAPS_ORDINARY_MAPS (SET)[(MAP)->d.ordinary.included_from]))
|
||||
|
||||
/* Nonzero if the map is at the bottom of the include stack. */
|
||||
#define MAIN_FILE_P(MAP) \
|
||||
((linemap_check_ordinary (MAP)->d.ordinary.included_from < 0))
|
||||
|
||||
#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
|
||||
|
||||
/* Assertion macro to be used in line-map code. */
|
||||
#define linemap_assert(EXPR) \
|
||||
do { \
|
||||
if (! (EXPR)) \
|
||||
abort (); \
|
||||
} while (0)
|
||||
|
||||
/* Assert that MAP encodes locations of tokens that are not part of
|
||||
the replacement-list of a macro expansion. */
|
||||
#define linemap_check_ordinary(LINE_MAP) __extension__ \
|
||||
({linemap_assert (!linemap_macro_expansion_map_p (LINE_MAP)); \
|
||||
(LINE_MAP);})
|
||||
#else
|
||||
#define linemap_assert(EXPR)
|
||||
#define linemap_check_ordinary(LINE_MAP) (LINE_MAP)
|
||||
#endif
|
||||
|
||||
/* Encode and return a source_location from a column number. The
|
||||
source line considered is the last source line used to call
|
||||
linemap_line_start, i.e, the last source line which a location was
|
||||
encoded from. */
|
||||
extern source_location
|
||||
linemap_position_for_column (struct line_maps *, unsigned int);
|
||||
|
||||
/* Encode and return a source location from a given line and
|
||||
column. */
|
||||
source_location linemap_position_for_line_and_column (struct line_map *,
|
||||
linenum_type,
|
||||
unsigned int);
|
||||
/* Return the file this map is for. */
|
||||
#define LINEMAP_FILE(MAP) \
|
||||
(linemap_check_ordinary (MAP)->d.ordinary.to_file)
|
||||
|
||||
/* Return the line number this map started encoding location from. */
|
||||
#define LINEMAP_LINE(MAP) \
|
||||
(linemap_check_ordinary (MAP)->d.ordinary.to_line)
|
||||
|
||||
/* Return a positive value if map encodes locations from a system
|
||||
header, 0 otherwise. Returns 1 if MAP encodes locations in a
|
||||
system header and 2 if it encodes locations in a C system header
|
||||
that therefore needs to be extern "C" protected in C++. */
|
||||
#define LINEMAP_SYSP(MAP) \
|
||||
(linemap_check_ordinary (MAP)->d.ordinary.sysp)
|
||||
|
||||
/* Return a positive value if PRE denotes the location of a token that
|
||||
comes before the token of POST, 0 if PRE denotes the location of
|
||||
the same token as the token for POST, and a negative value
|
||||
otherwise. */
|
||||
int linemap_compare_locations (struct line_maps *set,
|
||||
source_location pre,
|
||||
source_location post);
|
||||
|
||||
/* Return TRUE if LOC_A denotes the location a token that comes
|
||||
topogically before the token denoted by location LOC_B, or if they
|
||||
are equal. */
|
||||
#define linemap_location_before_p(SET, LOC_A, LOC_B) \
|
||||
(linemap_compare_locations ((SET), (LOC_A), (LOC_B)) >= 0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* The name of the source file involved. */
|
||||
const char *file;
|
||||
|
||||
/* The line-location in the source file. */
|
||||
int line;
|
||||
|
||||
int column;
|
||||
|
||||
void *data;
|
||||
|
||||
/* In a system header?. */
|
||||
bool sysp;
|
||||
} expanded_location;
|
||||
|
||||
/* This is enum is used by the function linemap_resolve_location
|
||||
below. The meaning of the values is explained in the comment of
|
||||
that function. */
|
||||
enum location_resolution_kind
|
||||
{
|
||||
LRK_MACRO_EXPANSION_POINT,
|
||||
LRK_SPELLING_LOCATION,
|
||||
LRK_MACRO_DEFINITION_LOCATION
|
||||
};
|
||||
|
||||
/* Resolve a virtual location into either a spelling location, an
|
||||
expansion point location or a token argument replacement point
|
||||
location. Return the map that encodes the virtual location as well
|
||||
as the resolved location.
|
||||
|
||||
If LOC is *NOT* the location of a token resulting from the
|
||||
expansion of a macro, then the parameter LRK (which stands for
|
||||
Location Resolution Kind) is ignored and the resulting location
|
||||
just equals the one given in argument.
|
||||
|
||||
Now if LOC *IS* the location of a token resulting from the
|
||||
expansion of a macro, this is what happens.
|
||||
|
||||
* If LRK is set to LRK_MACRO_EXPANSION_POINT
|
||||
-------------------------------
|
||||
|
||||
The virtual location is resolved to the first macro expansion point
|
||||
that led to this macro expansion.
|
||||
|
||||
* If LRK is set to LRK_SPELLING_LOCATION
|
||||
-------------------------------------
|
||||
|
||||
The virtual location is resolved to the locus where the token has
|
||||
been spelled in the source. This can follow through all the macro
|
||||
expansions that led to the token.
|
||||
|
||||
* If LRK is set to LRK_MACRO_DEFINITION_LOCATION
|
||||
--------------------------------------
|
||||
|
||||
The virtual location is resolved to the locus of the token in the
|
||||
context of the macro definition.
|
||||
|
||||
If LOC is the locus of a token that is an argument of a
|
||||
function-like macro [replacing a parameter in the replacement list
|
||||
of the macro] the virtual location is resolved to the locus of the
|
||||
parameter that is replaced, in the context of the definition of the
|
||||
macro.
|
||||
|
||||
If LOC is the locus of a token that is not an argument of a
|
||||
function-like macro, then the function behaves as if LRK was set to
|
||||
LRK_SPELLING_LOCATION.
|
||||
|
||||
If LOC_MAP is not NULL, *LOC_MAP is set to the map encoding the
|
||||
returned location. Note that if the returned location wasn't originally
|
||||
encoded by a map, the *MAP is set to NULL. This can happen if LOC
|
||||
resolves to a location reserved for the client code, like
|
||||
UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
|
||||
|
||||
source_location linemap_resolve_location (struct line_maps *,
|
||||
source_location loc,
|
||||
enum location_resolution_kind lrk,
|
||||
const struct line_map **loc_map);
|
||||
|
||||
/* Suppose that LOC is the virtual location of a token coming from the
|
||||
expansion of a macro M. This function then steps up to get the
|
||||
location L of the point where M got expanded. If L is a spelling
|
||||
location inside a macro expansion M', then this function returns
|
||||
the point where M' was expanded. LOC_MAP is an output parameter.
|
||||
When non-NULL, *LOC_MAP is set to the map of the returned
|
||||
location. */
|
||||
source_location linemap_unwind_toward_expansion (struct line_maps *,
|
||||
source_location loc,
|
||||
const struct line_map **loc_map);
|
||||
|
||||
/* If LOC is the virtual location of a token coming from the expansion
|
||||
of a macro M and if its spelling location is reserved (e.g, a
|
||||
location for a built-in token), then this function unwinds (using
|
||||
linemap_unwind_toward_expansion) the location until a location that
|
||||
is not reserved and is not in a system header is reached. In other
|
||||
words, this unwinds the reserved location until a location that is
|
||||
in real source code is reached.
|
||||
|
||||
Otherwise, if the spelling location for LOC is not reserved or if
|
||||
LOC doesn't come from the expansion of a macro, the function
|
||||
returns LOC as is and *MAP is not touched.
|
||||
|
||||
*MAP is set to the map of the returned location if the later is
|
||||
different from LOC. */
|
||||
source_location linemap_unwind_to_first_non_reserved_loc (struct line_maps *,
|
||||
source_location loc,
|
||||
const struct line_map **map);
|
||||
|
||||
/* Expand source code location LOC and return a user readable source
|
||||
code location. LOC must be a spelling (non-virtual) location. If
|
||||
it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
|
||||
location is returned. */
|
||||
expanded_location linemap_expand_location (struct line_maps *,
|
||||
const struct line_map *,
|
||||
source_location loc);
|
||||
|
||||
/* Statistics about maps allocation and usage as returned by
|
||||
linemap_get_statistics. */
|
||||
struct linemap_stats
|
||||
{
|
||||
long num_ordinary_maps_allocated;
|
||||
long num_ordinary_maps_used;
|
||||
long ordinary_maps_allocated_size;
|
||||
long ordinary_maps_used_size;
|
||||
long num_expanded_macros;
|
||||
long num_macro_tokens;
|
||||
long num_macro_maps_used;
|
||||
long macro_maps_allocated_size;
|
||||
long macro_maps_used_size;
|
||||
long macro_maps_locations_size;
|
||||
long duplicated_macro_maps_locations_size;
|
||||
};
|
||||
|
||||
/* Compute and return statistics about the memory consumption of some
|
||||
parts of the line table SET. */
|
||||
void linemap_get_statistics (struct line_maps *, struct linemap_stats *);
|
||||
|
||||
/* Dump debugging information about source location LOC into the file
|
||||
stream STREAM. SET is the line map set LOC comes from. */
|
||||
void linemap_dump_location (struct line_maps *, source_location, FILE *);
|
||||
|
||||
/* Dump line map at index IX in line table SET to STREAM. If STREAM
|
||||
is NULL, use stderr. IS_MACRO is true if the caller wants to
|
||||
dump a macro map, false otherwise. */
|
||||
void linemap_dump (FILE *, struct line_maps *, unsigned, bool);
|
||||
|
||||
/* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
|
||||
NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
|
||||
specifies how many macro maps to dump. */
|
||||
void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int);
|
||||
|
||||
#endif /* !LIBCPP_LINE_MAP_H */
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
/* Machine mode definitions for GCC; included by rtl.h and tree.h.
|
||||
Copyright (C) 1991-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef HAVE_MACHINE_MODES
|
||||
#define HAVE_MACHINE_MODES
|
||||
|
||||
/* Make an enum class that gives all the machine modes. */
|
||||
#include "insn-modes.h"
|
||||
|
||||
/* Get the name of mode MODE as a string. */
|
||||
|
||||
extern const char * const mode_name[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_NAME(MODE) mode_name[MODE]
|
||||
|
||||
/* Mode classes. */
|
||||
|
||||
#include "mode-classes.def"
|
||||
#define DEF_MODE_CLASS(M) M
|
||||
enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
|
||||
#undef DEF_MODE_CLASS
|
||||
#undef MODE_CLASSES
|
||||
|
||||
/* Get the general kind of object that mode MODE represents
|
||||
(integer, floating, complex, etc.) */
|
||||
|
||||
extern const unsigned char mode_class[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_CLASS(MODE) ((enum mode_class) mode_class[MODE])
|
||||
|
||||
/* Nonzero if MODE is an integral mode. */
|
||||
#define INTEGRAL_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_INT)
|
||||
|
||||
/* Nonzero if MODE is a floating-point mode. */
|
||||
#define FLOAT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)
|
||||
|
||||
/* Nonzero if MODE is a complex mode. */
|
||||
#define COMPLEX_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
|
||||
|
||||
/* Nonzero if MODE is a vector mode. */
|
||||
#define VECTOR_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
|
||||
|
||||
/* Nonzero if MODE is a scalar integral mode. */
|
||||
#define SCALAR_INT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)
|
||||
|
||||
/* Nonzero if MODE is a scalar floating point mode. */
|
||||
#define SCALAR_FLOAT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT)
|
||||
|
||||
/* Nonzero if MODE is a decimal floating point mode. */
|
||||
#define DECIMAL_FLOAT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT)
|
||||
|
||||
/* Nonzero if MODE is a scalar fract mode. */
|
||||
#define SCALAR_FRACT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_FRACT)
|
||||
|
||||
/* Nonzero if MODE is a scalar ufract mode. */
|
||||
#define SCALAR_UFRACT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_UFRACT)
|
||||
|
||||
/* Nonzero if MODE is a scalar fract or ufract mode. */
|
||||
#define ALL_SCALAR_FRACT_MODE_P(MODE) \
|
||||
(SCALAR_FRACT_MODE_P (MODE) || SCALAR_UFRACT_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar accum mode. */
|
||||
#define SCALAR_ACCUM_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_ACCUM)
|
||||
|
||||
/* Nonzero if MODE is a scalar uaccum mode. */
|
||||
#define SCALAR_UACCUM_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_UACCUM)
|
||||
|
||||
/* Nonzero if MODE is a scalar accum or uaccum mode. */
|
||||
#define ALL_SCALAR_ACCUM_MODE_P(MODE) \
|
||||
(SCALAR_ACCUM_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar fract or accum mode. */
|
||||
#define SIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \
|
||||
(SCALAR_FRACT_MODE_P (MODE) || SCALAR_ACCUM_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar ufract or uaccum mode. */
|
||||
#define UNSIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \
|
||||
(SCALAR_UFRACT_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar fract, ufract, accum or uaccum mode. */
|
||||
#define ALL_SCALAR_FIXED_POINT_MODE_P(MODE) \
|
||||
(SIGNED_SCALAR_FIXED_POINT_MODE_P (MODE) \
|
||||
|| UNSIGNED_SCALAR_FIXED_POINT_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector fract mode. */
|
||||
#define FRACT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_FRACT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT)
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector ufract mode. */
|
||||
#define UFRACT_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_UFRACT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT)
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector fract or ufract mode. */
|
||||
#define ALL_FRACT_MODE_P(MODE) \
|
||||
(FRACT_MODE_P (MODE) || UFRACT_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector accum mode. */
|
||||
#define ACCUM_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_ACCUM \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM)
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector uaccum mode. */
|
||||
#define UACCUM_MODE_P(MODE) \
|
||||
(GET_MODE_CLASS (MODE) == MODE_UACCUM \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector accum or uaccum mode. */
|
||||
#define ALL_ACCUM_MODE_P(MODE) \
|
||||
(ACCUM_MODE_P (MODE) || UACCUM_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector fract or accum mode. */
|
||||
#define SIGNED_FIXED_POINT_MODE_P(MODE) \
|
||||
(FRACT_MODE_P (MODE) || ACCUM_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector ufract or uaccum mode. */
|
||||
#define UNSIGNED_FIXED_POINT_MODE_P(MODE) \
|
||||
(UFRACT_MODE_P (MODE) || UACCUM_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if MODE is a scalar/vector fract, ufract, accum or uaccum mode. */
|
||||
#define ALL_FIXED_POINT_MODE_P(MODE) \
|
||||
(SIGNED_FIXED_POINT_MODE_P (MODE) \
|
||||
|| UNSIGNED_FIXED_POINT_MODE_P (MODE))
|
||||
|
||||
/* Nonzero if CLASS modes can be widened. */
|
||||
#define CLASS_HAS_WIDER_MODES_P(CLASS) \
|
||||
(CLASS == MODE_INT \
|
||||
|| CLASS == MODE_PARTIAL_INT \
|
||||
|| CLASS == MODE_FLOAT \
|
||||
|| CLASS == MODE_DECIMAL_FLOAT \
|
||||
|| CLASS == MODE_COMPLEX_FLOAT \
|
||||
|| CLASS == MODE_FRACT \
|
||||
|| CLASS == MODE_UFRACT \
|
||||
|| CLASS == MODE_ACCUM \
|
||||
|| CLASS == MODE_UACCUM)
|
||||
|
||||
/* Get the size in bytes and bits of an object of mode MODE. */
|
||||
|
||||
extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_SIZE(MODE) ((unsigned short) mode_size[MODE])
|
||||
#define GET_MODE_BITSIZE(MODE) \
|
||||
((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT))
|
||||
|
||||
/* Get the number of value bits of an object of mode MODE. */
|
||||
extern const unsigned short mode_precision[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_PRECISION(MODE) mode_precision[MODE]
|
||||
|
||||
/* Get the number of integral bits of an object of mode MODE. */
|
||||
extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_IBIT(MODE) mode_ibit[MODE]
|
||||
|
||||
/* Get the number of fractional bits of an object of mode MODE. */
|
||||
extern CONST_MODE_FBIT unsigned char mode_fbit[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_FBIT(MODE) mode_fbit[MODE]
|
||||
|
||||
/* Get a bitmask containing 1 for all bits in a word
|
||||
that fit within mode MODE. */
|
||||
|
||||
extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
|
||||
|
||||
#define GET_MODE_MASK(MODE) mode_mask_array[MODE]
|
||||
|
||||
/* Return the mode of the inner elements in a vector. */
|
||||
|
||||
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_INNER(MODE) ((enum machine_mode) mode_inner[MODE])
|
||||
|
||||
/* Get the size in bytes or bites of the basic parts of an
|
||||
object of mode MODE. */
|
||||
|
||||
#define GET_MODE_UNIT_SIZE(MODE) \
|
||||
(GET_MODE_INNER (MODE) == VOIDmode \
|
||||
? GET_MODE_SIZE (MODE) \
|
||||
: GET_MODE_SIZE (GET_MODE_INNER (MODE)))
|
||||
|
||||
#define GET_MODE_UNIT_BITSIZE(MODE) \
|
||||
((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
|
||||
|
||||
#define GET_MODE_UNIT_PRECISION(MODE) \
|
||||
(GET_MODE_INNER (MODE) == VOIDmode \
|
||||
? GET_MODE_PRECISION (MODE) \
|
||||
: GET_MODE_PRECISION (GET_MODE_INNER (MODE)))
|
||||
|
||||
/* Get the number of units in the object. */
|
||||
|
||||
extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_NUNITS(MODE) mode_nunits[MODE]
|
||||
|
||||
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
|
||||
|
||||
extern const unsigned char mode_wider[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_WIDER_MODE(MODE) ((enum machine_mode) mode_wider[MODE])
|
||||
|
||||
/* For scalars, this is a mode with twice the precision. For vectors,
|
||||
this is a mode with the same inner mode but with twice the elements. */
|
||||
extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
|
||||
#define GET_MODE_2XWIDER_MODE(MODE) ((enum machine_mode) mode_2xwider[MODE])
|
||||
|
||||
/* Return the mode for data of a given size SIZE and mode class CLASS.
|
||||
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
|
||||
The value is BLKmode if no other mode is found. */
|
||||
|
||||
extern enum machine_mode mode_for_size (unsigned int, enum mode_class, int);
|
||||
|
||||
/* Similar, but find the smallest mode for a given width. */
|
||||
|
||||
extern enum machine_mode smallest_mode_for_size (unsigned int,
|
||||
enum mode_class);
|
||||
|
||||
|
||||
/* Return an integer mode of the exact same size as the input mode,
|
||||
or BLKmode on failure. */
|
||||
|
||||
extern enum machine_mode int_mode_for_mode (enum machine_mode);
|
||||
|
||||
/* Return a mode that is suitable for representing a vector,
|
||||
or BLKmode on failure. */
|
||||
|
||||
extern enum machine_mode mode_for_vector (enum machine_mode, unsigned);
|
||||
|
||||
/* A class for iterating through possible bitfield modes. */
|
||||
class bit_field_mode_iterator
|
||||
{
|
||||
public:
|
||||
bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT,
|
||||
HOST_WIDE_INT, HOST_WIDE_INT,
|
||||
unsigned int, bool);
|
||||
bool next_mode (enum machine_mode *);
|
||||
bool prefer_smaller_modes ();
|
||||
|
||||
private:
|
||||
enum machine_mode mode_;
|
||||
/* We use signed values here because the bit position can be negative
|
||||
for invalid input such as gcc.dg/pr48335-8.c. */
|
||||
HOST_WIDE_INT bitsize_;
|
||||
HOST_WIDE_INT bitpos_;
|
||||
HOST_WIDE_INT bitregion_start_;
|
||||
HOST_WIDE_INT bitregion_end_;
|
||||
unsigned int align_;
|
||||
bool volatilep_;
|
||||
int count_;
|
||||
};
|
||||
|
||||
/* Find the best mode to use to access a bit field. */
|
||||
|
||||
extern enum machine_mode get_best_mode (int, int,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned int,
|
||||
enum machine_mode, bool);
|
||||
|
||||
/* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
|
||||
|
||||
extern CONST_MODE_BASE_ALIGN unsigned char mode_base_align[NUM_MACHINE_MODES];
|
||||
|
||||
extern unsigned get_mode_alignment (enum machine_mode);
|
||||
|
||||
#define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
|
||||
|
||||
/* For each class, get the narrowest mode in that class. */
|
||||
|
||||
extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS];
|
||||
#define GET_CLASS_NARROWEST_MODE(CLASS) \
|
||||
((enum machine_mode) class_narrowest_mode[CLASS])
|
||||
|
||||
/* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
|
||||
and the mode whose class is Pmode and whose size is POINTER_SIZE. */
|
||||
|
||||
extern enum machine_mode byte_mode;
|
||||
extern enum machine_mode word_mode;
|
||||
extern enum machine_mode ptr_mode;
|
||||
|
||||
/* Target-dependent machine mode initialization - in insn-modes.c. */
|
||||
extern void init_adjust_machine_modes (void);
|
||||
|
||||
#define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \
|
||||
TRULY_NOOP_TRUNCATION (GET_MODE_PRECISION (MODE1), \
|
||||
GET_MODE_PRECISION (MODE2))
|
||||
|
||||
#define HWI_COMPUTABLE_MODE_P(MODE) \
|
||||
(SCALAR_INT_MODE_P (MODE) \
|
||||
&& GET_MODE_PRECISION (MODE) <= HOST_BITS_PER_WIDE_INT)
|
||||
|
||||
#endif /* not HAVE_MACHINE_MODES */
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/* md5.h - Declaration of functions and data types used for MD5 sum
|
||||
computing library functions.
|
||||
Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _MD5_H
|
||||
#define _MD5_H 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined HAVE_LIMITS_H || _LIBC
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#include "ansidecl.h"
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
doing that would require that the configure script compile and *run*
|
||||
the resulting executable. Locally running cross-compiled executables
|
||||
is usually not possible. */
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <sys/types.h>
|
||||
typedef u_int32_t md5_uint32;
|
||||
typedef uintptr_t md5_uintptr;
|
||||
#elif defined (HAVE_SYS_TYPES_H) && defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
typedef uint32_t md5_uint32;
|
||||
typedef uintptr_t md5_uintptr;
|
||||
#else
|
||||
# define INT_MAX_32_BITS 2147483647
|
||||
|
||||
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||
This should be valid for all systems GNU cares about because
|
||||
that doesn't include 16-bit systems, and only modern systems
|
||||
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||
|
||||
# ifndef INT_MAX
|
||||
# define INT_MAX INT_MAX_32_BITS
|
||||
# endif
|
||||
|
||||
# if INT_MAX == INT_MAX_32_BITS
|
||||
typedef unsigned int md5_uint32;
|
||||
# else
|
||||
# if SHRT_MAX == INT_MAX_32_BITS
|
||||
typedef unsigned short md5_uint32;
|
||||
# else
|
||||
# if LONG_MAX == INT_MAX_32_BITS
|
||||
typedef unsigned long md5_uint32;
|
||||
# else
|
||||
/* The following line is intended to evoke an error.
|
||||
Using #error is not portable enough. */
|
||||
"Cannot determine unsigned 32-bit data type."
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
/* We have to make a guess about the integer type equivalent in size
|
||||
to pointers which should always be correct. */
|
||||
typedef unsigned long int md5_uintptr;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct md5_ctx
|
||||
{
|
||||
md5_uint32 A;
|
||||
md5_uint32 B;
|
||||
md5_uint32 C;
|
||||
md5_uint32 D;
|
||||
|
||||
md5_uint32 total[2];
|
||||
md5_uint32 buflen;
|
||||
char buffer[128] ATTRIBUTE_ALIGNED_ALIGNOF(md5_uint32);
|
||||
};
|
||||
|
||||
/*
|
||||
* The following three functions are build up the low level used in
|
||||
* the functions `md5_stream' and `md5_buffer'.
|
||||
*/
|
||||
|
||||
/* Initialize structure containing state of computation.
|
||||
(RFC 1321, 3.3: Step 3) */
|
||||
extern void md5_init_ctx (struct md5_ctx *ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is necessary that LEN is a multiple of 64!!! */
|
||||
extern void md5_process_block (const void *buffer, size_t len,
|
||||
struct md5_ctx *ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is NOT required that LEN is a multiple of 64. */
|
||||
extern void md5_process_bytes (const void *buffer, size_t len,
|
||||
struct md5_ctx *ctx);
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 16 bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
|
||||
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
|
||||
|
||||
|
||||
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK. */
|
||||
extern int md5_stream (FILE *stream, void *resblock);
|
||||
|
||||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
extern void *md5_buffer (const char *buffer, size_t len, void *resblock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* Machine mode class definitions for GCC.
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define MODE_CLASSES \
|
||||
DEF_MODE_CLASS (MODE_RANDOM), /* other */ \
|
||||
DEF_MODE_CLASS (MODE_CC), /* condition code in a register */ \
|
||||
DEF_MODE_CLASS (MODE_INT), /* integer */ \
|
||||
DEF_MODE_CLASS (MODE_PARTIAL_INT), /* integer with padding bits */ \
|
||||
DEF_MODE_CLASS (MODE_FRACT), /* signed fractional number */ \
|
||||
DEF_MODE_CLASS (MODE_UFRACT), /* unsigned fractional number */ \
|
||||
DEF_MODE_CLASS (MODE_ACCUM), /* signed accumulator */ \
|
||||
DEF_MODE_CLASS (MODE_UACCUM), /* unsigned accumulator */ \
|
||||
DEF_MODE_CLASS (MODE_FLOAT), /* floating point */ \
|
||||
DEF_MODE_CLASS (MODE_DECIMAL_FLOAT), /* decimal floating point */ \
|
||||
DEF_MODE_CLASS (MODE_COMPLEX_INT), /* complex numbers */ \
|
||||
DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \
|
||||
DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \
|
||||
DEF_MODE_CLASS (MODE_VECTOR_FRACT), /* SIMD vectors */ \
|
||||
DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */ \
|
||||
DEF_MODE_CLASS (MODE_VECTOR_ACCUM), /* SIMD vectors */ \
|
||||
DEF_MODE_CLASS (MODE_VECTOR_UACCUM), /* SIMD vectors */ \
|
||||
DEF_MODE_CLASS (MODE_VECTOR_FLOAT)
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
additional tree codes used in the Objective C front end (see tree.def
|
||||
for the standard codes).
|
||||
Copyright (C) 1990-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* Objective-C types. */
|
||||
DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", tcc_type, 0)
|
||||
DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type",
|
||||
tcc_type, 0)
|
||||
DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", tcc_type, 0)
|
||||
DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type",
|
||||
tcc_type, 0)
|
||||
DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", tcc_type, 0)
|
||||
|
||||
/* Objective-C decls. */
|
||||
DEFTREECODE (KEYWORD_DECL, "keyword_decl", tcc_declaration, 0)
|
||||
DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", tcc_declaration, 0)
|
||||
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", tcc_declaration, 0)
|
||||
DEFTREECODE (PROPERTY_DECL, "property_decl", tcc_declaration, 0)
|
||||
|
||||
/* Objective-C expressions. */
|
||||
DEFTREECODE (MESSAGE_SEND_EXPR, "message_send_expr", tcc_expression, 3)
|
||||
DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", tcc_expression, 1)
|
||||
|
||||
/* This tree is used to represent the expression 'object.property',
|
||||
where 'object' is an Objective-C object and 'property' is an
|
||||
Objective-C property. Operand 0 is the object (the tree
|
||||
representing the expression), and Operand 1 is the property (the
|
||||
PROPERTY_DECL). Operand 2 is the 'getter' call, ready to be used;
|
||||
we pregenerate it because it is hard to generate it properly later
|
||||
on. Operand 3 records whether using the 'getter' call should
|
||||
generate a deprecation warning or not.
|
||||
|
||||
A PROPERTY_REF tree needs to be transformed into 'setter' and
|
||||
'getter' calls at some point; at the moment this happens in two
|
||||
places:
|
||||
|
||||
* if we detect that a modify expression is being applied to a
|
||||
PROPERTY_REF, then we transform that into a 'getter' call (this
|
||||
happens in build_modify_expr() or cp_build_modify_expr()).
|
||||
|
||||
* else, it will remain as a PROPERTY_REF until we get to
|
||||
gimplification; at that point, we convert each PROPERTY_REF into
|
||||
a 'getter' call during ObjC/ObjC++ gimplify. At that point, it
|
||||
is quite hard to build a 'getter' call, but we have already built
|
||||
it and we just need to swap Operand 2 in, and emit the deprecation
|
||||
warnings from Operand 3 if needed.
|
||||
|
||||
Please note that when the Objective-C 2.0 "dot-syntax" 'object.component'
|
||||
is encountered, where 'component' is not a property but there are valid
|
||||
setter/getter methods for it, an artificial PROPERTY_DECL is generated
|
||||
and used in the PROPERTY_REF. */
|
||||
DEFTREECODE (PROPERTY_REF, "property_ref", tcc_expression, 4)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
End:
|
||||
*/
|
||||
|
|
@ -0,0 +1,545 @@
|
|||
/* obstack.h - object stack macros
|
||||
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
/* Summary:
|
||||
|
||||
All the apparent functions defined here are macros. The idea
|
||||
is that you would use these pre-tested macros to solve a
|
||||
very specific set of problems, and they would run fast.
|
||||
Caution: no side-effects in arguments please!! They may be
|
||||
evaluated MANY times!!
|
||||
|
||||
These macros operate a stack of objects. Each object starts life
|
||||
small, and may grow to maturity. (Consider building a word syllable
|
||||
by syllable.) An object can move while it is growing. Once it has
|
||||
been "finished" it never changes address again. So the "top of the
|
||||
stack" is typically an immature growing object, while the rest of the
|
||||
stack is of mature, fixed size and fixed address objects.
|
||||
|
||||
These routines grab large chunks of memory, using a function you
|
||||
supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
|
||||
by calling `obstack_chunk_free'. You must define them and declare
|
||||
them before using any obstack macros.
|
||||
|
||||
Each independent stack is represented by a `struct obstack'.
|
||||
Each of the obstack macros expects a pointer to such a structure
|
||||
as the first argument.
|
||||
|
||||
One motivation for this package is the problem of growing char strings
|
||||
in symbol tables. Unless you are "fascist pig with a read-only mind"
|
||||
--Gosper's immortal quote from HAKMEM item 154, out of context--you
|
||||
would not like to put any arbitrary upper limit on the length of your
|
||||
symbols.
|
||||
|
||||
In practice this often means you will build many short symbols and a
|
||||
few long symbols. At the time you are reading a symbol you don't know
|
||||
how long it is. One traditional method is to read a symbol into a
|
||||
buffer, realloc()ating the buffer every time you try to read a symbol
|
||||
that is longer than the buffer. This is beaut, but you still will
|
||||
want to copy the symbol from the buffer to a more permanent
|
||||
symbol-table entry say about half the time.
|
||||
|
||||
With obstacks, you can work differently. Use one obstack for all symbol
|
||||
names. As you read a symbol, grow the name in the obstack gradually.
|
||||
When the name is complete, finalize it. Then, if the symbol exists already,
|
||||
free the newly read name.
|
||||
|
||||
The way we do this is to take a large chunk, allocating memory from
|
||||
low addresses. When you want to build a symbol in the chunk you just
|
||||
add chars above the current "high water mark" in the chunk. When you
|
||||
have finished adding chars, because you got to the end of the symbol,
|
||||
you know how long the chars are, and you can create a new object.
|
||||
Mostly the chars will not burst over the highest address of the chunk,
|
||||
because you would typically expect a chunk to be (say) 100 times as
|
||||
long as an average object.
|
||||
|
||||
In case that isn't clear, when we have enough chars to make up
|
||||
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
|
||||
so we just point to it where it lies. No moving of chars is
|
||||
needed and this is the second win: potentially long strings need
|
||||
never be explicitly shuffled. Once an object is formed, it does not
|
||||
change its address during its lifetime.
|
||||
|
||||
When the chars burst over a chunk boundary, we allocate a larger
|
||||
chunk, and then copy the partly formed object from the end of the old
|
||||
chunk to the beginning of the new larger chunk. We then carry on
|
||||
accreting characters to the end of the object as we normally would.
|
||||
|
||||
A special macro is provided to add a single char at a time to a
|
||||
growing object. This allows the use of register variables, which
|
||||
break the ordinary 'growth' macro.
|
||||
|
||||
Summary:
|
||||
We allocate large chunks.
|
||||
We carve out one object at a time from the current chunk.
|
||||
Once carved, an object never moves.
|
||||
We are free to append data of any size to the currently
|
||||
growing object.
|
||||
Exactly one object is growing in an obstack at any one time.
|
||||
You can run one obstack per control block.
|
||||
You may have as many control blocks as you dare.
|
||||
Because of the way we do it, you can `unwind' an obstack
|
||||
back to a previous state. (You may remove objects much
|
||||
as you would with a stack.)
|
||||
*/
|
||||
|
||||
|
||||
/* Don't do the contents of this file more than once. */
|
||||
|
||||
#ifndef _OBSTACK_H
|
||||
#define _OBSTACK_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* We use subtraction of (char *) 0 instead of casting to int
|
||||
because on word-addressable machines a simple cast to int
|
||||
may ignore the byte-within-word field of the pointer. */
|
||||
|
||||
#ifndef __PTR_TO_INT
|
||||
# define __PTR_TO_INT(P) ((P) - (char *) 0)
|
||||
#endif
|
||||
|
||||
#ifndef __INT_TO_PTR
|
||||
# define __INT_TO_PTR(P) ((P) + (char *) 0)
|
||||
#endif
|
||||
|
||||
/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is
|
||||
defined, as with GNU C, use that; that way we don't pollute the
|
||||
namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is
|
||||
available, include it and use ptrdiff_t. In traditional C, long is
|
||||
the best that we can do. */
|
||||
|
||||
#ifdef __PTRDIFF_TYPE__
|
||||
# define PTR_INT_TYPE __PTRDIFF_TYPE__
|
||||
#else
|
||||
# ifdef HAVE_STDDEF_H
|
||||
# include <stddef.h>
|
||||
# define PTR_INT_TYPE ptrdiff_t
|
||||
# else
|
||||
# define PTR_INT_TYPE long
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || defined HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
|
||||
#else
|
||||
# ifdef memcpy
|
||||
# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N))
|
||||
# else
|
||||
# define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
struct _obstack_chunk /* Lives at front of each chunk. */
|
||||
{
|
||||
char *limit; /* 1 past end of this chunk */
|
||||
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
|
||||
char contents[4]; /* objects begin here */
|
||||
};
|
||||
|
||||
struct obstack /* control current object in current chunk */
|
||||
{
|
||||
long chunk_size; /* preferred size to allocate chunks in */
|
||||
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
|
||||
char *object_base; /* address of object we are building */
|
||||
char *next_free; /* where to add next char to current object */
|
||||
char *chunk_limit; /* address of char after current chunk */
|
||||
PTR_INT_TYPE temp; /* Temporary for some macros. */
|
||||
int alignment_mask; /* Mask of alignment for each object. */
|
||||
/* These prototypes vary based on `use_extra_arg', and we use
|
||||
casts to the prototypeless function type in all assignments,
|
||||
but having prototypes here quiets -Wstrict-prototypes. */
|
||||
struct _obstack_chunk *(*chunkfun) (void *, long);
|
||||
void (*freefun) (void *, struct _obstack_chunk *);
|
||||
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
|
||||
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
|
||||
unsigned maybe_empty_object:1;/* There is a possibility that the current
|
||||
chunk contains a zero-length object. This
|
||||
prevents freeing the chunk if we allocate
|
||||
a bigger chunk to replace it. */
|
||||
unsigned alloc_failed:1; /* No longer used, as we now call the failed
|
||||
handler on error, but retained for binary
|
||||
compatibility. */
|
||||
};
|
||||
|
||||
/* Declare the external functions we use; they are in obstack.c. */
|
||||
|
||||
extern void _obstack_newchunk (struct obstack *, int);
|
||||
extern void _obstack_free (struct obstack *, void *);
|
||||
extern int _obstack_begin (struct obstack *, int, int,
|
||||
void *(*) (long), void (*) (void *));
|
||||
extern int _obstack_begin_1 (struct obstack *, int, int,
|
||||
void *(*) (void *, long),
|
||||
void (*) (void *, void *), void *);
|
||||
extern int _obstack_memory_used (struct obstack *);
|
||||
|
||||
/* Do the function-declarations after the structs
|
||||
but before defining the macros. */
|
||||
|
||||
void obstack_init (struct obstack *obstack);
|
||||
|
||||
void * obstack_alloc (struct obstack *obstack, int size);
|
||||
|
||||
void * obstack_copy (struct obstack *obstack, void *address, int size);
|
||||
void * obstack_copy0 (struct obstack *obstack, void *address, int size);
|
||||
|
||||
void obstack_free (struct obstack *obstack, void *block);
|
||||
|
||||
void obstack_blank (struct obstack *obstack, int size);
|
||||
|
||||
void obstack_grow (struct obstack *obstack, void *data, int size);
|
||||
void obstack_grow0 (struct obstack *obstack, void *data, int size);
|
||||
|
||||
void obstack_1grow (struct obstack *obstack, int data_char);
|
||||
void obstack_ptr_grow (struct obstack *obstack, void *data);
|
||||
void obstack_int_grow (struct obstack *obstack, int data);
|
||||
|
||||
void * obstack_finish (struct obstack *obstack);
|
||||
|
||||
int obstack_object_size (struct obstack *obstack);
|
||||
|
||||
int obstack_room (struct obstack *obstack);
|
||||
void obstack_make_room (struct obstack *obstack, int size);
|
||||
void obstack_1grow_fast (struct obstack *obstack, int data_char);
|
||||
void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
|
||||
void obstack_int_grow_fast (struct obstack *obstack, int data);
|
||||
void obstack_blank_fast (struct obstack *obstack, int size);
|
||||
|
||||
void * obstack_base (struct obstack *obstack);
|
||||
void * obstack_next_free (struct obstack *obstack);
|
||||
int obstack_alignment_mask (struct obstack *obstack);
|
||||
int obstack_chunk_size (struct obstack *obstack);
|
||||
int obstack_memory_used (struct obstack *obstack);
|
||||
|
||||
/* Error handler called when `obstack_chunk_alloc' failed to allocate
|
||||
more memory. This can be set to a user defined function. The
|
||||
default action is to print a message and abort. */
|
||||
extern void (*obstack_alloc_failed_handler) (void);
|
||||
|
||||
/* Exit value used when `print_and_abort' is used. */
|
||||
extern int obstack_exit_failure;
|
||||
|
||||
/* Pointer to beginning of object being allocated or to be allocated next.
|
||||
Note that this might not be the final address of the object
|
||||
because a new chunk might be needed to hold the final size. */
|
||||
|
||||
#define obstack_base(h) ((h)->object_base)
|
||||
|
||||
/* Size for allocating ordinary chunks. */
|
||||
|
||||
#define obstack_chunk_size(h) ((h)->chunk_size)
|
||||
|
||||
/* Pointer to next byte not yet allocated in current chunk. */
|
||||
|
||||
#define obstack_next_free(h) ((h)->next_free)
|
||||
|
||||
/* Mask specifying low bits that should be clear in address of an object. */
|
||||
|
||||
#define obstack_alignment_mask(h) ((h)->alignment_mask)
|
||||
|
||||
/* To prevent prototype warnings provide complete argument list in
|
||||
standard C version. */
|
||||
# define obstack_init(h) \
|
||||
_obstack_begin ((h), 0, 0, \
|
||||
(void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
|
||||
|
||||
# define obstack_begin(h, size) \
|
||||
_obstack_begin ((h), (size), 0, \
|
||||
(void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
|
||||
|
||||
# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
|
||||
_obstack_begin ((h), (size), (alignment), \
|
||||
(void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun))
|
||||
|
||||
# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
|
||||
_obstack_begin_1 ((h), (size), (alignment), \
|
||||
(void *(*) (void *, long)) (chunkfun), \
|
||||
(void (*) (void *, void *)) (freefun), (arg))
|
||||
|
||||
# define obstack_chunkfun(h, newchunkfun) \
|
||||
((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
|
||||
|
||||
# define obstack_freefun(h, newfreefun) \
|
||||
((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
|
||||
|
||||
#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
|
||||
|
||||
#define obstack_blank_fast(h,n) ((h)->next_free += (n))
|
||||
|
||||
#define obstack_memory_used(h) _obstack_memory_used (h)
|
||||
|
||||
#if defined __GNUC__ && defined __STDC__ && __STDC__
|
||||
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
|
||||
does not implement __extension__. But that compiler doesn't define
|
||||
__GNUC_MINOR__. */
|
||||
# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
|
||||
# define __extension__
|
||||
# endif
|
||||
|
||||
/* For GNU C, if not -traditional,
|
||||
we can define these macros to compute all args only once
|
||||
without using a global variable.
|
||||
Also, we can avoid using the `temp' slot, to make faster code. */
|
||||
|
||||
# define obstack_object_size(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
(unsigned) (__o->next_free - __o->object_base); })
|
||||
|
||||
# define obstack_room(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
(unsigned) (__o->chunk_limit - __o->next_free); })
|
||||
|
||||
# define obstack_make_room(OBSTACK,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->chunk_limit - __o->next_free < __len) \
|
||||
_obstack_newchunk (__o, __len); \
|
||||
(void) 0; })
|
||||
|
||||
# define obstack_empty_p(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
(__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
|
||||
|
||||
# define obstack_grow(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->next_free + __len > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, __len); \
|
||||
_obstack_memcpy (__o->next_free, (where), __len); \
|
||||
__o->next_free += __len; \
|
||||
(void) 0; })
|
||||
|
||||
# define obstack_grow0(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->next_free + __len + 1 > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, __len + 1); \
|
||||
_obstack_memcpy (__o->next_free, (where), __len); \
|
||||
__o->next_free += __len; \
|
||||
*(__o->next_free)++ = 0; \
|
||||
(void) 0; })
|
||||
|
||||
# define obstack_1grow(OBSTACK,datum) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
if (__o->next_free + 1 > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, 1); \
|
||||
obstack_1grow_fast (__o, datum); \
|
||||
(void) 0; })
|
||||
|
||||
/* These assume that the obstack alignment is good enough for pointers or ints,
|
||||
and that the data added so far to the current object
|
||||
shares that much alignment. */
|
||||
|
||||
# define obstack_ptr_grow(OBSTACK,datum) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, sizeof (void *)); \
|
||||
obstack_ptr_grow_fast (__o, datum); })
|
||||
|
||||
# define obstack_int_grow(OBSTACK,datum) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, sizeof (int)); \
|
||||
obstack_int_grow_fast (__o, datum); })
|
||||
|
||||
# define obstack_ptr_grow_fast(OBSTACK,aptr) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o1 = (OBSTACK); \
|
||||
*(const void **) __o1->next_free = (aptr); \
|
||||
__o1->next_free += sizeof (const void *); \
|
||||
(void) 0; })
|
||||
|
||||
# define obstack_int_grow_fast(OBSTACK,aint) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o1 = (OBSTACK); \
|
||||
*(int *) __o1->next_free = (aint); \
|
||||
__o1->next_free += sizeof (int); \
|
||||
(void) 0; })
|
||||
|
||||
# define obstack_blank(OBSTACK,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->chunk_limit - __o->next_free < __len) \
|
||||
_obstack_newchunk (__o, __len); \
|
||||
obstack_blank_fast (__o, __len); \
|
||||
(void) 0; })
|
||||
|
||||
# define obstack_alloc(OBSTACK,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__h = (OBSTACK); \
|
||||
obstack_blank (__h, (length)); \
|
||||
obstack_finish (__h); })
|
||||
|
||||
# define obstack_copy(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__h = (OBSTACK); \
|
||||
obstack_grow (__h, (where), (length)); \
|
||||
obstack_finish (__h); })
|
||||
|
||||
# define obstack_copy0(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__h = (OBSTACK); \
|
||||
obstack_grow0 (__h, (where), (length)); \
|
||||
obstack_finish (__h); })
|
||||
|
||||
/* The local variable is named __o1 to avoid a name conflict
|
||||
when obstack_blank is called. */
|
||||
# define obstack_finish(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o1 = (OBSTACK); \
|
||||
void *value; \
|
||||
value = (void *) __o1->object_base; \
|
||||
if (__o1->next_free == value) \
|
||||
__o1->maybe_empty_object = 1; \
|
||||
__o1->next_free \
|
||||
= __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
|
||||
& ~ (__o1->alignment_mask)); \
|
||||
if (__o1->next_free - (char *)__o1->chunk \
|
||||
> __o1->chunk_limit - (char *)__o1->chunk) \
|
||||
__o1->next_free = __o1->chunk_limit; \
|
||||
__o1->object_base = __o1->next_free; \
|
||||
value; })
|
||||
|
||||
# define obstack_free(OBSTACK, OBJ) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
void *__obj = (void *) (OBJ); \
|
||||
if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
|
||||
__o->next_free = __o->object_base = (char *) __obj; \
|
||||
else (obstack_free) (__o, __obj); })
|
||||
|
||||
#else /* not __GNUC__ or not __STDC__ */
|
||||
|
||||
# define obstack_object_size(h) \
|
||||
(unsigned) ((h)->next_free - (h)->object_base)
|
||||
|
||||
# define obstack_room(h) \
|
||||
(unsigned) ((h)->chunk_limit - (h)->next_free)
|
||||
|
||||
# define obstack_empty_p(h) \
|
||||
((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
|
||||
|
||||
/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
|
||||
so that we can avoid having void expressions
|
||||
in the arms of the conditional expression.
|
||||
Casting the third operand to void was tried before,
|
||||
but some compilers won't accept it. */
|
||||
|
||||
# define obstack_make_room(h,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->next_free + (h)->temp > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), (h)->temp), 0) : 0))
|
||||
|
||||
# define obstack_grow(h,where,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->next_free + (h)->temp > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
|
||||
_obstack_memcpy ((h)->next_free, (where), (h)->temp), \
|
||||
(h)->next_free += (h)->temp)
|
||||
|
||||
# define obstack_grow0(h,where,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
|
||||
_obstack_memcpy ((h)->next_free, (where), (h)->temp), \
|
||||
(h)->next_free += (h)->temp, \
|
||||
*((h)->next_free)++ = 0)
|
||||
|
||||
# define obstack_1grow(h,datum) \
|
||||
( (((h)->next_free + 1 > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), 1), 0) : 0), \
|
||||
obstack_1grow_fast (h, datum))
|
||||
|
||||
# define obstack_ptr_grow(h,datum) \
|
||||
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
|
||||
obstack_ptr_grow_fast (h, datum))
|
||||
|
||||
# define obstack_int_grow(h,datum) \
|
||||
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
|
||||
obstack_int_grow_fast (h, datum))
|
||||
|
||||
# define obstack_ptr_grow_fast(h,aptr) \
|
||||
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
|
||||
|
||||
# define obstack_int_grow_fast(h,aint) \
|
||||
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
|
||||
|
||||
# define obstack_blank(h,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->chunk_limit - (h)->next_free < (h)->temp) \
|
||||
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
|
||||
obstack_blank_fast (h, (h)->temp))
|
||||
|
||||
# define obstack_alloc(h,length) \
|
||||
(obstack_blank ((h), (length)), obstack_finish ((h)))
|
||||
|
||||
# define obstack_copy(h,where,length) \
|
||||
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
|
||||
|
||||
# define obstack_copy0(h,where,length) \
|
||||
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
|
||||
|
||||
# define obstack_finish(h) \
|
||||
( ((h)->next_free == (h)->object_base \
|
||||
? (((h)->maybe_empty_object = 1), 0) \
|
||||
: 0), \
|
||||
(h)->temp = __PTR_TO_INT ((h)->object_base), \
|
||||
(h)->next_free \
|
||||
= __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
|
||||
& ~ ((h)->alignment_mask)), \
|
||||
(((h)->next_free - (char *) (h)->chunk \
|
||||
> (h)->chunk_limit - (char *) (h)->chunk) \
|
||||
? ((h)->next_free = (h)->chunk_limit) : 0), \
|
||||
(h)->object_base = (h)->next_free, \
|
||||
(void *) __INT_TO_PTR ((h)->temp))
|
||||
|
||||
# define obstack_free(h,obj) \
|
||||
( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
|
||||
(((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
|
||||
? (((h)->next_free = (h)->object_base \
|
||||
= (h)->temp + (char *) (h)->chunk), 0) \
|
||||
: ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0)))
|
||||
|
||||
#endif /* not __GNUC__ or not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* C++ */
|
||||
#endif
|
||||
|
||||
#endif /* obstack.h */
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
OpenMP builtins used in the GNU compiler.
|
||||
Copyright (C) 2005-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Before including this file, you should define a macro:
|
||||
|
||||
DEF_GOMP_BUILTIN (ENUM, NAME, TYPE, ATTRS)
|
||||
|
||||
See builtins.def for details. */
|
||||
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_THREAD_NUM, "omp_get_thread_num",
|
||||
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_NUM_THREADS, "omp_get_num_threads",
|
||||
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_START, "GOMP_atomic_start",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_END, "GOMP_atomic_end",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER, "GOMP_barrier",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT, "GOMP_taskwait",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKYIELD, "GOMP_taskyield",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_START, "GOMP_critical_start",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_END, "GOMP_critical_end",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_NAME_START,
|
||||
"GOMP_critical_name_start",
|
||||
BT_FN_VOID_PTRPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_NAME_END,
|
||||
"GOMP_critical_name_end",
|
||||
BT_FN_VOID_PTRPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
/* NOTE: Do not change the order of BUILT_IN_GOMP_LOOP_*_START. They
|
||||
are used in index arithmetic with enum omp_clause_schedule_kind
|
||||
in omp-low.c. */
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_START,
|
||||
"GOMP_loop_static_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_DYNAMIC_START,
|
||||
"GOMP_loop_dynamic_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_GUIDED_START,
|
||||
"GOMP_loop_guided_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_RUNTIME_START,
|
||||
"GOMP_loop_runtime_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_STATIC_START,
|
||||
"GOMP_loop_ordered_static_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_START,
|
||||
"GOMP_loop_ordered_dynamic_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_START,
|
||||
"GOMP_loop_ordered_guided_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_START,
|
||||
"GOMP_loop_ordered_runtime_start",
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_NEXT, "GOMP_loop_static_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_DYNAMIC_NEXT, "GOMP_loop_dynamic_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_GUIDED_NEXT, "GOMP_loop_guided_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_RUNTIME_NEXT, "GOMP_loop_runtime_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_STATIC_NEXT,
|
||||
"GOMP_loop_ordered_static_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_NEXT,
|
||||
"GOMP_loop_ordered_dynamic_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_NEXT,
|
||||
"GOMP_loop_ordered_guided_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_NEXT,
|
||||
"GOMP_loop_ordered_runtime_next",
|
||||
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_STATIC_START,
|
||||
"GOMP_loop_ull_static_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_DYNAMIC_START,
|
||||
"GOMP_loop_ull_dynamic_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_GUIDED_START,
|
||||
"GOMP_loop_ull_guided_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_RUNTIME_START,
|
||||
"GOMP_loop_ull_runtime_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_STATIC_START,
|
||||
"GOMP_loop_ull_ordered_static_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START,
|
||||
"GOMP_loop_ull_ordered_dynamic_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_GUIDED_START,
|
||||
"GOMP_loop_ull_ordered_guided_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_RUNTIME_START,
|
||||
"GOMP_loop_ull_ordered_runtime_start",
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULLPTR_ULLPTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT, "GOMP_loop_ull_static_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_DYNAMIC_NEXT, "GOMP_loop_ull_dynamic_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_GUIDED_NEXT, "GOMP_loop_ull_guided_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_RUNTIME_NEXT, "GOMP_loop_ull_runtime_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT,
|
||||
"GOMP_loop_ull_ordered_static_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT,
|
||||
"GOMP_loop_ull_ordered_dynamic_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT,
|
||||
"GOMP_loop_ull_ordered_guided_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT,
|
||||
"GOMP_loop_ull_ordered_runtime_next",
|
||||
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
/* NOTE: Do not change the order of BUILT_IN_GOMP_PARALLEL_LOOP_*_START.
|
||||
They are used in index arithmetic with enum omp_clause_schedule_kind
|
||||
in omp-low.c. */
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
|
||||
"GOMP_parallel_loop_static_start",
|
||||
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
|
||||
"GOMP_parallel_loop_dynamic_start",
|
||||
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
|
||||
"GOMP_parallel_loop_guided_start",
|
||||
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
|
||||
"GOMP_parallel_loop_runtime_start",
|
||||
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END, "GOMP_loop_end",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END_NOWAIT, "GOMP_loop_end_nowait",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ORDERED_START, "GOMP_ordered_start",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ORDERED_END, "GOMP_ordered_end",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_START, "GOMP_parallel_start",
|
||||
BT_FN_VOID_OMPFN_PTR_UINT, ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_END, "GOMP_parallel_end",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASK, "GOMP_task",
|
||||
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_START, "GOMP_sections_start",
|
||||
BT_FN_UINT_UINT, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_NEXT, "GOMP_sections_next",
|
||||
BT_FN_UINT, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_SECTIONS_START,
|
||||
"GOMP_parallel_sections_start",
|
||||
BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END, "GOMP_sections_end",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END_NOWAIT,
|
||||
"GOMP_sections_end_nowait",
|
||||
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_START, "GOMP_single_start",
|
||||
BT_FN_BOOL, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_START, "GOMP_single_copy_start",
|
||||
BT_FN_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_END, "GOMP_single_copy_end",
|
||||
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue