This commit was generated by cvs2svn to compensate for changes in r96263,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
+6445
-16
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+52
-7
@@ -728,6 +728,7 @@ find_base_value (src)
|
||||
rtx src;
|
||||
{
|
||||
unsigned int regno;
|
||||
|
||||
switch (GET_CODE (src))
|
||||
{
|
||||
case SYMBOL_REF:
|
||||
@@ -744,12 +745,12 @@ find_base_value (src)
|
||||
return new_reg_base_value[regno];
|
||||
|
||||
/* If a pseudo has a known base value, return it. Do not do this
|
||||
for hard regs since it can result in a circular dependency
|
||||
chain for registers which have values at function entry.
|
||||
for non-fixed hard regs since it can result in a circular
|
||||
dependency chain for registers which have values at function entry.
|
||||
|
||||
The test above is not sufficient because the scheduler may move
|
||||
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
|
||||
if (regno >= FIRST_PSEUDO_REGISTER
|
||||
if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
|
||||
&& regno < reg_base_value_size
|
||||
&& reg_base_value[regno])
|
||||
return reg_base_value[regno];
|
||||
@@ -846,8 +847,6 @@ find_base_value (src)
|
||||
if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
|
||||
break;
|
||||
/* Fall through. */
|
||||
case ZERO_EXTEND:
|
||||
case SIGN_EXTEND: /* used for NT/Alpha pointers */
|
||||
case HIGH:
|
||||
case PRE_INC:
|
||||
case PRE_DEC:
|
||||
@@ -857,6 +856,19 @@ find_base_value (src)
|
||||
case POST_MODIFY:
|
||||
return find_base_value (XEXP (src, 0));
|
||||
|
||||
case ZERO_EXTEND:
|
||||
case SIGN_EXTEND: /* used for NT/Alpha pointers */
|
||||
{
|
||||
rtx temp = find_base_value (XEXP (src, 0));
|
||||
|
||||
#ifdef POINTERS_EXTEND_UNSIGNED
|
||||
if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
|
||||
temp = convert_memory_address (Pmode, temp);
|
||||
#endif
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1230,8 +1242,6 @@ find_base_term (x)
|
||||
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
|
||||
return 0;
|
||||
/* Fall through. */
|
||||
case ZERO_EXTEND:
|
||||
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
|
||||
case HIGH:
|
||||
case PRE_INC:
|
||||
case PRE_DEC:
|
||||
@@ -1241,6 +1251,19 @@ find_base_term (x)
|
||||
case POST_MODIFY:
|
||||
return find_base_term (XEXP (x, 0));
|
||||
|
||||
case ZERO_EXTEND:
|
||||
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
|
||||
{
|
||||
rtx temp = find_base_term (XEXP (x, 0));
|
||||
|
||||
#ifdef POINTERS_EXTEND_UNSIGNED
|
||||
if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
|
||||
temp = convert_memory_address (Pmode, temp);
|
||||
#endif
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
case VALUE:
|
||||
val = CSELIB_VAL_PTR (x);
|
||||
for (l = val->locs; l; l = l->next)
|
||||
@@ -1999,6 +2022,13 @@ true_dependence (mem, mem_mode, x, varies)
|
||||
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
|
||||
return 1;
|
||||
|
||||
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
|
||||
This is used in epilogue deallocation functions. */
|
||||
if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
|
||||
return 1;
|
||||
if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
|
||||
return 1;
|
||||
|
||||
if (DIFFERENT_ALIAS_SETS_P (x, mem))
|
||||
return 0;
|
||||
|
||||
@@ -2074,6 +2104,13 @@ canon_true_dependence (mem, mem_mode, mem_addr, x, varies)
|
||||
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
|
||||
return 1;
|
||||
|
||||
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
|
||||
This is used in epilogue deallocation functions. */
|
||||
if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
|
||||
return 1;
|
||||
if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
|
||||
return 1;
|
||||
|
||||
if (DIFFERENT_ALIAS_SETS_P (x, mem))
|
||||
return 0;
|
||||
|
||||
@@ -2133,6 +2170,13 @@ write_dependence_p (mem, x, writep)
|
||||
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
|
||||
return 1;
|
||||
|
||||
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
|
||||
This is used in epilogue deallocation functions. */
|
||||
if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
|
||||
return 1;
|
||||
if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
|
||||
return 1;
|
||||
|
||||
if (DIFFERENT_ALIAS_SETS_P (x, mem))
|
||||
return 0;
|
||||
|
||||
@@ -2253,6 +2297,7 @@ nonlocal_mentioned_p (x)
|
||||
case CC0:
|
||||
case CONST_INT:
|
||||
case CONST_DOUBLE:
|
||||
case CONST_VECTOR:
|
||||
case CONST:
|
||||
case LABEL_REF:
|
||||
return 0;
|
||||
|
||||
+214
-82
@@ -1,5 +1,6 @@
|
||||
/* ANSI and traditional C compatability macros
|
||||
Copyright 1991, 1992, 1996 Free Software Foundation, Inc.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
|
||||
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
|
||||
@@ -20,144 +21,275 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
ANSI C is assumed if __STDC__ is #defined.
|
||||
|
||||
Macro ANSI C definition Traditional C definition
|
||||
----- ---- - ---------- ----------- - ----------
|
||||
PTR `void *' `char *'
|
||||
LONG_DOUBLE `long double' `double'
|
||||
VOLATILE `volatile' `'
|
||||
SIGNED `signed' `'
|
||||
PTRCONST `void *const' `char *'
|
||||
ANSI_PROTOTYPES 1 not 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)
|
||||
|
||||
CONST is also defined, but is obsolete. Just use const.
|
||||
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.
|
||||
|
||||
obsolete -- DEFUN (name, arglist, args)
|
||||
For declaring functions with prototypes, we also provide these:
|
||||
|
||||
Defines function NAME.
|
||||
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:
|
||||
|
||||
ARGLIST lists the arguments, separated by commas and enclosed in
|
||||
parentheses. ARGLIST becomes the argument list in traditional C.
|
||||
char *strcpy PARAMS ((char *dest, char *source));
|
||||
...
|
||||
char *
|
||||
strcpy (dest, source)
|
||||
char *dest;
|
||||
char *source;
|
||||
{ ... }
|
||||
|
||||
ARGS list the arguments with their types. It becomes a prototype in
|
||||
ANSI C, and the type declarations in traditional C. Arguments should
|
||||
be separated with `AND'. For functions with a variable number of
|
||||
arguments, the last thing listed should be `DOTS'.
|
||||
|
||||
obsolete -- DEFUN_VOID (name)
|
||||
VPARAMS ((prototype, ...))
|
||||
-- for functions which take a variable number of arguments. Use
|
||||
PARAMS to declare the function, VPARAMS to define it. For example:
|
||||
|
||||
Defines a function NAME, which takes no arguments.
|
||||
int printf PARAMS ((const char *format, ...));
|
||||
...
|
||||
int
|
||||
printf VPARAMS ((const char *format, ...))
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
obsolete -- EXFUN (name, (prototype)) -- obsolete.
|
||||
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.
|
||||
|
||||
Replaced by PARAMS. Do not use; will disappear someday soon.
|
||||
Was used in external function declarations.
|
||||
In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
|
||||
parentheses). In traditional C it is `NAME()'.
|
||||
For a function that takes no arguments, PROTOTYPE should be `(void)'.
|
||||
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.
|
||||
|
||||
obsolete -- PROTO (type, name, (prototype) -- obsolete.
|
||||
Here is a complete example:
|
||||
|
||||
This one has also been replaced by PARAMS. Do not use.
|
||||
int
|
||||
printf VPARAMS ((const char *format, ...))
|
||||
{
|
||||
int result;
|
||||
|
||||
PARAMS ((args))
|
||||
VA_OPEN (ap, format);
|
||||
VA_FIXEDARG (ap, const char *, format);
|
||||
|
||||
We could use the EXFUN macro to handle prototype declarations, but
|
||||
the name is misleading and the result is ugly. So we just define a
|
||||
simple macro to handle the parameter lists, as in:
|
||||
result = vfprintf (stdout, format, ap);
|
||||
VA_CLOSE (ap);
|
||||
|
||||
static int foo PARAMS ((int, char));
|
||||
return result;
|
||||
}
|
||||
|
||||
This produces: `static int foo();' or `static int foo (int, char);'
|
||||
|
||||
EXFUN would have done it like this:
|
||||
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.
|
||||
|
||||
static int EXFUN (foo, (int, char));
|
||||
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.
|
||||
|
||||
but the function is not external...and it's hard to visually parse
|
||||
the function name out of the mess. EXFUN should be considered
|
||||
obsolete; new code should be written to use PARAMS.
|
||||
|
||||
DOTS is also obsolete.
|
||||
|
||||
Examples:
|
||||
|
||||
extern int printf PARAMS ((const char *format, ...));
|
||||
*/
|
||||
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
|
||||
|
||||
#define _ANSIDECL_H 1
|
||||
|
||||
/* 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 (_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__. */
|
||||
|
||||
#define PTR void *
|
||||
#define PTRCONST void *CONST
|
||||
#define LONG_DOUBLE long double
|
||||
#define ANSI_PROTOTYPES 1
|
||||
#define PTR void *
|
||||
#define PTRCONST void *const
|
||||
#define LONG_DOUBLE long double
|
||||
|
||||
#ifndef IN_GCC
|
||||
#define AND ,
|
||||
#define NOARGS void
|
||||
#define VOLATILE volatile
|
||||
#define SIGNED signed
|
||||
#endif /* ! IN_GCC */
|
||||
#define PARAMS(ARGS) ARGS
|
||||
#define VPARAMS(ARGS) ARGS
|
||||
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
|
||||
|
||||
#define PARAMS(paramlist) paramlist
|
||||
#define ANSI_PROTOTYPES 1
|
||||
/* 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
|
||||
|
||||
#define VPARAMS(ARGS) ARGS
|
||||
#define VA_START(va_list,var) va_start(va_list,var)
|
||||
/* 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
|
||||
/* 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 DOTS , ...
|
||||
#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. */
|
||||
|
||||
#define PTR char *
|
||||
#define PTRCONST PTR
|
||||
#define LONG_DOUBLE double
|
||||
#undef ANSI_PROTOTYPES
|
||||
#define PTR char *
|
||||
#define PTRCONST PTR
|
||||
#define LONG_DOUBLE double
|
||||
|
||||
#ifndef IN_GCC
|
||||
#define AND ;
|
||||
#define NOARGS
|
||||
#define VOLATILE
|
||||
#define SIGNED
|
||||
#endif /* !IN_GCC */
|
||||
#define PARAMS(args) ()
|
||||
#define VPARAMS(args) (va_alist) va_dcl
|
||||
#define VA_START(va_list, var) va_start(va_list)
|
||||
|
||||
#ifndef const /* some systems define it in header files for non-ansi mode */
|
||||
#define const
|
||||
#endif
|
||||
#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)
|
||||
|
||||
#define PARAMS(paramlist) ()
|
||||
/* 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
|
||||
|
||||
#define VPARAMS(ARGS) (va_alist) va_dcl
|
||||
#define VA_START(va_list,var) va_start(va_list)
|
||||
|
||||
/* These are obsolete. Do not use. */
|
||||
#ifndef IN_GCC
|
||||
#define CONST
|
||||
#define DOTS
|
||||
#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. */
|
||||
#ifndef ATTRIBUTE_UNUSED_LABEL
|
||||
# if (GCC_VERSION >= 2093)
|
||||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
|
||||
# else
|
||||
# define ATTRIBUTE_UNUSED_LABEL
|
||||
# endif /* GNUC >= 2.93 */
|
||||
#endif /* ATTRIBUTE_UNUSED_LABEL */
|
||||
|
||||
#ifndef ATTRIBUTE_UNUSED
|
||||
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||
#endif /* ATTRIBUTE_UNUSED */
|
||||
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
#endif /* ATTRIBUTE_NORETURN */
|
||||
|
||||
#ifndef ATTRIBUTE_PRINTF
|
||||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||
#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 */
|
||||
|
||||
/* 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
|
||||
|
||||
/* Bootstrap support: Adjust certain macros defined by Autoconf,
|
||||
which are only valid for the stage1 compiler. If we detect
|
||||
a modern version of GCC, we are probably in stage2 or beyond,
|
||||
so unconditionally reset the values. Note that const, inline,
|
||||
etc. have been dealt with above. */
|
||||
#if (GCC_VERSION >= 2007)
|
||||
# ifndef HAVE_LONG_DOUBLE
|
||||
# define HAVE_LONG_DOUBLE 1
|
||||
# endif
|
||||
#endif /* GCC >= 2.7 */
|
||||
|
||||
#endif /* ansidecl.h */
|
||||
|
||||
+33
-1
@@ -51,6 +51,8 @@ static tree handle_noreturn_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_noinline_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_used_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_unused_attribute PARAMS ((tree *, tree, tree, int,
|
||||
@@ -109,6 +111,8 @@ static const struct attribute_spec c_common_attribute_table[] =
|
||||
handle_noreturn_attribute },
|
||||
{ "noinline", 0, 0, true, false, false,
|
||||
handle_noinline_attribute },
|
||||
{ "always_inline", 0, 0, true, false, false,
|
||||
handle_always_inline_attribute },
|
||||
{ "used", 0, 0, true, false, false,
|
||||
handle_used_attribute },
|
||||
{ "unused", 0, 0, false, false, false,
|
||||
@@ -382,7 +386,9 @@ decl_attributes (node, attributes, flags)
|
||||
|
||||
/* Layout the decl in case anything changed. */
|
||||
if (spec->type_required && DECL_P (*node)
|
||||
&& TREE_CODE (*node) == VAR_DECL)
|
||||
&& (TREE_CODE (*node) == VAR_DECL
|
||||
|| TREE_CODE (*node) == PARM_DECL
|
||||
|| TREE_CODE (*node) == RESULT_DECL))
|
||||
{
|
||||
/* Force a recalculation of mode and size. */
|
||||
DECL_MODE (*node) = VOIDmode;
|
||||
@@ -563,6 +569,31 @@ handle_noinline_attribute (node, name, args, flags, no_add_attrs)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "always_inline" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
|
||||
tree *node;
|
||||
tree name;
|
||||
tree args ATTRIBUTE_UNUSED;
|
||||
int flags ATTRIBUTE_UNUSED;
|
||||
bool *no_add_attrs;
|
||||
{
|
||||
if (TREE_CODE (*node) == FUNCTION_DECL)
|
||||
{
|
||||
/* Do nothing else, just set the attribute. We'll get at
|
||||
it later with lookup_attribute. */
|
||||
}
|
||||
else
|
||||
{
|
||||
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "used" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
@@ -1431,3 +1462,4 @@ strip_attrs (specs_attrs)
|
||||
|
||||
return specs;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Define control and data flow tables, and regsets.
|
||||
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001
|
||||
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@@ -311,6 +311,7 @@ extern void redirect_edge_pred PARAMS ((edge, basic_block));
|
||||
extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx));
|
||||
extern basic_block create_basic_block PARAMS ((int, rtx, rtx));
|
||||
extern int flow_delete_block PARAMS ((basic_block));
|
||||
extern int flow_delete_block_noexpunge PARAMS ((basic_block));
|
||||
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
|
||||
extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
|
||||
basic_block));
|
||||
@@ -629,6 +630,7 @@ extern void debug_regset PARAMS ((regset));
|
||||
extern void allocate_reg_life_data PARAMS ((void));
|
||||
extern void allocate_bb_life_data PARAMS ((void));
|
||||
extern void expunge_block PARAMS ((basic_block));
|
||||
extern void expunge_block_nocompact PARAMS ((basic_block));
|
||||
extern basic_block alloc_block PARAMS ((void));
|
||||
extern void find_unreachable_blocks PARAMS ((void));
|
||||
extern void delete_noop_moves PARAMS ((rtx));
|
||||
@@ -689,6 +691,7 @@ extern conflict_graph conflict_graph_compute
|
||||
partition));
|
||||
extern bool mark_dfs_back_edges PARAMS ((void));
|
||||
extern void update_br_prob_note PARAMS ((basic_block));
|
||||
extern void fixup_abnormal_edges PARAMS ((void));
|
||||
|
||||
/* In dominance.c */
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Basic block reordering routines for the GNU compiler.
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#include "flags.h"
|
||||
#include "output.h"
|
||||
#include "cfglayout.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Local function prototypes. */
|
||||
static void make_reorder_chain PARAMS ((void));
|
||||
@@ -260,6 +261,9 @@ reorder_basic_blocks ()
|
||||
if (n_basic_blocks <= 1)
|
||||
return;
|
||||
|
||||
if ((* targetm.cannot_modify_jumps_p) ())
|
||||
return;
|
||||
|
||||
cfg_layout_initialize ();
|
||||
|
||||
make_reorder_chain ();
|
||||
|
||||
+62
-28
@@ -2991,37 +2991,54 @@ rtx
|
||||
std_expand_builtin_va_arg (valist, type)
|
||||
tree valist, type;
|
||||
{
|
||||
tree addr_tree, t;
|
||||
HOST_WIDE_INT align;
|
||||
HOST_WIDE_INT rounded_size;
|
||||
tree addr_tree, t, type_size = NULL;
|
||||
tree align, alignm1;
|
||||
tree rounded_size;
|
||||
rtx addr;
|
||||
|
||||
/* Compute the rounded size of the type. */
|
||||
align = PARM_BOUNDARY / BITS_PER_UNIT;
|
||||
rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
|
||||
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
|
||||
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
|
||||
if (type == error_mark_node
|
||||
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|
||||
|| TREE_OVERFLOW (type_size))
|
||||
rounded_size = size_zero_node;
|
||||
else
|
||||
rounded_size = fold (build (MULT_EXPR, sizetype,
|
||||
fold (build (TRUNC_DIV_EXPR, sizetype,
|
||||
fold (build (PLUS_EXPR, sizetype,
|
||||
type_size, alignm1)),
|
||||
align)),
|
||||
align));
|
||||
|
||||
/* Get AP. */
|
||||
addr_tree = valist;
|
||||
if (PAD_VARARGS_DOWN)
|
||||
if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
|
||||
{
|
||||
/* Small args are padded downward. */
|
||||
|
||||
HOST_WIDE_INT adj
|
||||
= rounded_size > align ? rounded_size : int_size_in_bytes (type);
|
||||
|
||||
addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
|
||||
build_int_2 (rounded_size - adj, 0));
|
||||
addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
|
||||
fold (build (COND_EXPR, sizetype,
|
||||
fold (build (GT_EXPR, sizetype,
|
||||
rounded_size,
|
||||
align)),
|
||||
size_zero_node,
|
||||
fold (build (MINUS_EXPR, sizetype,
|
||||
rounded_size,
|
||||
type_size))))));
|
||||
}
|
||||
|
||||
addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
|
||||
addr = copy_to_reg (addr);
|
||||
|
||||
/* Compute new value for AP. */
|
||||
t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
|
||||
build (PLUS_EXPR, TREE_TYPE (valist), valist,
|
||||
build_int_2 (rounded_size, 0)));
|
||||
TREE_SIDE_EFFECTS (t) = 1;
|
||||
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
if (! integer_zerop (rounded_size))
|
||||
{
|
||||
t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
|
||||
build (PLUS_EXPR, TREE_TYPE (valist), valist,
|
||||
rounded_size));
|
||||
TREE_SIDE_EFFECTS (t) = 1;
|
||||
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -3064,7 +3081,7 @@ expand_builtin_va_arg (valist, type)
|
||||
else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
|
||||
{
|
||||
const char *name = "<anonymous type>", *pname = 0;
|
||||
static int gave_help;
|
||||
static bool gave_help;
|
||||
|
||||
if (TYPE_NAME (type))
|
||||
{
|
||||
@@ -3083,13 +3100,24 @@ expand_builtin_va_arg (valist, type)
|
||||
pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
|
||||
}
|
||||
|
||||
error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
|
||||
/* Unfortunately, this is merely undefined, rather than a constraint
|
||||
violation, so we cannot make this an error. If this call is never
|
||||
executed, the program is still strictly conforming. */
|
||||
warning ("`%s' is promoted to `%s' when passed through `...'",
|
||||
name, pname);
|
||||
if (! gave_help)
|
||||
{
|
||||
gave_help = 1;
|
||||
error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
|
||||
gave_help = true;
|
||||
warning ("(so you should pass `%s' not `%s' to `va_arg')",
|
||||
pname, name);
|
||||
}
|
||||
|
||||
/* We can, however, treat "undefined" any way we please.
|
||||
Call abort to encourage the user to fix the program. */
|
||||
expand_builtin_trap ();
|
||||
|
||||
/* This is dead code, but go ahead and finish so that the
|
||||
mode of the result comes out right. */
|
||||
addr = const0_rtx;
|
||||
}
|
||||
else
|
||||
@@ -3541,6 +3569,18 @@ expand_builtin_expect_jump (exp, if_false_label, if_true_label)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
expand_builtin_trap ()
|
||||
{
|
||||
#ifdef HAVE_trap
|
||||
if (HAVE_trap)
|
||||
emit_insn (gen_trap ());
|
||||
else
|
||||
#endif
|
||||
emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
|
||||
emit_barrier ();
|
||||
}
|
||||
|
||||
/* Expand an expression EXP that calls a built-in function,
|
||||
with result going to TARGET if that's convenient
|
||||
@@ -3875,13 +3915,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
}
|
||||
|
||||
case BUILT_IN_TRAP:
|
||||
#ifdef HAVE_trap
|
||||
if (HAVE_trap)
|
||||
emit_insn (gen_trap ());
|
||||
else
|
||||
#endif
|
||||
error ("__builtin_trap not supported by this target");
|
||||
emit_barrier ();
|
||||
expand_builtin_trap ();
|
||||
return const0_rtx;
|
||||
|
||||
case BUILT_IN_PUTCHAR:
|
||||
|
||||
@@ -71,8 +71,8 @@ DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0)
|
||||
DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0)
|
||||
|
||||
/* Used to represent a 'switch' statement. The operands are
|
||||
SWITCH_COND and SWITCH_BODY, respectively. */
|
||||
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 2)
|
||||
SWITCH_COND, SWITCH_BODY and SWITCH_TYPE, respectively. */
|
||||
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 3)
|
||||
|
||||
/* Used to represent a 'goto' statement. The operand is GOTO_DESTINATION. */
|
||||
DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
|
||||
@@ -113,6 +113,11 @@ DEFTREECODE (STMT_EXPR, "stmt_expr", 'e', 1)
|
||||
the compound literal. */
|
||||
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1)
|
||||
|
||||
/* A CLEANUP_STMT marks the point at which a declaration is fully
|
||||
constructed. If, after this point, the CLEANUP_DECL goes out of
|
||||
scope, the CLEANUP_EXPR must be run. */
|
||||
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
|
||||
+17
-2
@@ -33,6 +33,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
DECL_PRETTY_FUNCTION_P (in VAR_DECL)
|
||||
NEW_FOR_SCOPE_P (in FOR_STMT)
|
||||
ASM_INPUT_P (in ASM_STMT)
|
||||
STMT_EXPR_NO_SCOPE (in STMT_EXPR)
|
||||
1: C_DECLARED_LABEL_FLAG (in LABEL_DECL)
|
||||
STMT_IS_FULL_EXPR_P (in _STMT)
|
||||
2: STMT_LINENO_FOR_FN_P (in _STMT)
|
||||
@@ -538,6 +539,7 @@ extern char *get_directive_line PARAMS ((void));
|
||||
and, if so, perhaps change them both back to their original type. */
|
||||
extern tree shorten_compare PARAMS ((tree *, tree *, tree *, enum tree_code *));
|
||||
|
||||
extern tree pointer_int_sum PARAMS ((enum tree_code, tree, tree));
|
||||
extern unsigned int min_precision PARAMS ((tree, int));
|
||||
|
||||
/* Add qualifiers to a type, in the fashion for C. */
|
||||
@@ -603,10 +605,12 @@ extern tree strip_array_types PARAMS ((tree));
|
||||
#define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
|
||||
#define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
|
||||
|
||||
/* SWITCH_STMT accessors. These give access to the condition and body
|
||||
/* SWITCH_STMT accessors. These give access to the condition, body and
|
||||
original condition type (before any compiler conversions)
|
||||
of the switch statement, respectively. */
|
||||
#define SWITCH_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
|
||||
#define SWITCH_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
|
||||
#define SWITCH_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
|
||||
|
||||
/* CASE_LABEL accessors. These give access to the high and low values
|
||||
of a case label, respectively. */
|
||||
@@ -643,6 +647,10 @@ extern tree strip_array_types PARAMS ((tree));
|
||||
/* STMT_EXPR accessor. */
|
||||
#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
|
||||
|
||||
/* Nonzero if this statement-expression does not have an associated scope. */
|
||||
#define STMT_EXPR_NO_SCOPE(NODE) \
|
||||
TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
|
||||
|
||||
/* LABEL_STMT accessor. This gives access to the label associated with
|
||||
the given label statement. */
|
||||
#define LABEL_STMT_LABEL(NODE) TREE_OPERAND (LABEL_STMT_CHECK (NODE), 0)
|
||||
@@ -694,6 +702,13 @@ extern tree strip_array_types PARAMS ((tree));
|
||||
#define ASM_VOLATILE_P(NODE) \
|
||||
(ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE)
|
||||
|
||||
/* The VAR_DECL to clean up in a CLEANUP_STMT. */
|
||||
#define CLEANUP_DECL(NODE) \
|
||||
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
|
||||
/* The cleanup to run in a CLEANUP_STMT. */
|
||||
#define CLEANUP_EXPR(NODE) \
|
||||
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
|
||||
|
||||
/* The filename we are changing to as of this FILE_STMT. */
|
||||
#define FILE_STMT_FILENAME_NODE(NODE) \
|
||||
(TREE_OPERAND (FILE_STMT_CHECK (NODE), 0))
|
||||
@@ -749,7 +764,7 @@ extern void genrtl_compound_stmt PARAMS ((tree));
|
||||
extern void genrtl_asm_stmt PARAMS ((tree, tree,
|
||||
tree, tree,
|
||||
tree, int));
|
||||
extern void genrtl_decl_cleanup PARAMS ((tree, tree));
|
||||
extern void genrtl_decl_cleanup PARAMS ((tree));
|
||||
extern int stmts_are_full_exprs_p PARAMS ((void));
|
||||
extern int anon_aggr_type_p PARAMS ((tree));
|
||||
|
||||
|
||||
+196
-155
@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "debug.h"
|
||||
#include "timevar.h"
|
||||
#include "c-common.h"
|
||||
#include "c-pragma.h"
|
||||
|
||||
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
|
||||
enum decl_context
|
||||
@@ -53,6 +54,7 @@ enum decl_context
|
||||
FUNCDEF, /* Function definition */
|
||||
PARM, /* Declaration of parm before function body */
|
||||
FIELD, /* Declaration inside struct or union */
|
||||
BITFIELD, /* Likewise but with specified width */
|
||||
TYPENAME}; /* Typename (inside cast or sizeof) */
|
||||
|
||||
|
||||
@@ -133,6 +135,11 @@ int current_function_returns_value;
|
||||
|
||||
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. */
|
||||
|
||||
int current_function_returns_abnormally;
|
||||
|
||||
/* Set to nonzero by `grokdeclarator' for a function
|
||||
whose return type is defaulted, if warnings for this are desired. */
|
||||
|
||||
@@ -275,13 +282,12 @@ static tree lookup_tag PARAMS ((enum tree_code, tree,
|
||||
struct binding_level *, int));
|
||||
static tree lookup_tag_reverse PARAMS ((tree));
|
||||
static tree grokdeclarator PARAMS ((tree, tree, enum decl_context,
|
||||
int, tree));
|
||||
int));
|
||||
static tree grokparms PARAMS ((tree, int));
|
||||
static void layout_array_type PARAMS ((tree));
|
||||
static tree c_make_fname_decl PARAMS ((tree, int));
|
||||
static void c_expand_body PARAMS ((tree, int, int));
|
||||
static void warn_if_shadowing PARAMS ((tree, tree));
|
||||
static tree build_bitfield_integer_type PARAMS ((tree, tree, const char *));
|
||||
|
||||
/* C-specific option variables. */
|
||||
|
||||
@@ -319,7 +325,7 @@ int flag_noniso_default_format_attributes = 1;
|
||||
being traditional. */
|
||||
int flag_allow_single_precision = 0;
|
||||
|
||||
/* Nonzero means to treat bit-fields as signed unless they say `unsigned'. */
|
||||
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
|
||||
|
||||
int flag_signed_bitfields = 1;
|
||||
int explicit_flag_signed_bitfields = 0;
|
||||
@@ -1543,6 +1549,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
|
||||
if (! different_binding_level)
|
||||
TREE_TYPE (olddecl) = oldtype;
|
||||
}
|
||||
else if (TYPE_ARG_TYPES (oldtype) == NULL
|
||||
&& TYPE_ARG_TYPES (newtype) != NULL)
|
||||
{
|
||||
/* For bcmp, bzero, fputs the builtin type has arguments not
|
||||
specified. Use the ones from the prototype so that type checking
|
||||
is done for them. */
|
||||
tree trytype
|
||||
= build_function_type (TREE_TYPE (oldtype),
|
||||
TYPE_ARG_TYPES (newtype));
|
||||
trytype = build_type_attribute_variant (trytype,
|
||||
TYPE_ATTRIBUTES (oldtype));
|
||||
|
||||
oldtype = trytype;
|
||||
if (! different_binding_level)
|
||||
TREE_TYPE (olddecl) = oldtype;
|
||||
}
|
||||
if (!types_match)
|
||||
{
|
||||
/* If types don't match for a built-in, throw away the built-in. */
|
||||
@@ -1669,6 +1691,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
|
||||
&& current_binding_level == global_binding_level)
|
||||
? "`%s' previously defined here"
|
||||
: "`%s' previously declared here"));
|
||||
return 0;
|
||||
}
|
||||
else if (TREE_CODE (newdecl) == TYPE_DECL
|
||||
&& (DECL_IN_SYSTEM_HEADER (olddecl)
|
||||
@@ -1932,7 +1955,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
|
||||
}
|
||||
|
||||
/* Merge the storage class information. */
|
||||
DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);
|
||||
merge_weak (newdecl, olddecl);
|
||||
|
||||
/* For functions, static overrides non-static. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
@@ -2177,11 +2201,13 @@ pushdecl (x)
|
||||
not errors. X11 for instance depends on this. */
|
||||
if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
|
||||
{
|
||||
t = lookup_name (name);
|
||||
t = IDENTIFIER_GLOBAL_VALUE (name);
|
||||
/* Type decls at global scope don't conflict with externs declared
|
||||
inside lexical blocks. */
|
||||
if (t && TREE_CODE (t) == TYPE_DECL)
|
||||
t = 0;
|
||||
if (! t || TREE_CODE (t) == TYPE_DECL)
|
||||
/* If there's no visible global declaration, try for an
|
||||
invisible one. */
|
||||
t = IDENTIFIER_LIMBO_VALUE (name);
|
||||
different_binding_level = 1;
|
||||
}
|
||||
if (t != 0 && t == error_mark_node)
|
||||
@@ -3053,8 +3079,7 @@ c_init_decl_processing ()
|
||||
boolean_true_node = integer_one_node;
|
||||
boolean_false_node = integer_zero_node;
|
||||
|
||||
/* With GCC, C99's _Bool is always of size 1. */
|
||||
c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
|
||||
c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
|
||||
TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
|
||||
TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
|
||||
TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
|
||||
@@ -3214,6 +3239,10 @@ builtin_function (name, type, function_code, class, library_name)
|
||||
DECL_BUILT_IN_CLASS (decl) = class;
|
||||
DECL_FUNCTION_CODE (decl) = function_code;
|
||||
|
||||
/* The return builtins leave the current function. */
|
||||
if (function_code == BUILT_IN_RETURN || function_code == BUILT_IN_EH_RETURN)
|
||||
TREE_THIS_VOLATILE (decl) = 1;
|
||||
|
||||
/* Warn if a function in the namespace for users
|
||||
is used without an occasion to consider it declared. */
|
||||
if (name[0] != '_' || name[1] != '_')
|
||||
@@ -3390,8 +3419,7 @@ groktypename (typename)
|
||||
|
||||
split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
|
||||
|
||||
typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
|
||||
NULL_TREE);
|
||||
typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
|
||||
|
||||
/* Apply attributes. */
|
||||
decl_attributes (&typename, attrs, 0);
|
||||
@@ -3409,7 +3437,7 @@ groktypename_in_parm_context (typename)
|
||||
return typename;
|
||||
return grokdeclarator (TREE_VALUE (typename),
|
||||
TREE_PURPOSE (typename),
|
||||
PARM, 0, NULL_TREE);
|
||||
PARM, 0);
|
||||
}
|
||||
|
||||
/* Decode a declarator in an ordinary declaration or data definition.
|
||||
@@ -3442,7 +3470,7 @@ start_decl (declarator, declspecs, initialized, attributes)
|
||||
deprecated_state = DEPRECATED_SUPPRESS;
|
||||
|
||||
decl = grokdeclarator (declarator, declspecs,
|
||||
NORMAL, initialized, NULL_TREE);
|
||||
NORMAL, initialized);
|
||||
|
||||
deprecated_state = DEPRECATED_NORMAL;
|
||||
|
||||
@@ -3551,6 +3579,10 @@ start_decl (declarator, declspecs, initialized, attributes)
|
||||
/* Set attributes here so if duplicate decl, will have proper attributes. */
|
||||
decl_attributes (&decl, attributes, 0);
|
||||
|
||||
/* If #pragma weak was used, mark the decl weak now. */
|
||||
if (current_binding_level == global_binding_level)
|
||||
maybe_apply_pragma_weak (decl);
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_DECLARED_INLINE_P (decl)
|
||||
&& DECL_UNINLINABLE (decl)
|
||||
@@ -3596,6 +3628,8 @@ finish_decl (decl, init, asmspec_tree)
|
||||
const char *asmspec = 0;
|
||||
|
||||
/* If a name was specified, get the string. */
|
||||
if (current_binding_level == global_binding_level)
|
||||
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
|
||||
if (asmspec_tree)
|
||||
asmspec = TREE_STRING_POINTER (asmspec_tree);
|
||||
|
||||
@@ -3820,8 +3854,7 @@ push_parm_decl (parm)
|
||||
immediate_size_expand = 0;
|
||||
|
||||
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
|
||||
TREE_PURPOSE (TREE_PURPOSE (parm)),
|
||||
PARM, 0, NULL_TREE);
|
||||
TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
|
||||
decl_attributes (&decl, TREE_VALUE (parm), 0);
|
||||
|
||||
#if 0
|
||||
@@ -3981,92 +4014,6 @@ complete_array_type (type, initial_value, do_default)
|
||||
return value;
|
||||
}
|
||||
|
||||
/* A bit-field NAME should have an integer type whose precision
|
||||
accurately reflects its WIDTH. If TYPE is good for that, return
|
||||
it, otherwise create and return the appropriate type.
|
||||
|
||||
This routine also performs sanity checks on the bit-field's type
|
||||
and width, and uses appropriate values if they are invalid. */
|
||||
static tree
|
||||
build_bitfield_integer_type (type, width, orig_name)
|
||||
tree type, width;
|
||||
const char *orig_name;
|
||||
{
|
||||
tree type_mv;
|
||||
unsigned int max_width;
|
||||
unsigned HOST_WIDE_INT w;
|
||||
const char *name = orig_name ? orig_name: _("<anonymous>");
|
||||
|
||||
/* Necessary? */
|
||||
STRIP_NOPS (width);
|
||||
|
||||
/* Detect and ignore out of range field width and process valid
|
||||
field widths. */
|
||||
if (TREE_CODE (width) != INTEGER_CST)
|
||||
{
|
||||
error ("bit-field `%s' width not an integer constant", name);
|
||||
width = integer_one_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
constant_expression_warning (width);
|
||||
if (tree_int_cst_sgn (width) < 0)
|
||||
{
|
||||
error ("negative width in bit-field `%s'", name);
|
||||
width = integer_one_node;
|
||||
}
|
||||
else if (integer_zerop (width) && orig_name)
|
||||
{
|
||||
error ("zero width for bit-field `%s'", name);
|
||||
width = integer_one_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Detect invalid bit-field type. */
|
||||
if (TREE_CODE (type) != INTEGER_TYPE
|
||||
&& TREE_CODE (type) != BOOLEAN_TYPE
|
||||
&& TREE_CODE (type) != ENUMERAL_TYPE)
|
||||
{
|
||||
error ("bit-field `%s' has invalid type", name);
|
||||
type = unsigned_type_node;
|
||||
}
|
||||
|
||||
type_mv = TYPE_MAIN_VARIANT (type);
|
||||
if (pedantic
|
||||
&& type_mv != integer_type_node
|
||||
&& type_mv != unsigned_type_node
|
||||
&& type_mv != c_bool_type_node
|
||||
/* Accept an enum that's equivalent to int or unsigned int. */
|
||||
&& (TREE_CODE (type) != ENUMERAL_TYPE
|
||||
|| TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)))
|
||||
pedwarn ("type of bit-field `%s' is a GCC extension", name);
|
||||
|
||||
if (type_mv == c_bool_type_node)
|
||||
max_width = CHAR_TYPE_SIZE;
|
||||
else
|
||||
max_width = TYPE_PRECISION (type);
|
||||
|
||||
if (0 < compare_tree_int (width, max_width))
|
||||
{
|
||||
error ("width of `%s' exceeds its type", name);
|
||||
w = max_width;
|
||||
}
|
||||
else
|
||||
w = tree_low_cst (width, 1);
|
||||
|
||||
if (TREE_CODE (type) == ENUMERAL_TYPE
|
||||
&& (w < min_precision (TYPE_MIN_VALUE (type), TREE_UNSIGNED (type))
|
||||
|| w < min_precision (TYPE_MAX_VALUE (type), TREE_UNSIGNED (type))))
|
||||
warning ("`%s' is narrower than values of its type", name);
|
||||
|
||||
/* The type of a bit-field should have precision the same as the
|
||||
bit-field's width. */
|
||||
if (w != TYPE_PRECISION (type))
|
||||
type = build_nonstandard_integer_type (w, TREE_UNSIGNED (type));
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Given declspecs and a declarator,
|
||||
determine the name and type of the object declared
|
||||
and construct a ..._DECL node for it.
|
||||
@@ -4086,9 +4033,8 @@ build_bitfield_integer_type (type, width, orig_name)
|
||||
TYPENAME if for a typename (in a cast or sizeof).
|
||||
Don't make a DECL node; just return the ..._TYPE node.
|
||||
FIELD for a struct or union field; make a FIELD_DECL.
|
||||
BITFIELD for a field with specified width.
|
||||
INITIALIZED is 1 if the decl has an initializer.
|
||||
WIDTH is non-NULL for bit-fields, and is an INTEGER_CST node representing
|
||||
the width of the bit-field.
|
||||
|
||||
In the TYPENAME case, DECLARATOR is really an absolute declarator.
|
||||
It may also be so in the PARM case, for a prototype where the
|
||||
@@ -4098,12 +4044,11 @@ build_bitfield_integer_type (type, width, orig_name)
|
||||
and `extern' are interpreted. */
|
||||
|
||||
static tree
|
||||
grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
tree declspecs;
|
||||
tree declarator;
|
||||
enum decl_context decl_context;
|
||||
int initialized;
|
||||
tree width;
|
||||
{
|
||||
int specbits = 0;
|
||||
tree spec;
|
||||
@@ -4118,16 +4063,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
int explicit_char = 0;
|
||||
int defaulted_int = 0;
|
||||
tree typedef_decl = 0;
|
||||
const char *name, *orig_name;
|
||||
const char *name;
|
||||
tree typedef_type = 0;
|
||||
int funcdef_flag = 0;
|
||||
enum tree_code innermost_code = ERROR_MARK;
|
||||
int bitfield = 0;
|
||||
int size_varies = 0;
|
||||
tree decl_attr = NULL_TREE;
|
||||
tree array_ptr_quals = NULL_TREE;
|
||||
int array_parm_static = 0;
|
||||
tree returned_attrs = NULL_TREE;
|
||||
bool bitfield = width != NULL_TREE;
|
||||
|
||||
if (decl_context == BITFIELD)
|
||||
bitfield = 1, decl_context = FIELD;
|
||||
|
||||
if (decl_context == FUNCDEF)
|
||||
funcdef_flag = 1, decl_context = NORMAL;
|
||||
@@ -4160,7 +4108,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
orig_name = name;
|
||||
if (name == 0)
|
||||
name = "type name";
|
||||
}
|
||||
@@ -4377,9 +4324,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
}
|
||||
|
||||
/* Decide whether an integer type is signed or not.
|
||||
Optionally treat bit-fields as signed by default. */
|
||||
Optionally treat bitfields as signed by default. */
|
||||
if (specbits & 1 << (int) RID_UNSIGNED
|
||||
/* Traditionally, all bit-fields are unsigned. */
|
||||
/* Traditionally, all bitfields are unsigned. */
|
||||
|| (bitfield && flag_traditional
|
||||
&& (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
|
||||
|| (bitfield && ! flag_signed_bitfields
|
||||
@@ -4452,11 +4399,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
}
|
||||
}
|
||||
|
||||
/* A bit-field needs its type to have precision equal to its width,
|
||||
rather than the precision of the specified standard type. */
|
||||
if (bitfield)
|
||||
type = build_bitfield_integer_type (type, width, orig_name);
|
||||
|
||||
/* Figure out the type qualifiers for the declaration. There are
|
||||
two ways a declaration can become qualified. One is something
|
||||
like `const int i' where the `const' is explicit. Another is
|
||||
@@ -4602,9 +4544,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
if (inner_decl == NULL_TREE
|
||||
|| TREE_CODE (inner_decl) == IDENTIFIER_NODE)
|
||||
attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
|
||||
if (TREE_CODE (inner_decl) == CALL_EXPR)
|
||||
else if (TREE_CODE (inner_decl) == CALL_EXPR)
|
||||
attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
|
||||
if (TREE_CODE (inner_decl) == ARRAY_REF)
|
||||
else if (TREE_CODE (inner_decl) == ARRAY_REF)
|
||||
attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
|
||||
returned_attrs = decl_attributes (&type,
|
||||
chainon (returned_attrs, attrs),
|
||||
@@ -4723,10 +4665,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
}
|
||||
else if (decl_context == FIELD)
|
||||
{
|
||||
/* ??? Need to check somewhere that this is a structure
|
||||
and not a union, that this field is last, and that
|
||||
this structure has at least one other named member. */
|
||||
|
||||
if (pedantic && !flag_isoc99 && !in_system_header)
|
||||
pedwarn ("ISO C89 does not support flexible array members");
|
||||
|
||||
@@ -5106,6 +5044,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
else if (decl_context == FIELD)
|
||||
{
|
||||
/* Structure field. It may not be a function. */
|
||||
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
{
|
||||
error ("field `%s' declared as a function", name);
|
||||
@@ -5129,29 +5068,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
#endif
|
||||
}
|
||||
decl = build_decl (FIELD_DECL, declarator, type);
|
||||
if (bitfield)
|
||||
{
|
||||
DECL_SIZE (decl) = bitsize_int (TYPE_PRECISION (type));
|
||||
DECL_BIT_FIELD (decl) = 1;
|
||||
SET_DECL_C_BIT_FIELD (decl);
|
||||
|
||||
/* Bit-field width 0 => force desired amount of alignment. */
|
||||
if (TYPE_PRECISION (type) == 0)
|
||||
{
|
||||
#ifdef EMPTY_FIELD_BOUNDARY
|
||||
DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
|
||||
EMPTY_FIELD_BOUNDARY);
|
||||
#endif
|
||||
#ifdef PCC_BITFIELD_TYPE_MATTERS
|
||||
if (PCC_BITFIELD_TYPE_MATTERS)
|
||||
{
|
||||
DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
|
||||
TYPE_ALIGN (type));
|
||||
DECL_USER_ALIGN (decl) |= TYPE_USER_ALIGN (type);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
DECL_NONADDRESSABLE_P (decl) = bitfield;
|
||||
|
||||
if (size_varies)
|
||||
@@ -5201,6 +5117,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
|
||||
TREE_PUBLIC (decl)
|
||||
= !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
|
||||
|
||||
if (defaulted_int)
|
||||
C_FUNCTION_IMPLICIT_INT (decl) = 1;
|
||||
|
||||
/* Record presence of `inline', if it is reasonable. */
|
||||
if (MAIN_NAME_P (declarator))
|
||||
{
|
||||
@@ -5654,7 +5573,7 @@ start_struct (code, name)
|
||||
|
||||
/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
|
||||
of a structure component, returning a FIELD_DECL node.
|
||||
WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
|
||||
WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
|
||||
|
||||
This is done during the parsing of the struct declaration.
|
||||
The FIELD_DECL nodes are chained together and the lot of them
|
||||
@@ -5680,9 +5599,10 @@ grokfield (filename, line, declarator, declspecs, width)
|
||||
}
|
||||
}
|
||||
|
||||
value = grokdeclarator (declarator, declspecs, FIELD, 0, width);
|
||||
value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
|
||||
|
||||
finish_decl (value, NULL_TREE, NULL_TREE);
|
||||
DECL_INITIAL (value) = width;
|
||||
|
||||
maybe_objc_check_decl (value);
|
||||
return value;
|
||||
@@ -5734,7 +5654,10 @@ finish_struct (t, fieldlist, attributes)
|
||||
fieldlist ? _("named members") : _("members"));
|
||||
}
|
||||
|
||||
/* Install struct as DECL_CONTEXT of each field decl. */
|
||||
/* Install struct as DECL_CONTEXT of each field decl.
|
||||
Also process specified field sizes,m which is found in the DECL_INITIAL.
|
||||
Store 0 there, except for ": 0" fields (so we can find them
|
||||
and delete them, below). */
|
||||
|
||||
saw_named_field = 0;
|
||||
for (x = fieldlist; x; x = TREE_CHAIN (x))
|
||||
@@ -5770,7 +5693,94 @@ finish_struct (t, fieldlist, attributes)
|
||||
error ("nested redefinition of `%s'",
|
||||
IDENTIFIER_POINTER (TYPE_NAME (t)));
|
||||
|
||||
if (TREE_TYPE (x) != error_mark_node && !DECL_BIT_FIELD (x))
|
||||
/* Detect invalid bit-field size. */
|
||||
if (DECL_INITIAL (x))
|
||||
STRIP_NOPS (DECL_INITIAL (x));
|
||||
if (DECL_INITIAL (x))
|
||||
{
|
||||
if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
|
||||
constant_expression_warning (DECL_INITIAL (x));
|
||||
else
|
||||
{
|
||||
error_with_decl (x,
|
||||
"bit-field `%s' width not an integer constant");
|
||||
DECL_INITIAL (x) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Detect invalid bit-field type. */
|
||||
if (DECL_INITIAL (x)
|
||||
&& TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
|
||||
{
|
||||
error_with_decl (x, "bit-field `%s' has invalid type");
|
||||
DECL_INITIAL (x) = NULL;
|
||||
}
|
||||
|
||||
if (DECL_INITIAL (x) && pedantic
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
|
||||
/* Accept an enum that's equivalent to int or unsigned int. */
|
||||
&& !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
|
||||
&& (TYPE_PRECISION (TREE_TYPE (x))
|
||||
== TYPE_PRECISION (integer_type_node))))
|
||||
pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
|
||||
|
||||
/* Detect and ignore out of range field width and process valid
|
||||
field widths. */
|
||||
if (DECL_INITIAL (x))
|
||||
{
|
||||
int max_width
|
||||
= (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
|
||||
? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
|
||||
|
||||
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
|
||||
error_with_decl (x, "negative width in bit-field `%s'");
|
||||
else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
|
||||
pedwarn_with_decl (x, "width of `%s' exceeds its type");
|
||||
else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
|
||||
error_with_decl (x, "zero width for bit-field `%s'");
|
||||
else
|
||||
{
|
||||
/* The test above has assured us that TREE_INT_CST_HIGH is 0. */
|
||||
unsigned HOST_WIDE_INT width
|
||||
= tree_low_cst (DECL_INITIAL (x), 1);
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
|
||||
&& (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
|
||||
TREE_UNSIGNED (TREE_TYPE (x)))
|
||||
|| (width
|
||||
< min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
|
||||
TREE_UNSIGNED (TREE_TYPE (x))))))
|
||||
warning_with_decl (x,
|
||||
"`%s' is narrower than values of its type");
|
||||
|
||||
DECL_SIZE (x) = bitsize_int (width);
|
||||
DECL_BIT_FIELD (x) = 1;
|
||||
SET_DECL_C_BIT_FIELD (x);
|
||||
|
||||
if (width == 0
|
||||
&& ! (* targetm.ms_bitfield_layout_p) (t))
|
||||
{
|
||||
/* field size 0 => force desired amount of alignment. */
|
||||
#ifdef EMPTY_FIELD_BOUNDARY
|
||||
DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
|
||||
#endif
|
||||
#ifdef PCC_BITFIELD_TYPE_MATTERS
|
||||
if (PCC_BITFIELD_TYPE_MATTERS)
|
||||
{
|
||||
DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
|
||||
TYPE_ALIGN (TREE_TYPE (x)));
|
||||
DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (TREE_TYPE (x) != error_mark_node)
|
||||
{
|
||||
unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
|
||||
: TYPE_ALIGN (TREE_TYPE (x)));
|
||||
@@ -5782,6 +5792,8 @@ finish_struct (t, fieldlist, attributes)
|
||||
DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
|
||||
}
|
||||
|
||||
DECL_INITIAL (x) = 0;
|
||||
|
||||
/* Detect flexible array member in an invalid context. */
|
||||
if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
|
||||
&& TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
|
||||
@@ -6197,6 +6209,7 @@ start_function (declspecs, declarator, attributes)
|
||||
|
||||
current_function_returns_value = 0; /* Assume, until we see it does. */
|
||||
current_function_returns_null = 0;
|
||||
current_function_returns_abnormally = 0;
|
||||
warn_about_return_type = 0;
|
||||
current_extern_inline = 0;
|
||||
c_function_varargs = 0;
|
||||
@@ -6206,7 +6219,7 @@ start_function (declspecs, declarator, attributes)
|
||||
/* Don't expand any sizes in the return type of the function. */
|
||||
immediate_size_expand = 0;
|
||||
|
||||
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE);
|
||||
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
|
||||
|
||||
/* If the declarator is not suitable for a function definition,
|
||||
cause a syntax error. */
|
||||
@@ -6218,6 +6231,10 @@ start_function (declspecs, declarator, attributes)
|
||||
|
||||
decl_attributes (&decl1, attributes, 0);
|
||||
|
||||
/* If #pragma weak was used, mark the decl weak now. */
|
||||
if (current_binding_level == global_binding_level)
|
||||
maybe_apply_pragma_weak (decl1);
|
||||
|
||||
if (DECL_DECLARED_INLINE_P (decl1)
|
||||
&& DECL_UNINLINABLE (decl1)
|
||||
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
|
||||
@@ -6874,17 +6891,21 @@ store_parm_decls ()
|
||||
|
||||
This is called after parsing the body of the function definition.
|
||||
|
||||
NESTED is nonzero if the function being finished is nested in another. */
|
||||
NESTED is nonzero if the function being finished is nested in another.
|
||||
CAN_DEFER_P is nonzero if the function may be deferred. */
|
||||
|
||||
void
|
||||
finish_function (nested)
|
||||
finish_function (nested, can_defer_p)
|
||||
int nested;
|
||||
int can_defer_p;
|
||||
{
|
||||
tree fndecl = current_function_decl;
|
||||
|
||||
/* TREE_READONLY (fndecl) = 1;
|
||||
This caused &foo to be of type ptr-to-const-function
|
||||
which then got a warning when stored in a ptr-to-function variable. */
|
||||
#if 0
|
||||
/* This caused &foo to be of type ptr-to-const-function which then
|
||||
got a warning when stored in a ptr-to-function variable. */
|
||||
TREE_READONLY (fndecl) = 1;
|
||||
#endif
|
||||
|
||||
poplevel (1, 0, 1);
|
||||
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
|
||||
@@ -6926,6 +6947,22 @@ finish_function (nested)
|
||||
|
||||
/* Tie off the statement tree for this function. */
|
||||
finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
|
||||
|
||||
/* Complain if there's just no return statement. */
|
||||
if (warn_return_type
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
|
||||
&& !current_function_returns_value && !current_function_returns_null
|
||||
/* Don't complain if we abort. */
|
||||
&& !current_function_returns_abnormally
|
||||
/* Don't warn for main(). */
|
||||
&& !MAIN_NAME_P (DECL_NAME (fndecl))
|
||||
/* Or if they didn't actually specify a return type. */
|
||||
&& !C_FUNCTION_IMPLICIT_INT (fndecl)
|
||||
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
|
||||
inline function, as we might never be compiled separately. */
|
||||
&& DECL_INLINE (fndecl))
|
||||
warning ("no return statement in function returning non-void");
|
||||
|
||||
/* Clear out memory we no longer need. */
|
||||
free_after_parsing (cfun);
|
||||
/* Since we never call rest_of_compilation, we never clear
|
||||
@@ -6936,7 +6973,8 @@ finish_function (nested)
|
||||
if (! nested)
|
||||
{
|
||||
/* Generate RTL for the body of this function. */
|
||||
c_expand_body (fndecl, nested, 1);
|
||||
c_expand_body (fndecl, nested, can_defer_p);
|
||||
|
||||
/* Let the error reporting routines know that we're outside a
|
||||
function. For a nested function, this value is used in
|
||||
pop_c_function_context and then reset via pop_function_context. */
|
||||
@@ -7215,6 +7253,7 @@ struct c_language_function
|
||||
tree shadowed_labels;
|
||||
int returns_value;
|
||||
int returns_null;
|
||||
int returns_abnormally;
|
||||
int warn_about_return_type;
|
||||
int extern_inline;
|
||||
struct binding_level *binding_level;
|
||||
@@ -7238,6 +7277,7 @@ push_c_function_context (f)
|
||||
p->shadowed_labels = shadowed_labels;
|
||||
p->returns_value = current_function_returns_value;
|
||||
p->returns_null = current_function_returns_null;
|
||||
p->returns_abnormally = current_function_returns_abnormally;
|
||||
p->warn_about_return_type = warn_about_return_type;
|
||||
p->extern_inline = current_extern_inline;
|
||||
p->binding_level = current_binding_level;
|
||||
@@ -7275,6 +7315,7 @@ pop_c_function_context (f)
|
||||
shadowed_labels = p->shadowed_labels;
|
||||
current_function_returns_value = p->returns_value;
|
||||
current_function_returns_null = p->returns_null;
|
||||
current_function_returns_abnormally = p->returns_abnormally;
|
||||
warn_about_return_type = p->warn_about_return_type;
|
||||
current_extern_inline = p->extern_inline;
|
||||
current_binding_level = p->binding_level;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Check calls to formatted I/O functions (-Wformat).
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@@ -1516,13 +1516,12 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num)
|
||||
res->number_non_literal++;
|
||||
return;
|
||||
}
|
||||
if (!host_integerp (arg1, 1))
|
||||
if (!host_integerp (arg1, 0)
|
||||
|| (offset = tree_low_cst (arg1, 0)) < 0)
|
||||
{
|
||||
res->number_non_literal++;
|
||||
return;
|
||||
}
|
||||
|
||||
offset = TREE_INT_CST_LOW (arg1);
|
||||
}
|
||||
if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,9 @@ static void c_post_options PARAMS ((void));
|
||||
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
|
||||
anon_aggr_type_p
|
||||
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
c_convert_parm_for_inlining
|
||||
|
||||
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
|
||||
|
||||
|
||||
+32
-16
@@ -85,7 +85,8 @@ static int ignore_escape_flag;
|
||||
|
||||
static void parse_float PARAMS ((PTR));
|
||||
static tree lex_number PARAMS ((const char *, unsigned int));
|
||||
static tree lex_string PARAMS ((const char *, unsigned int, int));
|
||||
static tree lex_string PARAMS ((const unsigned char *, unsigned int,
|
||||
int));
|
||||
static tree lex_charconst PARAMS ((const cpp_token *));
|
||||
static void update_header_times PARAMS ((const char *));
|
||||
static int dump_one_header PARAMS ((splay_tree_node, void *));
|
||||
@@ -239,7 +240,7 @@ cb_ident (pfile, line, str)
|
||||
if (! flag_no_ident)
|
||||
{
|
||||
/* Convert escapes in the string. */
|
||||
tree value = lex_string ((const char *)str->text, str->len, 0);
|
||||
tree value = lex_string (str->text, str->len, 0);
|
||||
ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
|
||||
}
|
||||
#endif
|
||||
@@ -271,10 +272,12 @@ cb_file_change (pfile, new_map)
|
||||
main_input_filename = new_map->to_file;
|
||||
else
|
||||
{
|
||||
lineno = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
|
||||
int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
|
||||
|
||||
lineno = included_at;
|
||||
push_srcloc (new_map->to_file, 1);
|
||||
input_file_stack->indent_level = indent_level;
|
||||
(*debug_hooks->start_source_file) (lineno, new_map->to_file);
|
||||
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
|
||||
#ifndef NO_IMPLICIT_EXTERN_C
|
||||
if (c_header_level)
|
||||
++c_header_level;
|
||||
@@ -807,8 +810,8 @@ c_lex (value)
|
||||
|
||||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
*value = lex_string ((const char *)tok->val.str.text,
|
||||
tok->val.str.len, tok->type == CPP_WSTRING);
|
||||
*value = lex_string (tok->val.str.text, tok->val.str.len,
|
||||
tok->type == CPP_WSTRING);
|
||||
break;
|
||||
|
||||
/* These tokens should not be visible outside cpplib. */
|
||||
@@ -1297,14 +1300,14 @@ lex_number (str, len)
|
||||
|
||||
static tree
|
||||
lex_string (str, len, wide)
|
||||
const char *str;
|
||||
const unsigned char *str;
|
||||
unsigned int len;
|
||||
int wide;
|
||||
{
|
||||
tree value;
|
||||
char *buf = alloca ((len + 1) * (wide ? WCHAR_BYTES : 1));
|
||||
char *q = buf;
|
||||
const char *p = str, *limit = str + len;
|
||||
const unsigned char *p = str, *limit = str + len;
|
||||
unsigned int c;
|
||||
unsigned width = wide ? WCHAR_TYPE_SIZE
|
||||
: TYPE_PRECISION (char_type_node);
|
||||
@@ -1320,7 +1323,7 @@ lex_string (str, len, wide)
|
||||
wchar_t wc;
|
||||
int char_len;
|
||||
|
||||
char_len = local_mbtowc (&wc, p, limit - p);
|
||||
char_len = local_mbtowc (&wc, (const char *) p, limit - p);
|
||||
if (char_len == -1)
|
||||
{
|
||||
warning ("ignoring invalid multibyte character");
|
||||
@@ -1344,8 +1347,7 @@ lex_string (str, len, wide)
|
||||
mask = ((unsigned int) 1 << width) - 1;
|
||||
else
|
||||
mask = ~0;
|
||||
c = cpp_parse_escape (parse_in, (const unsigned char **) &p,
|
||||
(const unsigned char *) limit,
|
||||
c = cpp_parse_escape (parse_in, &p, limit,
|
||||
mask, flag_traditional);
|
||||
}
|
||||
|
||||
@@ -1405,7 +1407,7 @@ lex_charconst (token)
|
||||
const cpp_token *token;
|
||||
{
|
||||
HOST_WIDE_INT result;
|
||||
tree value;
|
||||
tree type, value;
|
||||
unsigned int chars_seen;
|
||||
|
||||
result = cpp_interpret_charconst (parse_in, token, warn_multichar,
|
||||
@@ -1413,7 +1415,7 @@ lex_charconst (token)
|
||||
if (token->type == CPP_WCHAR)
|
||||
{
|
||||
value = build_int_2 (result, 0);
|
||||
TREE_TYPE (value) = wchar_type_node;
|
||||
type = wchar_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1425,10 +1427,24 @@ lex_charconst (token)
|
||||
/* In C, a character constant has type 'int'.
|
||||
In C++ 'char', but multi-char charconsts have type 'int'. */
|
||||
if (c_language == clk_cplusplus && chars_seen <= 1)
|
||||
TREE_TYPE (value) = char_type_node;
|
||||
type = char_type_node;
|
||||
else
|
||||
TREE_TYPE (value) = integer_type_node;
|
||||
type = integer_type_node;
|
||||
}
|
||||
|
||||
|
||||
/* cpp_interpret_charconst issues a warning if the constant
|
||||
overflows, but if the number fits in HOST_WIDE_INT anyway, it
|
||||
will return it un-truncated, which may cause problems down the
|
||||
line. So set the type to widest_integer_literal_type, call
|
||||
convert to truncate it to the proper type, then clear
|
||||
TREE_OVERFLOW so we don't get a second warning.
|
||||
|
||||
FIXME: cpplib's assessment of overflow may not be accurate on a
|
||||
platform where the final type can change at (compiler's) runtime. */
|
||||
|
||||
TREE_TYPE (value) = widest_integer_literal_type_node;
|
||||
value = convert (type, value);
|
||||
TREE_OVERFLOW (value) = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ int
|
||||
c_disregard_inline_limits (fn)
|
||||
tree fn;
|
||||
{
|
||||
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
|
||||
return 1;
|
||||
|
||||
return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
|
||||
}
|
||||
|
||||
@@ -142,6 +145,10 @@ c_cannot_inline_tree_fn (fnp)
|
||||
tree fn = *fnp;
|
||||
tree t;
|
||||
|
||||
if (flag_really_no_inline
|
||||
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
|
||||
return 1;
|
||||
|
||||
if (! function_attribute_inlinable_p (fn))
|
||||
{
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
@@ -317,7 +324,7 @@ finish_cdtor (body)
|
||||
|
||||
RECHAIN_STMTS (body, COMPOUND_BODY (body));
|
||||
|
||||
finish_function (0);
|
||||
finish_function (0, 0);
|
||||
}
|
||||
|
||||
/* Called at end of parsing, but before end-of-file processing. */
|
||||
|
||||
+10
-6
@@ -395,7 +395,7 @@ fndef:
|
||||
save_filename save_lineno compstmt_or_error
|
||||
{ DECL_SOURCE_FILE (current_function_decl) = $7;
|
||||
DECL_SOURCE_LINE (current_function_decl) = $8;
|
||||
finish_function (0);
|
||||
finish_function (0, 1);
|
||||
POP_DECLSPEC_STACK; }
|
||||
| declspecs_ts setspecs declarator error
|
||||
{ POP_DECLSPEC_STACK; }
|
||||
@@ -409,7 +409,7 @@ fndef:
|
||||
save_filename save_lineno compstmt_or_error
|
||||
{ DECL_SOURCE_FILE (current_function_decl) = $7;
|
||||
DECL_SOURCE_LINE (current_function_decl) = $8;
|
||||
finish_function (0);
|
||||
finish_function (0, 1);
|
||||
POP_DECLSPEC_STACK; }
|
||||
| declspecs_nots setspecs notype_declarator error
|
||||
{ POP_DECLSPEC_STACK; }
|
||||
@@ -423,7 +423,7 @@ fndef:
|
||||
save_filename save_lineno compstmt_or_error
|
||||
{ DECL_SOURCE_FILE (current_function_decl) = $6;
|
||||
DECL_SOURCE_LINE (current_function_decl) = $7;
|
||||
finish_function (0);
|
||||
finish_function (0, 1);
|
||||
POP_DECLSPEC_STACK; }
|
||||
| setspecs notype_declarator error
|
||||
{ POP_DECLSPEC_STACK; }
|
||||
@@ -1582,7 +1582,7 @@ nested_function:
|
||||
{ tree decl = current_function_decl;
|
||||
DECL_SOURCE_FILE (decl) = $5;
|
||||
DECL_SOURCE_LINE (decl) = $6;
|
||||
finish_function (1);
|
||||
finish_function (1, 1);
|
||||
pop_function_context ();
|
||||
add_decl_stmt (decl); }
|
||||
;
|
||||
@@ -1612,7 +1612,7 @@ notype_nested_function:
|
||||
{ tree decl = current_function_decl;
|
||||
DECL_SOURCE_FILE (decl) = $5;
|
||||
DECL_SOURCE_LINE (decl) = $6;
|
||||
finish_function (1);
|
||||
finish_function (1, 1);
|
||||
pop_function_context ();
|
||||
add_decl_stmt (decl); }
|
||||
;
|
||||
@@ -2067,6 +2067,7 @@ end ifobjc
|
||||
|
||||
poplevel: /* empty */
|
||||
{ $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); }
|
||||
;
|
||||
|
||||
/* Start and end blocks created for the new scopes of C99. */
|
||||
c99_block_start: /* empty */
|
||||
@@ -2137,7 +2138,8 @@ compstmt_or_error:
|
||||
;
|
||||
|
||||
compstmt_start: '{' { compstmt_count++;
|
||||
$$ = c_begin_compound_stmt (); }
|
||||
$$ = c_begin_compound_stmt (); }
|
||||
;
|
||||
|
||||
compstmt_nostart: '}'
|
||||
{ $$ = convert (void_type_node, integer_zero_node); }
|
||||
@@ -2169,9 +2171,11 @@ compstmt_primary_start:
|
||||
compstmt_count++;
|
||||
$$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree));
|
||||
}
|
||||
;
|
||||
|
||||
compstmt: compstmt_start compstmt_nostart
|
||||
{ RECHAIN_STMTS ($1, COMPOUND_BODY ($1));
|
||||
last_expr_type = NULL_TREE;
|
||||
$$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
+200
-6
@@ -1,5 +1,5 @@
|
||||
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
|
||||
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001
|
||||
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "c-lex.h"
|
||||
#include "c-common.h"
|
||||
#include "output.h"
|
||||
#include "tm_p.h"
|
||||
|
||||
@@ -55,9 +56,9 @@ static struct align_stack * alignment_stack = NULL;
|
||||
maximum_field_alignment in effect. When the final pop_alignment()
|
||||
happens, we restore the value to this, not to a value of 0 for
|
||||
maximum_field_alignment. Value is in bits. */
|
||||
static int default_alignment;
|
||||
static int default_alignment;
|
||||
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
|
||||
(default_alignment = maximum_field_alignment = (ALIGN))
|
||||
(default_alignment = maximum_field_alignment = (ALIGN))
|
||||
|
||||
static void push_alignment PARAMS ((int, tree));
|
||||
static void pop_alignment PARAMS ((tree));
|
||||
@@ -69,7 +70,6 @@ push_alignment (alignment, id)
|
||||
int alignment;
|
||||
tree id;
|
||||
{
|
||||
|
||||
if (alignment_stack == NULL
|
||||
|| alignment_stack->alignment != alignment
|
||||
|| id != NULL_TREE)
|
||||
@@ -274,14 +274,57 @@ handle_pragma_pack (dummy)
|
||||
#endif /* HANDLE_PRAGMA_PACK */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
static void apply_pragma_weak PARAMS ((tree, tree));
|
||||
static void handle_pragma_weak PARAMS ((cpp_reader *));
|
||||
|
||||
static tree pending_weaks;
|
||||
|
||||
static void
|
||||
apply_pragma_weak (decl, value)
|
||||
tree decl, value;
|
||||
{
|
||||
if (value)
|
||||
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
|
||||
build_tree_list (NULL, value)),
|
||||
0);
|
||||
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
|
||||
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|
||||
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
|
||||
|
||||
declare_weak (decl);
|
||||
}
|
||||
|
||||
void
|
||||
maybe_apply_pragma_weak (decl)
|
||||
tree decl;
|
||||
{
|
||||
tree *p, t, id;
|
||||
|
||||
/* Copied from the check in set_decl_assembler_name. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (TREE_CODE (decl) == VAR_DECL
|
||||
&& (TREE_STATIC (decl)
|
||||
|| DECL_EXTERNAL (decl)
|
||||
|| TREE_PUBLIC (decl))))
|
||||
id = DECL_ASSEMBLER_NAME (decl);
|
||||
else
|
||||
return;
|
||||
|
||||
for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
|
||||
if (id == TREE_PURPOSE (t))
|
||||
{
|
||||
apply_pragma_weak (decl, TREE_VALUE (t));
|
||||
*p = TREE_CHAIN (t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* #pragma weak name [= value] */
|
||||
static void
|
||||
handle_pragma_weak (dummy)
|
||||
cpp_reader *dummy ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree name, value, x;
|
||||
tree name, value, x, decl;
|
||||
enum cpp_ttype t;
|
||||
|
||||
value = 0;
|
||||
@@ -298,10 +341,149 @@ handle_pragma_weak (dummy)
|
||||
if (t != CPP_EOF)
|
||||
warning ("junk at end of #pragma weak");
|
||||
|
||||
add_weak (IDENTIFIER_POINTER (name), value ? IDENTIFIER_POINTER (value) : 0);
|
||||
decl = identifier_global_value (name);
|
||||
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
|
||||
apply_pragma_weak (decl, value);
|
||||
else
|
||||
pending_weaks = tree_cons (name, value, pending_weaks);
|
||||
}
|
||||
#else
|
||||
void
|
||||
maybe_apply_pragma_weak (decl)
|
||||
tree decl ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
|
||||
|
||||
static tree pending_redefine_extname;
|
||||
|
||||
/* #pragma redefined_extname oldname newname */
|
||||
static void
|
||||
handle_pragma_redefine_extname (dummy)
|
||||
cpp_reader *dummy ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree oldname, newname, decl, x;
|
||||
enum cpp_ttype t;
|
||||
|
||||
if (c_lex (&oldname) != CPP_NAME)
|
||||
{
|
||||
warning ("malformed #pragma redefine_extname, ignored");
|
||||
return;
|
||||
}
|
||||
if (c_lex (&newname) != CPP_NAME)
|
||||
{
|
||||
warning ("malformed #pragma redefine_extname, ignored");
|
||||
return;
|
||||
}
|
||||
t = c_lex (&x);
|
||||
if (t != CPP_EOF)
|
||||
warning ("junk at end of #pragma redefine_extname");
|
||||
|
||||
decl = identifier_global_value (oldname);
|
||||
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
|
||||
{
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl)
|
||||
&& DECL_ASSEMBLER_NAME (decl) != newname)
|
||||
warning ("#pragma redefine_extname conflicts with declaration");
|
||||
SET_DECL_ASSEMBLER_NAME (decl, newname);
|
||||
}
|
||||
else
|
||||
pending_redefine_extname
|
||||
= tree_cons (oldname, newname, pending_redefine_extname);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
|
||||
|
||||
static tree pragma_extern_prefix;
|
||||
|
||||
/* #pragma extern_prefix "prefix" */
|
||||
static void
|
||||
handle_pragma_extern_prefix (dummy)
|
||||
cpp_reader *dummy ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree prefix, x;
|
||||
enum cpp_ttype t;
|
||||
|
||||
if (c_lex (&prefix) != CPP_STRING)
|
||||
{
|
||||
warning ("malformed #pragma extern_prefix, ignored");
|
||||
return;
|
||||
}
|
||||
t = c_lex (&x);
|
||||
if (t != CPP_EOF)
|
||||
warning ("junk at end of #pragma extern_prefix");
|
||||
|
||||
/* Note that the length includes the null terminator. */
|
||||
pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Hook from the front ends to apply the results of one of the preceeding
|
||||
pragmas that rename variables. */
|
||||
|
||||
tree
|
||||
maybe_apply_renaming_pragma (decl, asmname)
|
||||
tree decl, asmname;
|
||||
{
|
||||
tree oldname;
|
||||
|
||||
/* Copied from the check in set_decl_assembler_name. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (TREE_CODE (decl) == VAR_DECL
|
||||
&& (TREE_STATIC (decl)
|
||||
|| DECL_EXTERNAL (decl)
|
||||
|| TREE_PUBLIC (decl))))
|
||||
oldname = DECL_ASSEMBLER_NAME (decl);
|
||||
else
|
||||
return asmname;
|
||||
|
||||
/* If the name begins with a *, that's a sign of an asmname attached to
|
||||
a previous declaration. */
|
||||
if (IDENTIFIER_POINTER (oldname)[0] == '*')
|
||||
{
|
||||
const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
|
||||
if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
|
||||
warning ("asm declaration conficts with previous rename");
|
||||
asmname = build_string (strlen (oldasmname), oldasmname);
|
||||
}
|
||||
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
{
|
||||
tree *p, t;
|
||||
|
||||
for (p = &pending_redefine_extname; (t = *p) ; p = &TREE_CHAIN (t))
|
||||
if (oldname == TREE_PURPOSE (t))
|
||||
{
|
||||
const char *newname = IDENTIFIER_POINTER (TREE_VALUE (t));
|
||||
|
||||
if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
|
||||
warning ("#pragma redefine_extname conflicts with declaration");
|
||||
*p = TREE_CHAIN (t);
|
||||
|
||||
return build_string (strlen (newname), newname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
if (pragma_extern_prefix && !asmname)
|
||||
{
|
||||
char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
|
||||
IDENTIFIER_POINTER (oldname), NULL);
|
||||
asmname = build_string (strlen (x), x);
|
||||
free (x);
|
||||
return asmname;
|
||||
}
|
||||
#endif
|
||||
|
||||
return asmname;
|
||||
}
|
||||
|
||||
void
|
||||
init_pragma ()
|
||||
{
|
||||
@@ -310,7 +492,19 @@ init_pragma ()
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
|
||||
ggc_add_tree_root (&pending_weaks, 1);
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
cpp_register_pragma (parse_in, 0, "redefine_extname",
|
||||
handle_pragma_redefine_extname);
|
||||
ggc_add_tree_root (&pending_redefine_extname, 1);
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
cpp_register_pragma (parse_in, 0, "extern_prefix",
|
||||
handle_pragma_extern_prefix);
|
||||
ggc_add_tree_root (&pragma_extern_prefix, 1);
|
||||
#endif
|
||||
|
||||
#ifdef REGISTER_TARGET_PRAGMAS
|
||||
REGISTER_TARGET_PRAGMAS (parse_in);
|
||||
#endif
|
||||
|
||||
@@ -23,9 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#define GCC_C_PRAGMA_H
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_WEAK_ALIAS are
|
||||
defined. */
|
||||
#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)
|
||||
#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
|
||||
|| defined (ASM_WEAKEN_DECL))
|
||||
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
|
||||
#endif
|
||||
|
||||
@@ -54,4 +53,7 @@ extern void cpp_register_pragma PARAMS ((cpp_reader *,
|
||||
void (*) PARAMS ((cpp_reader *))));
|
||||
#endif
|
||||
|
||||
extern void maybe_apply_pragma_weak PARAMS ((tree));
|
||||
extern tree maybe_apply_renaming_pragma PARAMS ((tree, tree));
|
||||
|
||||
#endif /* GCC_C_PRAGMA_H */
|
||||
|
||||
@@ -644,7 +644,7 @@ genrtl_switch_stmt (t)
|
||||
emit_line_note (input_filename, lineno);
|
||||
expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
|
||||
expand_stmt (SWITCH_BODY (t));
|
||||
expand_end_case (cond);
|
||||
expand_end_case_type (cond, SWITCH_TYPE (t));
|
||||
}
|
||||
|
||||
/* Create a CASE_LABEL tree node and return it. */
|
||||
@@ -737,12 +737,12 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands,
|
||||
/* Generate the RTL for a DECL_CLEANUP. */
|
||||
|
||||
void
|
||||
genrtl_decl_cleanup (decl, cleanup)
|
||||
tree decl;
|
||||
tree cleanup;
|
||||
genrtl_decl_cleanup (t)
|
||||
tree t;
|
||||
{
|
||||
tree decl = CLEANUP_DECL (t);
|
||||
if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
|
||||
expand_decl_cleanup (decl, cleanup);
|
||||
expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
|
||||
}
|
||||
|
||||
/* We're about to expand T, a statement. Set up appropriate context
|
||||
@@ -847,6 +847,10 @@ expand_stmt (t)
|
||||
genrtl_scope_stmt (t);
|
||||
break;
|
||||
|
||||
case CLEANUP_STMT:
|
||||
genrtl_decl_cleanup (t);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (lang_expand_stmt)
|
||||
(*lang_expand_stmt) (t);
|
||||
|
||||
+108
-122
@@ -58,7 +58,6 @@ static tree decl_constant_value_for_broken_optimization PARAMS ((tree));
|
||||
static tree default_function_array_conversion PARAMS ((tree));
|
||||
static tree lookup_field PARAMS ((tree, tree));
|
||||
static tree convert_arguments PARAMS ((tree, tree, tree, tree));
|
||||
static tree pointer_int_sum PARAMS ((enum tree_code, tree, tree));
|
||||
static tree pointer_diff PARAMS ((tree, tree));
|
||||
static tree unary_complex_lvalue PARAMS ((enum tree_code, tree, int));
|
||||
static void pedantic_lvalue_warning PARAMS ((enum tree_code));
|
||||
@@ -149,6 +148,11 @@ incomplete_type_error (value, type)
|
||||
case ARRAY_TYPE:
|
||||
if (TYPE_DOMAIN (type))
|
||||
{
|
||||
if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL)
|
||||
{
|
||||
error ("invalid use of flexible array member");
|
||||
return;
|
||||
}
|
||||
type = TREE_TYPE (type);
|
||||
goto retry;
|
||||
}
|
||||
@@ -1547,6 +1551,9 @@ build_function_call (function, params)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (fundecl && TREE_THIS_VOLATILE (fundecl))
|
||||
current_function_returns_abnormally = 1;
|
||||
|
||||
/* fntype now gets the type of function pointed to. */
|
||||
fntype = TREE_TYPE (fntype);
|
||||
|
||||
@@ -2052,29 +2059,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
||||
case BIT_XOR_EXPR:
|
||||
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
|
||||
shorten = -1;
|
||||
/* If one operand is a constant, and the other is a short type
|
||||
that has been converted to an int,
|
||||
really do the work in the short type and then convert the
|
||||
result to int. If we are lucky, the constant will be 0 or 1
|
||||
in the short type, making the entire operation go away. */
|
||||
if (TREE_CODE (op0) == INTEGER_CST
|
||||
&& TREE_CODE (op1) == NOP_EXPR
|
||||
&& TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))
|
||||
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0))))
|
||||
{
|
||||
final_type = result_type;
|
||||
op1 = TREE_OPERAND (op1, 0);
|
||||
result_type = TREE_TYPE (op1);
|
||||
}
|
||||
if (TREE_CODE (op1) == INTEGER_CST
|
||||
&& TREE_CODE (op0) == NOP_EXPR
|
||||
&& TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))
|
||||
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
|
||||
{
|
||||
final_type = result_type;
|
||||
op0 = TREE_OPERAND (op0, 0);
|
||||
result_type = TREE_TYPE (op0);
|
||||
}
|
||||
break;
|
||||
|
||||
case TRUNC_MOD_EXPR:
|
||||
@@ -2652,95 +2636,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a tree for the sum or difference (RESULTCODE says which)
|
||||
of pointer PTROP and integer INTOP. */
|
||||
|
||||
static tree
|
||||
pointer_int_sum (resultcode, ptrop, intop)
|
||||
enum tree_code resultcode;
|
||||
tree ptrop, intop;
|
||||
{
|
||||
tree size_exp;
|
||||
|
||||
tree result;
|
||||
tree folded;
|
||||
|
||||
/* The result is a pointer of the same type that is being added. */
|
||||
|
||||
tree result_type = TREE_TYPE (ptrop);
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
|
||||
{
|
||||
if (pedantic || warn_pointer_arith)
|
||||
pedwarn ("pointer of type `void *' used in arithmetic");
|
||||
size_exp = integer_one_node;
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
|
||||
{
|
||||
if (pedantic || warn_pointer_arith)
|
||||
pedwarn ("pointer to a function used in arithmetic");
|
||||
size_exp = integer_one_node;
|
||||
}
|
||||
else
|
||||
size_exp = c_size_in_bytes (TREE_TYPE (result_type));
|
||||
|
||||
/* If what we are about to multiply by the size of the elements
|
||||
contains a constant term, apply distributive law
|
||||
and multiply that constant term separately.
|
||||
This helps produce common subexpressions. */
|
||||
|
||||
if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
|
||||
&& ! TREE_CONSTANT (intop)
|
||||
&& TREE_CONSTANT (TREE_OPERAND (intop, 1))
|
||||
&& TREE_CONSTANT (size_exp)
|
||||
/* If the constant comes from pointer subtraction,
|
||||
skip this optimization--it would cause an error. */
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
|
||||
/* If the constant is unsigned, and smaller than the pointer size,
|
||||
then we must skip this optimization. This is because it could cause
|
||||
an overflow error if the constant is negative but INTOP is not. */
|
||||
&& (! TREE_UNSIGNED (TREE_TYPE (intop))
|
||||
|| (TYPE_PRECISION (TREE_TYPE (intop))
|
||||
== TYPE_PRECISION (TREE_TYPE (ptrop)))))
|
||||
{
|
||||
enum tree_code subcode = resultcode;
|
||||
tree int_type = TREE_TYPE (intop);
|
||||
if (TREE_CODE (intop) == MINUS_EXPR)
|
||||
subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
|
||||
/* Convert both subexpression types to the type of intop,
|
||||
because weird cases involving pointer arithmetic
|
||||
can result in a sum or difference with different type args. */
|
||||
ptrop = build_binary_op (subcode, ptrop,
|
||||
convert (int_type, TREE_OPERAND (intop, 1)), 1);
|
||||
intop = convert (int_type, TREE_OPERAND (intop, 0));
|
||||
}
|
||||
|
||||
/* Convert the integer argument to a type the same size as sizetype
|
||||
so the multiply won't overflow spuriously. */
|
||||
|
||||
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
|
||||
|| TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
|
||||
intop = convert (type_for_size (TYPE_PRECISION (sizetype),
|
||||
TREE_UNSIGNED (sizetype)), intop);
|
||||
|
||||
/* Replace the integer argument with a suitable product by the object size.
|
||||
Do this multiplication as signed, then convert to the appropriate
|
||||
pointer type (actually unsigned integral). */
|
||||
|
||||
intop = convert (result_type,
|
||||
build_binary_op (MULT_EXPR, intop,
|
||||
convert (TREE_TYPE (intop), size_exp), 1));
|
||||
|
||||
/* Create the sum or difference. */
|
||||
|
||||
result = build (resultcode, result_type, ptrop, intop);
|
||||
|
||||
folded = fold (result);
|
||||
if (folded == result)
|
||||
TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
|
||||
return folded;
|
||||
}
|
||||
|
||||
/* Return a tree for the difference of pointers OP0 and OP1.
|
||||
The resulting tree has type int. */
|
||||
|
||||
@@ -3819,7 +3714,8 @@ build_c_cast (type, expr)
|
||||
{
|
||||
tree in_type = type;
|
||||
tree in_otype = otype;
|
||||
int warn = 0;
|
||||
int added = 0;
|
||||
int discarded = 0;
|
||||
|
||||
/* Check that the qualifiers on IN_TYPE are a superset of
|
||||
the qualifiers of IN_OTYPE. The outermost level of
|
||||
@@ -3829,12 +3725,24 @@ build_c_cast (type, expr)
|
||||
{
|
||||
in_otype = TREE_TYPE (in_otype);
|
||||
in_type = TREE_TYPE (in_type);
|
||||
warn |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
|
||||
|
||||
/* GNU C allows cv-qualified function types. 'const'
|
||||
means the function is very pure, 'volatile' means it
|
||||
can't return. We need to warn when such qualifiers
|
||||
are added, not when they're taken away. */
|
||||
if (TREE_CODE (in_otype) == FUNCTION_TYPE
|
||||
&& TREE_CODE (in_type) == FUNCTION_TYPE)
|
||||
added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype));
|
||||
else
|
||||
discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
|
||||
}
|
||||
while (TREE_CODE (in_type) == POINTER_TYPE
|
||||
&& TREE_CODE (in_otype) == POINTER_TYPE);
|
||||
|
||||
if (warn)
|
||||
if (added)
|
||||
warning ("cast adds new qualifiers to function type");
|
||||
|
||||
if (discarded)
|
||||
/* There are qualifiers present in IN_OTYPE that are not
|
||||
present in IN_TYPE. */
|
||||
warning ("cast discards qualifiers from pointer target type");
|
||||
@@ -4372,6 +4280,30 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Convert VALUE for assignment into inlined parameter PARM. */
|
||||
|
||||
tree
|
||||
c_convert_parm_for_inlining (parm, value, fn)
|
||||
tree parm, value, fn;
|
||||
{
|
||||
tree ret, type;
|
||||
|
||||
/* If FN was prototyped, the value has been converted already
|
||||
in convert_arguments. */
|
||||
if (! value || TYPE_ARG_TYPES (TREE_TYPE (fn)))
|
||||
return value;
|
||||
|
||||
type = TREE_TYPE (parm);
|
||||
ret = convert_for_assignment (type, value,
|
||||
(char *) 0 /* arg passing */, fn,
|
||||
DECL_NAME (fn), 0);
|
||||
if (PROMOTE_PROTOTYPES
|
||||
&& INTEGRAL_TYPE_P (type)
|
||||
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
|
||||
ret = default_conversion (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Print a warning using MSGID.
|
||||
It gets OPNAME as its one parameter.
|
||||
If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
|
||||
@@ -4809,6 +4741,8 @@ digest_init (type, init, require_constant, constructor_constant)
|
||||
TYPE_MAIN_VARIANT (type))
|
||||
|| (code == ARRAY_TYPE
|
||||
&& comptypes (TREE_TYPE (inside_init), type))
|
||||
|| (code == VECTOR_TYPE
|
||||
&& comptypes (TREE_TYPE (inside_init), type))
|
||||
|| (code == POINTER_TYPE
|
||||
&& (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
|
||||
@@ -5320,6 +5254,14 @@ really_start_incremental_init (type)
|
||||
|
||||
constructor_unfilled_index = constructor_index;
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
|
||||
{
|
||||
/* Vectors are like simple fixed-size arrays. */
|
||||
constructor_max_index =
|
||||
build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
|
||||
constructor_index = convert (bitsizetype, integer_zero_node);
|
||||
constructor_unfilled_index = constructor_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle the case of int x = {5}; */
|
||||
@@ -5466,6 +5408,14 @@ push_init_level (implicit)
|
||||
constructor_unfilled_fields = constructor_fields;
|
||||
constructor_bit_index = bitsize_zero_node;
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
|
||||
{
|
||||
/* Vectors are like simple fixed-size arrays. */
|
||||
constructor_max_index =
|
||||
build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
|
||||
constructor_index = convert (bitsizetype, integer_zero_node);
|
||||
constructor_unfilled_index = constructor_index;
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
|
||||
{
|
||||
if (TYPE_DOMAIN (constructor_type))
|
||||
@@ -5602,7 +5552,8 @@ pop_init_level (implicit)
|
||||
;
|
||||
else if (TREE_CODE (constructor_type) != RECORD_TYPE
|
||||
&& TREE_CODE (constructor_type) != UNION_TYPE
|
||||
&& TREE_CODE (constructor_type) != ARRAY_TYPE)
|
||||
&& TREE_CODE (constructor_type) != ARRAY_TYPE
|
||||
&& TREE_CODE (constructor_type) != VECTOR_TYPE)
|
||||
{
|
||||
/* A nonincremental scalar initializer--just return
|
||||
the element, after verifying there is just one. */
|
||||
@@ -6648,6 +6599,16 @@ process_init_element (value)
|
||||
fieldtype = TYPE_MAIN_VARIANT (fieldtype);
|
||||
fieldcode = TREE_CODE (fieldtype);
|
||||
|
||||
/* Error for non-static initialization of a flexible array member. */
|
||||
if (fieldcode == ARRAY_TYPE
|
||||
&& !require_constant_value
|
||||
&& TYPE_SIZE (fieldtype) == NULL_TREE
|
||||
&& TREE_CHAIN (constructor_fields) == NULL_TREE)
|
||||
{
|
||||
error_init ("non-static initialization of a flexible array member");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Accept a string constant to initialize a subarray. */
|
||||
if (value != 0
|
||||
&& fieldcode == ARRAY_TYPE
|
||||
@@ -6811,6 +6772,31 @@ process_init_element (value)
|
||||
constructor_unfilled_index. */
|
||||
constructor_unfilled_index = constructor_index;
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
|
||||
{
|
||||
tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
|
||||
|
||||
/* Do a basic check of initializer size. Note that vectors
|
||||
always have a fixed size derived from their type. */
|
||||
if (tree_int_cst_lt (constructor_max_index, constructor_index))
|
||||
{
|
||||
pedwarn_init ("excess elements in vector initializer");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now output the actual element. */
|
||||
if (value)
|
||||
output_init_element (value, elttype, constructor_index, 1);
|
||||
|
||||
constructor_index
|
||||
= size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
|
||||
|
||||
if (! value)
|
||||
/* If we are doing the bookkeeping for an element that was
|
||||
directly output as a constructor, we must update
|
||||
constructor_unfilled_index. */
|
||||
constructor_unfilled_index = constructor_index;
|
||||
}
|
||||
|
||||
/* Handle the sole element allowed in a braced initializer
|
||||
for a scalar variable. */
|
||||
@@ -7071,6 +7057,7 @@ c_expand_return (retval)
|
||||
tree res = DECL_RESULT (current_function_decl);
|
||||
tree inner;
|
||||
|
||||
current_function_returns_value = 1;
|
||||
if (t == error_mark_node)
|
||||
return NULL_TREE;
|
||||
|
||||
@@ -7128,7 +7115,6 @@ c_expand_return (retval)
|
||||
}
|
||||
|
||||
retval = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
|
||||
current_function_returns_value = 1;
|
||||
}
|
||||
|
||||
return add_stmt (build_return_stmt (retval));
|
||||
@@ -7163,15 +7149,15 @@ c_start_case (exp)
|
||||
tree exp;
|
||||
{
|
||||
enum tree_code code;
|
||||
tree type;
|
||||
tree type, orig_type = error_mark_node;
|
||||
struct c_switch *cs;
|
||||
|
||||
if (exp != error_mark_node)
|
||||
{
|
||||
code = TREE_CODE (TREE_TYPE (exp));
|
||||
type = TREE_TYPE (exp);
|
||||
orig_type = TREE_TYPE (exp);
|
||||
|
||||
if (! INTEGRAL_TYPE_P (type)
|
||||
if (! INTEGRAL_TYPE_P (orig_type)
|
||||
&& code != ERROR_MARK)
|
||||
{
|
||||
error ("switch quantity not an integer");
|
||||
@@ -7193,7 +7179,7 @@ c_start_case (exp)
|
||||
|
||||
/* Add this new SWITCH_STMT to the stack. */
|
||||
cs = (struct c_switch *) xmalloc (sizeof (*cs));
|
||||
cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, NULL_TREE);
|
||||
cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, orig_type);
|
||||
cs->cases = splay_tree_new (case_compare, NULL, NULL);
|
||||
cs->next = switch_stack;
|
||||
switch_stack = cs;
|
||||
|
||||
+33
-25
@@ -181,7 +181,8 @@ static int calls_function_1 PARAMS ((tree, int));
|
||||
|
||||
static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
|
||||
HOST_WIDE_INT, HOST_WIDE_INT, rtx,
|
||||
rtx, int, rtx, int));
|
||||
rtx, int, rtx, int,
|
||||
CUMULATIVE_ARGS *));
|
||||
static void precompute_register_parameters PARAMS ((int,
|
||||
struct arg_data *,
|
||||
int *));
|
||||
@@ -444,7 +445,7 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
|
||||
static void
|
||||
emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
|
||||
struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
|
||||
call_fusage, ecf_flags)
|
||||
call_fusage, ecf_flags, args_so_far)
|
||||
rtx funexp;
|
||||
tree fndecl ATTRIBUTE_UNUSED;
|
||||
tree funtype ATTRIBUTE_UNUSED;
|
||||
@@ -456,6 +457,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
|
||||
int old_inhibit_defer_pop;
|
||||
rtx call_fusage;
|
||||
int ecf_flags;
|
||||
CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED;
|
||||
{
|
||||
rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
|
||||
rtx call_insn;
|
||||
@@ -466,6 +468,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
|
||||
struct_value_size_rtx = GEN_INT (struct_value_size);
|
||||
#endif
|
||||
|
||||
#ifdef CALL_POPS_ARGS
|
||||
n_popped += CALL_POPS_ARGS (* args_so_far);
|
||||
#endif
|
||||
|
||||
/* Ensure address is valid. SYMBOL_REF is already valid, so no need,
|
||||
and we don't want to load it into a register as an optimization,
|
||||
because prepare_call_address already did it if it should be done. */
|
||||
@@ -1505,14 +1511,9 @@ precompute_arguments (flags, num_actuals, args)
|
||||
if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
|
||||
abort ();
|
||||
|
||||
push_temp_slots ();
|
||||
|
||||
args[i].value
|
||||
= expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
preserve_temp_slots (args[i].value);
|
||||
pop_temp_slots ();
|
||||
|
||||
/* ANSI doesn't require a sequence point here,
|
||||
but PCC has one, so this will avoid some problems. */
|
||||
emit_queue ();
|
||||
@@ -2675,10 +2676,6 @@ expand_call (exp, target, ignore)
|
||||
if (pass && (flags & ECF_LIBCALL_BLOCK))
|
||||
NO_DEFER_POP;
|
||||
|
||||
/* Push the temporary stack slot level so that we can free any
|
||||
temporaries we make. */
|
||||
push_temp_slots ();
|
||||
|
||||
#ifdef FINAL_REG_PARM_STACK_SPACE
|
||||
reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant,
|
||||
args_size.var);
|
||||
@@ -3055,7 +3052,7 @@ expand_call (exp, target, ignore)
|
||||
emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
|
||||
adjusted_args_size.constant, struct_value_size,
|
||||
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
|
||||
flags);
|
||||
flags, & args_so_far);
|
||||
|
||||
/* Verify that we've deallocated all the stack we used. */
|
||||
if (pass
|
||||
@@ -3328,8 +3325,6 @@ expand_call (exp, target, ignore)
|
||||
if ((flags & ECF_MAY_BE_ALLOCA) && nonlocal_goto_handler_slots != 0)
|
||||
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
|
||||
|
||||
pop_temp_slots ();
|
||||
|
||||
/* Free up storage we no longer need. */
|
||||
for (i = 0; i < num_actuals; ++i)
|
||||
if (args[i].aligned_regs)
|
||||
@@ -4053,7 +4048,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
struct_value_size,
|
||||
FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
|
||||
valreg,
|
||||
old_inhibit_defer_pop + 1, call_fusage, flags);
|
||||
old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far);
|
||||
|
||||
/* For calls to `setjmp', etc., inform flow.c it should complain
|
||||
if nonvolatile values are live. For functions that cannot return,
|
||||
@@ -4361,7 +4356,13 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
/* If this isn't going to be placed on both the stack and in registers,
|
||||
set up the register and number of words. */
|
||||
if (! arg->pass_on_stack)
|
||||
reg = arg->reg, partial = arg->partial;
|
||||
{
|
||||
if (flags & ECF_SIBCALL)
|
||||
reg = arg->tail_call_reg;
|
||||
else
|
||||
reg = arg->reg;
|
||||
partial = arg->partial;
|
||||
}
|
||||
|
||||
if (reg != 0 && partial == 0)
|
||||
/* Being passed entirely in a register. We shouldn't be called in
|
||||
@@ -4459,6 +4460,11 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
partial, reg, used - size, argblock,
|
||||
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
|
||||
ARGS_SIZE_RTX (arg->alignment_pad));
|
||||
|
||||
/* Unless this is a partially-in-register argument, the argument is now
|
||||
in the stack. */
|
||||
if (partial == 0)
|
||||
arg->value = arg->stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4558,17 +4564,19 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
argblock, ARGS_SIZE_RTX (arg->offset),
|
||||
reg_parm_stack_space,
|
||||
ARGS_SIZE_RTX (arg->alignment_pad));
|
||||
|
||||
/* Unless this is a partially-in-register argument, the argument is now
|
||||
in the stack.
|
||||
|
||||
??? Unlike the case above, in which we want the actual
|
||||
address of the data, so that we can load it directly into a
|
||||
register, here we want the address of the stack slot, so that
|
||||
it's properly aligned for word-by-word copying or something
|
||||
like that. It's not clear that this is always correct. */
|
||||
if (partial == 0)
|
||||
arg->value = arg->stack_slot;
|
||||
}
|
||||
|
||||
/* Unless this is a partially-in-register argument, the argument is now
|
||||
in the stack.
|
||||
|
||||
??? Note that this can change arg->value from arg->stack to
|
||||
arg->stack_slot and it matters when they are not the same.
|
||||
It isn't totally clear that this is correct in all cases. */
|
||||
if (partial == 0)
|
||||
arg->value = arg->stack_slot;
|
||||
|
||||
/* Once we have pushed something, pops can't safely
|
||||
be deferred during the rest of the arguments. */
|
||||
NO_DEFER_POP;
|
||||
|
||||
+15
-7
@@ -1,6 +1,6 @@
|
||||
/* Control flow graph manipulation code for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@@ -221,6 +221,17 @@ alloc_block ()
|
||||
|
||||
/* Remove block B from the basic block array and compact behind it. */
|
||||
|
||||
void
|
||||
expunge_block_nocompact (b)
|
||||
basic_block b;
|
||||
{
|
||||
/* Invalidate data to make bughunting easier. */
|
||||
memset (b, 0, sizeof *b);
|
||||
b->index = -3;
|
||||
b->succ = (edge) first_deleted_block;
|
||||
first_deleted_block = (basic_block) b;
|
||||
}
|
||||
|
||||
void
|
||||
expunge_block (b)
|
||||
basic_block b;
|
||||
@@ -234,13 +245,10 @@ expunge_block (b)
|
||||
x->index = i;
|
||||
}
|
||||
|
||||
/* Invalidate data to make bughunting easier. */
|
||||
memset (b, 0, sizeof *b);
|
||||
b->index = -3;
|
||||
basic_block_info->num_elements--;
|
||||
n_basic_blocks--;
|
||||
b->succ = (edge) first_deleted_block;
|
||||
first_deleted_block = (basic_block) b;
|
||||
basic_block_info->num_elements--;
|
||||
|
||||
expunge_block_nocompact (b);
|
||||
}
|
||||
|
||||
/* Create an edge connecting SRC and DST with FLAGS optionally using
|
||||
|
||||
+62
-15
@@ -25,9 +25,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "rtl.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
#include "insn-config.h"
|
||||
#include "recog.h"
|
||||
#include "toplev.h"
|
||||
|
||||
#include "obstack.h"
|
||||
#include "tm_p.h"
|
||||
|
||||
/* Store the data structures necessary for depth-first search. */
|
||||
struct depth_first_search_dsS {
|
||||
@@ -53,6 +55,7 @@ static void flow_dfs_compute_reverse_finish
|
||||
PARAMS ((depth_first_search_ds));
|
||||
static void remove_fake_successors PARAMS ((basic_block));
|
||||
static bool need_fake_edge_p PARAMS ((rtx));
|
||||
static bool keep_with_call_p PARAMS ((rtx));
|
||||
|
||||
/* Return true if the block has no effect and only forwards control flow to
|
||||
its single destination. */
|
||||
@@ -209,6 +212,32 @@ need_fake_edge_p (insn)
|
||||
|| GET_CODE (PATTERN (insn)) == ASM_INPUT);
|
||||
}
|
||||
|
||||
/* Return true if INSN should be kept in the same block as a preceding call.
|
||||
This is done for a single-set whose destination is a fixed register or
|
||||
whose source is the function return value. This is a helper function for
|
||||
flow_call_edges_add. */
|
||||
|
||||
static bool
|
||||
keep_with_call_p (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx set;
|
||||
|
||||
if (INSN_P (insn) && (set = single_set (insn)) != NULL)
|
||||
{
|
||||
if (GET_CODE (SET_DEST (set)) == REG
|
||||
&& fixed_regs[REGNO (SET_DEST (set))]
|
||||
&& general_operand (SET_SRC (set), VOIDmode))
|
||||
return true;
|
||||
if (GET_CODE (SET_SRC (set)) == REG
|
||||
&& FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
|
||||
&& GET_CODE (SET_DEST (set)) == REG
|
||||
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -259,17 +288,27 @@ flow_call_edges_add (blocks)
|
||||
spanning tree in the case that the call doesn't return.
|
||||
|
||||
Handle this by adding a dummy instruction in a new last basic block. */
|
||||
if (check_last_block
|
||||
&& need_fake_edge_p (BASIC_BLOCK (n_basic_blocks - 1)->end))
|
||||
if (check_last_block)
|
||||
{
|
||||
edge e;
|
||||
basic_block bb = BASIC_BLOCK (n_basic_blocks - 1);
|
||||
rtx insn = bb->end;
|
||||
|
||||
for (e = BASIC_BLOCK (n_basic_blocks - 1)->succ; e; e = e->succ_next)
|
||||
if (e->dest == EXIT_BLOCK_PTR)
|
||||
break;
|
||||
/* Back up past insns that must be kept in the same block as a call. */
|
||||
while (insn != bb->head
|
||||
&& keep_with_call_p (insn))
|
||||
insn = PREV_INSN (insn);
|
||||
|
||||
insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
|
||||
commit_edge_insertions ();
|
||||
if (need_fake_edge_p (insn))
|
||||
{
|
||||
edge e;
|
||||
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
if (e->dest == EXIT_BLOCK_PTR)
|
||||
break;
|
||||
|
||||
insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
|
||||
commit_edge_insertions ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Now add fake edges to the function exit for any non constant
|
||||
@@ -288,14 +327,22 @@ flow_call_edges_add (blocks)
|
||||
if (need_fake_edge_p (insn))
|
||||
{
|
||||
edge e;
|
||||
rtx split_at_insn = insn;
|
||||
|
||||
/* The above condition should be enough to verify that there is
|
||||
no edge to the exit block in CFG already. Calling make_edge
|
||||
in such case would make us to mark that edge as fake and
|
||||
remove it later. */
|
||||
/* Don't split the block between a call and an insn that should
|
||||
remain in the same block as the call. */
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
while (split_at_insn != bb->end
|
||||
&& keep_with_call_p (NEXT_INSN (split_at_insn)))
|
||||
split_at_insn = NEXT_INSN (split_at_insn);
|
||||
|
||||
/* The handling above of the final block before the epilogue
|
||||
should be enough to verify that there is no edge to the exit
|
||||
block in CFG already. Calling make_edge in such case would
|
||||
cause us to mark that edge as fake and remove it later. */
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (insn == bb->end)
|
||||
if (split_at_insn == bb->end)
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
if (e->dest == EXIT_BLOCK_PTR)
|
||||
abort ();
|
||||
@@ -303,7 +350,7 @@ flow_call_edges_add (blocks)
|
||||
|
||||
/* Note that the following may create a new basic block
|
||||
and renumber the existing basic blocks. */
|
||||
e = split_block (bb, insn);
|
||||
e = split_block (bb, split_at_insn);
|
||||
if (e)
|
||||
blocks_split++;
|
||||
|
||||
|
||||
+174
-143
@@ -1,6 +1,6 @@
|
||||
/* Control flow optimization code for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@@ -44,6 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "toplev.h"
|
||||
#include "cselib.h"
|
||||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "obstack.h"
|
||||
|
||||
@@ -1096,9 +1097,20 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
|
||||
if (!bb2->succ
|
||||
|| !bb2->succ->succ_next
|
||||
|| bb1->succ->succ_next->succ_next
|
||||
|| bb2->succ->succ_next->succ_next
|
||||
|| !any_condjump_p (bb2->end)
|
||||
|| !onlyjump_p (bb1->end))
|
||||
|| !onlyjump_p (bb2->end))
|
||||
return false;
|
||||
|
||||
/* Do not crossjump across loop boundaries. This is a temporary
|
||||
workaround for the common scenario in which crossjumping results
|
||||
in killing the duplicated loop condition, making bb-reorder rotate
|
||||
the loop incorectly, leaving an extra unconditional jump inside
|
||||
the loop.
|
||||
|
||||
This check should go away once bb-reorder knows how to duplicate
|
||||
code in this case or rotate the loops to avoid this scenario. */
|
||||
if (bb1->loop_depth != bb2->loop_depth)
|
||||
return false;
|
||||
|
||||
b1 = BRANCH_EDGE (bb1);
|
||||
@@ -1174,9 +1186,10 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
/* Do not use f2 probability as f2 may be forwarded. */
|
||||
prob2 = REG_BR_PROB_BASE - b2->probability;
|
||||
|
||||
/* Fail if the difference in probabilities is
|
||||
greater than 5%. */
|
||||
if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 20)
|
||||
/* Fail if the difference in probabilities is greater than 50%.
|
||||
This rules out two well-predicted branches with opposite
|
||||
outcomes. */
|
||||
if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 2)
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
@@ -1277,12 +1290,10 @@ try_crossjump_to_edge (mode, e1, e2)
|
||||
away. We do this to look past the unconditional jump following a
|
||||
conditional jump that is required due to the current CFG shape. */
|
||||
if (src1->pred
|
||||
&& !src1->pred->pred_next
|
||||
&& FORWARDER_BLOCK_P (src1))
|
||||
e1 = src1->pred, src1 = e1->src;
|
||||
|
||||
if (src2->pred
|
||||
&& !src2->pred->pred_next
|
||||
&& FORWARDER_BLOCK_P (src2))
|
||||
e2 = src2->pred, src2 = e2->src;
|
||||
|
||||
@@ -1531,149 +1542,158 @@ try_optimize_cfg (mode)
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
update_forwarder_flag (BASIC_BLOCK (i));
|
||||
|
||||
/* Attempt to merge blocks as made possible by edge removal. If a block
|
||||
has only one successor, and the successor has only one predecessor,
|
||||
they may be combined. */
|
||||
do
|
||||
if (! (* targetm.cannot_modify_jumps_p) ())
|
||||
{
|
||||
changed = false;
|
||||
iterations++;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "\n\ntry_optimize_cfg iteration %i\n\n",
|
||||
iterations);
|
||||
|
||||
for (i = 0; i < n_basic_blocks;)
|
||||
/* Attempt to merge blocks as made possible by edge removal. If
|
||||
a block has only one successor, and the successor has only
|
||||
one predecessor, they may be combined. */
|
||||
do
|
||||
{
|
||||
basic_block c, b = BASIC_BLOCK (i);
|
||||
edge s;
|
||||
bool changed_here = false;
|
||||
changed = false;
|
||||
iterations++;
|
||||
|
||||
/* Delete trivially dead basic blocks. */
|
||||
while (b->pred == NULL)
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
"\n\ntry_optimize_cfg iteration %i\n\n",
|
||||
iterations);
|
||||
|
||||
for (i = 0; i < n_basic_blocks;)
|
||||
{
|
||||
c = BASIC_BLOCK (b->index - 1);
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleting block %i.\n", b->index);
|
||||
basic_block c, b = BASIC_BLOCK (i);
|
||||
edge s;
|
||||
bool changed_here = false;
|
||||
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
b = c;
|
||||
/* Delete trivially dead basic blocks. */
|
||||
while (b->pred == NULL)
|
||||
{
|
||||
c = BASIC_BLOCK (b->index - 1);
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleting block %i.\n",
|
||||
b->index);
|
||||
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
b = c;
|
||||
}
|
||||
|
||||
/* Remove code labels no longer used. Don't do this
|
||||
before CALL_PLACEHOLDER is removed, as some branches
|
||||
may be hidden within. */
|
||||
if (b->pred->pred_next == NULL
|
||||
&& (b->pred->flags & EDGE_FALLTHRU)
|
||||
&& !(b->pred->flags & EDGE_COMPLEX)
|
||||
&& GET_CODE (b->head) == CODE_LABEL
|
||||
&& (!(mode & CLEANUP_PRE_SIBCALL)
|
||||
|| !tail_recursion_label_p (b->head))
|
||||
/* If the previous block ends with a branch to this
|
||||
block, we can't delete the label. Normally this
|
||||
is a condjump that is yet to be simplified, but
|
||||
if CASE_DROPS_THRU, this can be a tablejump with
|
||||
some element going to the same place as the
|
||||
default (fallthru). */
|
||||
&& (b->pred->src == ENTRY_BLOCK_PTR
|
||||
|| GET_CODE (b->pred->src->end) != JUMP_INSN
|
||||
|| ! label_is_jump_target_p (b->head,
|
||||
b->pred->src->end)))
|
||||
{
|
||||
rtx label = b->head;
|
||||
|
||||
b->head = NEXT_INSN (b->head);
|
||||
delete_insn_chain (label, label);
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
|
||||
b->index);
|
||||
}
|
||||
|
||||
/* If we fall through an empty block, we can remove it. */
|
||||
if (b->pred->pred_next == NULL
|
||||
&& (b->pred->flags & EDGE_FALLTHRU)
|
||||
&& GET_CODE (b->head) != CODE_LABEL
|
||||
&& FORWARDER_BLOCK_P (b)
|
||||
/* Note that forwarder_block_p true ensures that
|
||||
there is a successor for this block. */
|
||||
&& (b->succ->flags & EDGE_FALLTHRU)
|
||||
&& n_basic_blocks > 1)
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
"Deleting fallthru block %i.\n",
|
||||
b->index);
|
||||
|
||||
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
|
||||
redirect_edge_succ_nodup (b->pred, b->succ->dest);
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
b = c;
|
||||
}
|
||||
|
||||
/* Merge blocks. Loop because chains of blocks might be
|
||||
combineable. */
|
||||
while ((s = b->succ) != NULL
|
||||
&& s->succ_next == NULL
|
||||
&& !(s->flags & EDGE_COMPLEX)
|
||||
&& (c = s->dest) != EXIT_BLOCK_PTR
|
||||
&& c->pred->pred_next == NULL
|
||||
/* If the jump insn has side effects,
|
||||
we can't kill the edge. */
|
||||
&& (GET_CODE (b->end) != JUMP_INSN
|
||||
|| onlyjump_p (b->end))
|
||||
&& merge_blocks (s, b, c, mode))
|
||||
changed_here = true;
|
||||
|
||||
/* Simplify branch over branch. */
|
||||
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
changed_here = true;
|
||||
}
|
||||
|
||||
/* If B has a single outgoing edge, but uses a
|
||||
non-trivial jump instruction without side-effects, we
|
||||
can either delete the jump entirely, or replace it
|
||||
with a simple unconditional jump. Use
|
||||
redirect_edge_and_branch to do the dirty work. */
|
||||
if (b->succ
|
||||
&& ! b->succ->succ_next
|
||||
&& b->succ->dest != EXIT_BLOCK_PTR
|
||||
&& onlyjump_p (b->end)
|
||||
&& redirect_edge_and_branch (b->succ, b->succ->dest))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
update_forwarder_flag (b);
|
||||
changed_here = true;
|
||||
}
|
||||
|
||||
/* Simplify branch to branch. */
|
||||
if (try_forward_edges (mode, b))
|
||||
changed_here = true;
|
||||
|
||||
/* Look for shared code between blocks. */
|
||||
if ((mode & CLEANUP_CROSSJUMP)
|
||||
&& try_crossjump_bb (mode, b))
|
||||
changed_here = true;
|
||||
|
||||
/* Don't get confused by the index shift caused by
|
||||
deleting blocks. */
|
||||
if (!changed_here)
|
||||
i = b->index + 1;
|
||||
else
|
||||
changed = true;
|
||||
}
|
||||
|
||||
/* Remove code labels no longer used. Don't do this before
|
||||
CALL_PLACEHOLDER is removed, as some branches may be hidden
|
||||
within. */
|
||||
if (b->pred->pred_next == NULL
|
||||
&& (b->pred->flags & EDGE_FALLTHRU)
|
||||
&& !(b->pred->flags & EDGE_COMPLEX)
|
||||
&& GET_CODE (b->head) == CODE_LABEL
|
||||
&& (!(mode & CLEANUP_PRE_SIBCALL)
|
||||
|| !tail_recursion_label_p (b->head))
|
||||
/* If the previous block ends with a branch to this block,
|
||||
we can't delete the label. Normally this is a condjump
|
||||
that is yet to be simplified, but if CASE_DROPS_THRU,
|
||||
this can be a tablejump with some element going to the
|
||||
same place as the default (fallthru). */
|
||||
&& (b->pred->src == ENTRY_BLOCK_PTR
|
||||
|| GET_CODE (b->pred->src->end) != JUMP_INSN
|
||||
|| ! label_is_jump_target_p (b->head, b->pred->src->end)))
|
||||
{
|
||||
rtx label = b->head;
|
||||
|
||||
b->head = NEXT_INSN (b->head);
|
||||
delete_insn_chain (label, label);
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
|
||||
b->index);
|
||||
}
|
||||
|
||||
/* If we fall through an empty block, we can remove it. */
|
||||
if (b->pred->pred_next == NULL
|
||||
&& (b->pred->flags & EDGE_FALLTHRU)
|
||||
&& GET_CODE (b->head) != CODE_LABEL
|
||||
&& FORWARDER_BLOCK_P (b)
|
||||
/* Note that forwarder_block_p true ensures that there
|
||||
is a successor for this block. */
|
||||
&& (b->succ->flags & EDGE_FALLTHRU)
|
||||
&& n_basic_blocks > 1)
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
|
||||
b->index);
|
||||
|
||||
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
|
||||
redirect_edge_succ_nodup (b->pred, b->succ->dest);
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
b = c;
|
||||
}
|
||||
|
||||
/* Merge blocks. Loop because chains of blocks might be
|
||||
combineable. */
|
||||
while ((s = b->succ) != NULL
|
||||
&& s->succ_next == NULL
|
||||
&& !(s->flags & EDGE_COMPLEX)
|
||||
&& (c = s->dest) != EXIT_BLOCK_PTR
|
||||
&& c->pred->pred_next == NULL
|
||||
/* If the jump insn has side effects,
|
||||
we can't kill the edge. */
|
||||
&& (GET_CODE (b->end) != JUMP_INSN
|
||||
|| onlyjump_p (b->end))
|
||||
&& merge_blocks (s, b, c, mode))
|
||||
changed_here = true;
|
||||
|
||||
/* Simplify branch over branch. */
|
||||
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
changed_here = true;
|
||||
}
|
||||
|
||||
/* If B has a single outgoing edge, but uses a non-trivial jump
|
||||
instruction without side-effects, we can either delete the
|
||||
jump entirely, or replace it with a simple unconditional jump.
|
||||
Use redirect_edge_and_branch to do the dirty work. */
|
||||
if (b->succ
|
||||
&& ! b->succ->succ_next
|
||||
&& b->succ->dest != EXIT_BLOCK_PTR
|
||||
&& onlyjump_p (b->end)
|
||||
&& redirect_edge_and_branch (b->succ, b->succ->dest))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
update_forwarder_flag (b);
|
||||
changed_here = true;
|
||||
}
|
||||
|
||||
/* Simplify branch to branch. */
|
||||
if (try_forward_edges (mode, b))
|
||||
changed_here = true;
|
||||
|
||||
/* Look for shared code between blocks. */
|
||||
if ((mode & CLEANUP_CROSSJUMP)
|
||||
&& try_crossjump_bb (mode, b))
|
||||
changed_here = true;
|
||||
|
||||
/* Don't get confused by the index shift caused by deleting
|
||||
blocks. */
|
||||
if (!changed_here)
|
||||
i = b->index + 1;
|
||||
else
|
||||
&& try_crossjump_bb (mode, EXIT_BLOCK_PTR))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ((mode & CLEANUP_CROSSJUMP)
|
||||
&& try_crossjump_bb (mode, EXIT_BLOCK_PTR))
|
||||
changed = true;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (changed)
|
||||
verify_flow_info ();
|
||||
if (changed)
|
||||
verify_flow_info ();
|
||||
#endif
|
||||
|
||||
changed_overall |= changed;
|
||||
changed_overall |= changed;
|
||||
}
|
||||
while (changed);
|
||||
}
|
||||
while (changed);
|
||||
|
||||
if (mode & CLEANUP_CROSSJUMP)
|
||||
remove_fake_edges ();
|
||||
@@ -1709,22 +1729,33 @@ try_optimize_cfg (mode)
|
||||
static bool
|
||||
delete_unreachable_blocks ()
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
bool changed = false;
|
||||
|
||||
find_unreachable_blocks ();
|
||||
|
||||
/* Delete all unreachable basic blocks. Count down so that we
|
||||
don't interfere with the block renumbering that happens in
|
||||
flow_delete_block. */
|
||||
/* Delete all unreachable basic blocks. Do compaction concurrently,
|
||||
as otherwise we can wind up with O(N^2) behaviour here when we
|
||||
have oodles of dead code. */
|
||||
|
||||
for (i = n_basic_blocks - 1; i >= 0; --i)
|
||||
for (i = j = 0; i < n_basic_blocks; ++i)
|
||||
{
|
||||
basic_block b = BASIC_BLOCK (i);
|
||||
|
||||
if (!(b->flags & BB_REACHABLE))
|
||||
flow_delete_block (b), changed = true;
|
||||
{
|
||||
flow_delete_block_noexpunge (b);
|
||||
expunge_block_nocompact (b);
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BASIC_BLOCK (j) = b;
|
||||
b->index = j++;
|
||||
}
|
||||
}
|
||||
n_basic_blocks = j;
|
||||
basic_block_info->num_elements = j;
|
||||
|
||||
if (changed)
|
||||
tidy_fallthru_edges ();
|
||||
|
||||
+79
-37
@@ -1,6 +1,6 @@
|
||||
/* Control flow graph manipulation code for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@@ -101,8 +101,7 @@ can_delete_label_p (label)
|
||||
/* User declared labels must be preserved. */
|
||||
&& LABEL_NAME (label) == 0
|
||||
&& !in_expr_list_p (forced_labels, label)
|
||||
&& !in_expr_list_p (label_value_list, label)
|
||||
&& !in_expr_list_p (exception_handler_labels, label));
|
||||
&& !in_expr_list_p (label_value_list, label));
|
||||
}
|
||||
|
||||
/* Delete INSN by patching it out. Return the next insn. */
|
||||
@@ -323,7 +322,7 @@ create_basic_block (index, head, end)
|
||||
to post-process the stream to remove empty blocks, loops, ranges, etc. */
|
||||
|
||||
int
|
||||
flow_delete_block (b)
|
||||
flow_delete_block_noexpunge (b)
|
||||
basic_block b;
|
||||
{
|
||||
int deleted_handler = 0;
|
||||
@@ -338,7 +337,7 @@ flow_delete_block (b)
|
||||
|
||||
insn = b->head;
|
||||
|
||||
never_reached_warning (insn);
|
||||
never_reached_warning (insn, b->end);
|
||||
|
||||
if (GET_CODE (insn) == CODE_LABEL)
|
||||
maybe_remove_eh_handler (insn);
|
||||
@@ -372,6 +371,15 @@ flow_delete_block (b)
|
||||
b->pred = NULL;
|
||||
b->succ = NULL;
|
||||
|
||||
return deleted_handler;
|
||||
}
|
||||
|
||||
int
|
||||
flow_delete_block (b)
|
||||
basic_block b;
|
||||
{
|
||||
int deleted_handler = flow_delete_block_noexpunge (b);
|
||||
|
||||
/* Remove the basic block from the array, and compact behind it. */
|
||||
expunge_block (b);
|
||||
|
||||
@@ -611,9 +619,9 @@ merge_blocks_nomove (a, b)
|
||||
rtx x;
|
||||
|
||||
for (x = a_end; x != b_end; x = NEXT_INSN (x))
|
||||
BLOCK_FOR_INSN (x) = a;
|
||||
set_block_for_insn (x, a);
|
||||
|
||||
BLOCK_FOR_INSN (b_end) = a;
|
||||
set_block_for_insn (b_end, a);
|
||||
}
|
||||
|
||||
a_end = b_end;
|
||||
@@ -714,7 +722,7 @@ try_redirect_by_replacing_jump (e, target)
|
||||
else
|
||||
{
|
||||
rtx target_label = block_label (target);
|
||||
rtx barrier;
|
||||
rtx barrier, tmp;
|
||||
|
||||
emit_jump_insn_after (gen_jump (target_label), insn);
|
||||
JUMP_LABEL (src->end) = target_label;
|
||||
@@ -723,8 +731,21 @@ try_redirect_by_replacing_jump (e, target)
|
||||
fprintf (rtl_dump_file, "Replacing insn %i by jump %i\n",
|
||||
INSN_UID (insn), INSN_UID (src->end));
|
||||
|
||||
|
||||
delete_insn_chain (kill_from, insn);
|
||||
|
||||
/* Recognize a tablejump that we are converting to a
|
||||
simple jump and remove its associated CODE_LABEL
|
||||
and ADDR_VEC or ADDR_DIFF_VEC. */
|
||||
if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
|
||||
&& (tmp = NEXT_INSN (tmp)) != NULL_RTX
|
||||
&& GET_CODE (tmp) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (tmp)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
|
||||
{
|
||||
delete_insn_chain (JUMP_LABEL (insn), tmp);
|
||||
}
|
||||
|
||||
barrier = next_nonnote_insn (src->end);
|
||||
if (!barrier || GET_CODE (barrier) != BARRIER)
|
||||
emit_barrier_after (src->end);
|
||||
@@ -905,7 +926,31 @@ force_nonfallthru_and_redirect (e, target)
|
||||
abort ();
|
||||
else if (!(e->flags & EDGE_FALLTHRU))
|
||||
abort ();
|
||||
else if (e->src->succ->succ_next)
|
||||
else if (e->src == ENTRY_BLOCK_PTR)
|
||||
{
|
||||
/* We can't redirect the entry block. Create an empty block at the
|
||||
start of the function which we use to add the new jump. */
|
||||
edge *pe1;
|
||||
basic_block bb = create_basic_block (0, e->dest->head, NULL);
|
||||
|
||||
/* Change the existing edge's source to be the new block, and add
|
||||
a new edge from the entry block to the new block. */
|
||||
e->src = bb;
|
||||
bb->count = e->count;
|
||||
bb->frequency = EDGE_FREQUENCY (e);
|
||||
bb->loop_depth = 0;
|
||||
for (pe1 = &ENTRY_BLOCK_PTR->succ; *pe1; pe1 = &(*pe1)->succ_next)
|
||||
if (*pe1 == e)
|
||||
{
|
||||
*pe1 = e->succ_next;
|
||||
break;
|
||||
}
|
||||
e->succ_next = 0;
|
||||
bb->succ = e;
|
||||
make_single_succ_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
|
||||
}
|
||||
|
||||
if (e->src->succ->succ_next)
|
||||
{
|
||||
/* Create the new structures. */
|
||||
note = last_loop_beg_note (e->src->end);
|
||||
@@ -1180,6 +1225,7 @@ split_edge (edge_in)
|
||||
: edge_in->dest->index, before, NULL);
|
||||
bb->count = edge_in->count;
|
||||
bb->frequency = EDGE_FREQUENCY (edge_in);
|
||||
bb->loop_depth = edge_in->dest->loop_depth;
|
||||
|
||||
/* ??? This info is likely going to be out of date very soon. */
|
||||
if (edge_in->dest->global_live_at_start)
|
||||
@@ -1863,9 +1909,30 @@ purge_dead_edges (bb)
|
||||
rtx insn = bb->end, note;
|
||||
bool purged = false;
|
||||
|
||||
/* ??? This makes no sense since the later test includes more cases. */
|
||||
if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn))
|
||||
return false;
|
||||
/* If this instruction cannot trap, remove REG_EH_REGION notes. */
|
||||
if (GET_CODE (insn) == INSN
|
||||
&& (note = find_reg_note (insn, REG_EH_REGION, NULL)))
|
||||
{
|
||||
rtx eqnote;
|
||||
|
||||
if (! may_trap_p (PATTERN (insn))
|
||||
|| ((eqnote = find_reg_equal_equiv_note (insn))
|
||||
&& ! may_trap_p (XEXP (eqnote, 0))))
|
||||
remove_note (insn, note);
|
||||
}
|
||||
|
||||
/* Cleanup abnormal edges caused by throwing insns that have been
|
||||
eliminated. */
|
||||
if (! can_throw_internal (bb->end))
|
||||
for (e = bb->succ; e; e = next)
|
||||
{
|
||||
next = e->succ_next;
|
||||
if (e->flags & EDGE_EH)
|
||||
{
|
||||
remove_edge (e);
|
||||
purged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_CODE (insn) == JUMP_INSN)
|
||||
{
|
||||
@@ -1934,31 +2001,6 @@ purge_dead_edges (bb)
|
||||
return purged;
|
||||
}
|
||||
|
||||
/* If this instruction cannot trap, remove REG_EH_REGION notes. */
|
||||
if (GET_CODE (insn) == INSN
|
||||
&& (note = find_reg_note (insn, REG_EH_REGION, NULL)))
|
||||
{
|
||||
rtx eqnote;
|
||||
|
||||
if (! may_trap_p (PATTERN (insn))
|
||||
|| ((eqnote = find_reg_equal_equiv_note (insn))
|
||||
&& ! may_trap_p (XEXP (eqnote, 0))))
|
||||
remove_note (insn, note);
|
||||
}
|
||||
|
||||
/* Cleanup abnormal edges caused by throwing insns that have been
|
||||
eliminated. */
|
||||
if (! can_throw_internal (bb->end))
|
||||
for (e = bb->succ; e; e = next)
|
||||
{
|
||||
next = e->succ_next;
|
||||
if (e->flags & EDGE_EH)
|
||||
{
|
||||
remove_edge (e);
|
||||
purged = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't see a jump insn, we don't know exactly why the block would
|
||||
have been broken at this point. Look for a simple, non-fallthru edge,
|
||||
as these are only created by conditional branches. If we find such an
|
||||
|
||||
@@ -532,7 +532,7 @@ dump_file (name)
|
||||
if (no_demangle)
|
||||
result = 0;
|
||||
else
|
||||
result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
|
||||
result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
||||
+265
-132
@@ -424,6 +424,33 @@ do_SUBST (into, newval)
|
||||
if (oldval == newval)
|
||||
return;
|
||||
|
||||
/* We'd like to catch as many invalid transformations here as
|
||||
possible. Unfortunately, there are way too many mode changes
|
||||
that are perfectly valid, so we'd waste too much effort for
|
||||
little gain doing the checks here. Focus on catching invalid
|
||||
transformations involving integer constants. */
|
||||
if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
|
||||
&& GET_CODE (newval) == CONST_INT)
|
||||
{
|
||||
/* Sanity check that we're replacing oldval with a CONST_INT
|
||||
that is a valid sign-extension for the original mode. */
|
||||
if (INTVAL (newval) != trunc_int_for_mode (INTVAL (newval),
|
||||
GET_MODE (oldval)))
|
||||
abort ();
|
||||
|
||||
/* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
|
||||
CONST_INT is not valid, because after the replacement, the
|
||||
original mode would be gone. Unfortunately, we can't tell
|
||||
when do_SUBST is called to replace the operand thereof, so we
|
||||
perform this test on oldval instead, checking whether an
|
||||
invalid replacement took place before we got here. */
|
||||
if ((GET_CODE (oldval) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (oldval)) == CONST_INT)
|
||||
|| (GET_CODE (oldval) == ZERO_EXTEND
|
||||
&& GET_CODE (XEXP (oldval, 0)) == CONST_INT))
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (undobuf.frees)
|
||||
buf = undobuf.frees, undobuf.frees = buf->next;
|
||||
else
|
||||
@@ -877,8 +904,10 @@ set_nonzero_bits_and_sign_copies (x, set, data)
|
||||
<< GET_MODE_BITSIZE (GET_MODE (x))));
|
||||
#endif
|
||||
|
||||
reg_nonzero_bits[REGNO (x)]
|
||||
|= nonzero_bits (src, nonzero_bits_mode);
|
||||
/* Don't call nonzero_bits if it cannot change anything. */
|
||||
if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
|
||||
reg_nonzero_bits[REGNO (x)]
|
||||
|= nonzero_bits (src, nonzero_bits_mode);
|
||||
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
|
||||
if (reg_sign_bit_copies[REGNO (x)] == 0
|
||||
|| reg_sign_bit_copies[REGNO (x)] > num)
|
||||
@@ -1478,6 +1507,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
|
||||
{
|
||||
/* New patterns for I3 and I2, respectively. */
|
||||
rtx newpat, newi2pat = 0;
|
||||
int substed_i2 = 0, substed_i1 = 0;
|
||||
/* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead. */
|
||||
int added_sets_1, added_sets_2;
|
||||
/* Total number of SETs to put into I3. */
|
||||
@@ -1939,6 +1969,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
|
||||
subst_low_cuid = INSN_CUID (i2);
|
||||
newpat = subst (PATTERN (i3), i2dest, i2src, 0,
|
||||
! i1_feeds_i3 && i1dest_in_i1src);
|
||||
substed_i2 = 1;
|
||||
|
||||
/* Record whether i2's body now appears within i3's body. */
|
||||
i2_is_used = n_occurrences;
|
||||
@@ -1963,6 +1994,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
|
||||
n_occurrences = 0;
|
||||
subst_low_cuid = INSN_CUID (i1);
|
||||
newpat = subst (newpat, i1dest, i1src, 0, 0);
|
||||
substed_i1 = 1;
|
||||
}
|
||||
|
||||
/* Fail if an autoincrement side-effect has been duplicated. Be careful
|
||||
@@ -2534,6 +2566,23 @@ try_combine (i3, i2, i1, new_direct_jump_p)
|
||||
|
||||
INSN_CODE (i3) = insn_code_number;
|
||||
PATTERN (i3) = newpat;
|
||||
|
||||
if (GET_CODE (i3) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (i3))
|
||||
{
|
||||
rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3);
|
||||
|
||||
reset_used_flags (call_usage);
|
||||
call_usage = copy_rtx (call_usage);
|
||||
|
||||
if (substed_i2)
|
||||
replace_rtx (call_usage, i2dest, i2src);
|
||||
|
||||
if (substed_i1)
|
||||
replace_rtx (call_usage, i1dest, i1src);
|
||||
|
||||
CALL_INSN_FUNCTION_USAGE (i3) = call_usage;
|
||||
}
|
||||
|
||||
if (undobuf.other_insn)
|
||||
INSN_CODE (undobuf.other_insn) = other_code_number;
|
||||
|
||||
@@ -3013,8 +3062,11 @@ find_split_point (loc, insn)
|
||||
SUBST (SET_SRC (x),
|
||||
gen_binary (IOR, mode,
|
||||
gen_binary (AND, mode, dest,
|
||||
GEN_INT (~(mask << pos)
|
||||
& GET_MODE_MASK (mode))),
|
||||
GEN_INT
|
||||
(
|
||||
trunc_int_for_mode
|
||||
(~(mask << pos)
|
||||
& GET_MODE_MASK (mode), mode))),
|
||||
GEN_INT (src << pos)));
|
||||
|
||||
SUBST (SET_DEST (x), dest);
|
||||
@@ -3485,7 +3537,24 @@ subst (x, from, to, in_dest, unique_copy)
|
||||
if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
|
||||
return new;
|
||||
|
||||
SUBST (XEXP (x, i), new);
|
||||
if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
|
||||
{
|
||||
x = simplify_subreg (GET_MODE (x), new,
|
||||
GET_MODE (SUBREG_REG (x)),
|
||||
SUBREG_BYTE (x));
|
||||
if (! x)
|
||||
abort ();
|
||||
}
|
||||
else if (GET_CODE (new) == CONST_INT
|
||||
&& GET_CODE (x) == ZERO_EXTEND)
|
||||
{
|
||||
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
|
||||
new, GET_MODE (XEXP (x, 0)));
|
||||
if (! x)
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
SUBST (XEXP (x, i), new);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3807,6 +3876,13 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Don't change the mode of the MEM if that would change the meaning
|
||||
of the address. */
|
||||
if (GET_CODE (SUBREG_REG (x)) == MEM
|
||||
&& (MEM_VOLATILE_P (SUBREG_REG (x))
|
||||
|| mode_dependent_address_p (XEXP (SUBREG_REG (x), 0))))
|
||||
return gen_rtx_CLOBBER (mode, const0_rtx);
|
||||
|
||||
/* Note that we cannot do any narrowing for non-constants since
|
||||
we might have been counting on using the fact that some bits were
|
||||
zero. We now do this in the SET. */
|
||||
@@ -5963,6 +6039,9 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
||||
if (mode == tmode)
|
||||
return new;
|
||||
|
||||
if (GET_CODE (new) == CONST_INT)
|
||||
return GEN_INT (trunc_int_for_mode (INTVAL (new), mode));
|
||||
|
||||
/* If we know that no extraneous bits are set, and that the high
|
||||
bit is not set, convert the extraction to the cheaper of
|
||||
sign and zero extension, that are equivalent in these cases. */
|
||||
@@ -6753,33 +6832,12 @@ force_to_mode (x, mode, mask, reg, just_select)
|
||||
smask |= (HOST_WIDE_INT) -1 << width;
|
||||
|
||||
if (GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||
&& exact_log2 (- smask) >= 0)
|
||||
{
|
||||
#ifdef STACK_BIAS
|
||||
if (STACK_BIAS
|
||||
&& (XEXP (x, 0) == stack_pointer_rtx
|
||||
|| XEXP (x, 0) == frame_pointer_rtx))
|
||||
{
|
||||
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
|
||||
|
||||
sp_mask &= ~(sp_alignment - 1);
|
||||
if ((sp_mask & ~smask) == 0
|
||||
&& ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~smask) != 0)
|
||||
return force_to_mode (plus_constant (XEXP (x, 0),
|
||||
((INTVAL (XEXP (x, 1)) -
|
||||
STACK_BIAS) & smask)
|
||||
+ STACK_BIAS),
|
||||
mode, smask, reg, next_select);
|
||||
}
|
||||
#endif
|
||||
if ((nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
|
||||
&& (INTVAL (XEXP (x, 1)) & ~smask) != 0)
|
||||
return force_to_mode (plus_constant (XEXP (x, 0),
|
||||
(INTVAL (XEXP (x, 1))
|
||||
& smask)),
|
||||
mode, smask, reg, next_select);
|
||||
}
|
||||
&& exact_log2 (- smask) >= 0
|
||||
&& (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
|
||||
&& (INTVAL (XEXP (x, 1)) & ~smask) != 0)
|
||||
return force_to_mode (plus_constant (XEXP (x, 0),
|
||||
(INTVAL (XEXP (x, 1)) & smask)),
|
||||
mode, smask, reg, next_select);
|
||||
}
|
||||
|
||||
/* ... fall through ... */
|
||||
@@ -7322,7 +7380,7 @@ if_then_else_cond (x, ptrue, pfalse)
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
|
||||
&& exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
|
||||
{
|
||||
*ptrue = GEN_INT (nz), *pfalse = const0_rtx;
|
||||
*ptrue = GEN_INT (trunc_int_for_mode (nz, mode)), *pfalse = const0_rtx;
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -7431,6 +7489,50 @@ known_cond (x, cond, reg, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (code == SUBREG)
|
||||
{
|
||||
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
|
||||
rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val);
|
||||
|
||||
if (SUBREG_REG (x) != r)
|
||||
{
|
||||
/* We must simplify subreg here, before we lose track of the
|
||||
original inner_mode. */
|
||||
new = simplify_subreg (GET_MODE (x), r,
|
||||
inner_mode, SUBREG_BYTE (x));
|
||||
if (new)
|
||||
return new;
|
||||
else
|
||||
SUBST (SUBREG_REG (x), r);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
/* We don't have to handle SIGN_EXTEND here, because even in the
|
||||
case of replacing something with a modeless CONST_INT, a
|
||||
CONST_INT is already (supposed to be) a valid sign extension for
|
||||
its narrower mode, which implies it's already properly
|
||||
sign-extended for the wider mode. Now, for ZERO_EXTEND, the
|
||||
story is different. */
|
||||
else if (code == ZERO_EXTEND)
|
||||
{
|
||||
enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
|
||||
rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
|
||||
|
||||
if (XEXP (x, 0) != r)
|
||||
{
|
||||
/* We must simplify the zero_extend here, before we lose
|
||||
track of the original inner_mode. */
|
||||
new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
|
||||
r, inner_mode);
|
||||
if (new)
|
||||
return new;
|
||||
else
|
||||
SUBST (XEXP (x, 0), r);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
@@ -7743,14 +7845,23 @@ simplify_and_const_int (x, mode, varop, constop)
|
||||
int i;
|
||||
|
||||
/* Simplify VAROP knowing that we will be only looking at some of the
|
||||
bits in it. */
|
||||
bits in it.
|
||||
|
||||
Note by passing in CONSTOP, we guarantee that the bits not set in
|
||||
CONSTOP are not significant and will never be examined. We must
|
||||
ensure that is the case by explicitly masking out those bits
|
||||
before returning. */
|
||||
varop = force_to_mode (varop, mode, constop, NULL_RTX, 0);
|
||||
|
||||
/* If VAROP is a CLOBBER, we will fail so return it; if it is a
|
||||
CONST_INT, we are done. */
|
||||
if (GET_CODE (varop) == CLOBBER || GET_CODE (varop) == CONST_INT)
|
||||
/* If VAROP is a CLOBBER, we will fail so return it. */
|
||||
if (GET_CODE (varop) == CLOBBER)
|
||||
return varop;
|
||||
|
||||
/* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
|
||||
to VAROP and return the new constant. */
|
||||
if (GET_CODE (varop) == CONST_INT)
|
||||
return GEN_INT (trunc_int_for_mode (INTVAL (varop) & constop, mode));
|
||||
|
||||
/* See what bits may be nonzero in VAROP. Unlike the general case of
|
||||
a call to nonzero_bits, here we don't care about bits outside
|
||||
MODE. */
|
||||
@@ -7916,40 +8027,28 @@ nonzero_bits (x, mode)
|
||||
nonzero &= GET_MODE_MASK (ptr_mode);
|
||||
#endif
|
||||
|
||||
#ifdef STACK_BOUNDARY
|
||||
/* If this is the stack pointer, we may know something about its
|
||||
alignment. If PUSH_ROUNDING is defined, it is possible for the
|
||||
stack to be momentarily aligned only to that amount, so we pick
|
||||
the least alignment. */
|
||||
|
||||
/* We can't check for arg_pointer_rtx here, because it is not
|
||||
guaranteed to have as much alignment as the stack pointer.
|
||||
In particular, in the Irix6 n64 ABI, the stack has 128 bit
|
||||
alignment but the argument pointer has only 64 bit alignment. */
|
||||
|
||||
if ((x == frame_pointer_rtx
|
||||
|| x == stack_pointer_rtx
|
||||
|| x == hard_frame_pointer_rtx
|
||||
|| (REGNO (x) >= FIRST_VIRTUAL_REGISTER
|
||||
&& REGNO (x) <= LAST_VIRTUAL_REGISTER))
|
||||
#ifdef STACK_BIAS
|
||||
&& !STACK_BIAS
|
||||
#endif
|
||||
)
|
||||
/* Include declared information about alignment of pointers. */
|
||||
/* ??? We don't properly preserve REG_POINTER changes across
|
||||
pointer-to-integer casts, so we can't trust it except for
|
||||
things that we know must be pointers. See execute/960116-1.c. */
|
||||
if ((x == stack_pointer_rtx
|
||||
|| x == frame_pointer_rtx
|
||||
|| x == arg_pointer_rtx)
|
||||
&& REGNO_POINTER_ALIGN (REGNO (x)))
|
||||
{
|
||||
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
unsigned HOST_WIDE_INT alignment
|
||||
= REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
|
||||
|
||||
#ifdef PUSH_ROUNDING
|
||||
if (REGNO (x) == STACK_POINTER_REGNUM && PUSH_ARGS)
|
||||
sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment);
|
||||
/* If PUSH_ROUNDING is defined, it is possible for the
|
||||
stack to be momentarily aligned only to that amount,
|
||||
so we pick the least alignment. */
|
||||
if (x == stack_pointer_rtx && PUSH_ARGS)
|
||||
alignment = MIN (PUSH_ROUNDING (1), alignment);
|
||||
#endif
|
||||
|
||||
/* We must return here, otherwise we may get a worse result from
|
||||
one of the choices below. There is nothing useful below as
|
||||
far as the stack pointer is concerned. */
|
||||
return nonzero &= ~(sp_alignment - 1);
|
||||
nonzero &= ~(alignment - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If X is a register whose nonzero bits value is current, use it.
|
||||
Otherwise, if X is a register whose value we can find, use that
|
||||
@@ -7957,14 +8056,16 @@ nonzero_bits (x, mode)
|
||||
for this register. */
|
||||
|
||||
if (reg_last_set_value[REGNO (x)] != 0
|
||||
&& reg_last_set_mode[REGNO (x)] == mode
|
||||
&& (reg_last_set_mode[REGNO (x)] == mode
|
||||
|| (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
|
||||
&& GET_MODE_CLASS (mode) == MODE_INT))
|
||||
&& (reg_last_set_label[REGNO (x)] == label_tick
|
||||
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
|
||||
&& REG_N_SETS (REGNO (x)) == 1
|
||||
&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
|
||||
REGNO (x))))
|
||||
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
|
||||
return reg_last_set_nonzero_bits[REGNO (x)];
|
||||
return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
|
||||
|
||||
tem = get_last_value (x);
|
||||
|
||||
@@ -7990,7 +8091,7 @@ nonzero_bits (x, mode)
|
||||
| ((HOST_WIDE_INT) (-1)
|
||||
<< GET_MODE_BITSIZE (GET_MODE (x))));
|
||||
#endif
|
||||
return nonzero_bits (tem, mode);
|
||||
return nonzero_bits (tem, mode) & nonzero;
|
||||
}
|
||||
else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
|
||||
{
|
||||
@@ -8099,8 +8200,14 @@ nonzero_bits (x, mode)
|
||||
|
||||
case XOR: case IOR:
|
||||
case UMIN: case UMAX: case SMIN: case SMAX:
|
||||
nonzero &= (nonzero_bits (XEXP (x, 0), mode)
|
||||
| nonzero_bits (XEXP (x, 1), mode));
|
||||
{
|
||||
unsigned HOST_WIDE_INT nonzero0 = nonzero_bits (XEXP (x, 0), mode);
|
||||
|
||||
/* Don't call nonzero_bits for the second time if it cannot change
|
||||
anything. */
|
||||
if ((nonzero & nonzero0) != nonzero)
|
||||
nonzero &= (nonzero0 | nonzero_bits (XEXP (x, 1), mode));
|
||||
}
|
||||
break;
|
||||
|
||||
case PLUS: case MINUS:
|
||||
@@ -8128,22 +8235,6 @@ nonzero_bits (x, mode)
|
||||
switch (code)
|
||||
{
|
||||
case PLUS:
|
||||
#ifdef STACK_BIAS
|
||||
if (STACK_BIAS
|
||||
&& (XEXP (x, 0) == stack_pointer_rtx
|
||||
|| XEXP (x, 0) == frame_pointer_rtx)
|
||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
{
|
||||
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
|
||||
nz0 = (GET_MODE_MASK (mode) & ~(sp_alignment - 1));
|
||||
nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS;
|
||||
width0 = floor_log2 (nz0) + 1;
|
||||
width1 = floor_log2 (nz1) + 1;
|
||||
low0 = floor_log2 (nz0 & -nz0);
|
||||
low1 = floor_log2 (nz1 & -nz1);
|
||||
}
|
||||
#endif
|
||||
result_width = MAX (width0, width1) + 1;
|
||||
result_low = MIN (low0, low1);
|
||||
break;
|
||||
@@ -9590,7 +9681,7 @@ recog_for_combine (pnewpat, insn, pnotes)
|
||||
int num_clobbers_to_add = 0;
|
||||
int i;
|
||||
rtx notes = 0;
|
||||
rtx old_notes;
|
||||
rtx dummy_insn;
|
||||
|
||||
/* If PAT is a PARALLEL, check to see if it contains the CLOBBER
|
||||
we use to indicate that something didn't match. If we find such a
|
||||
@@ -9601,11 +9692,13 @@ recog_for_combine (pnewpat, insn, pnotes)
|
||||
&& XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
|
||||
return -1;
|
||||
|
||||
/* Remove the old notes prior to trying to recognize the new pattern. */
|
||||
old_notes = REG_NOTES (insn);
|
||||
REG_NOTES (insn) = 0;
|
||||
/* *pnewpat does not have to be actual PATTERN (insn), so make a dummy
|
||||
instruction for pattern recognition. */
|
||||
dummy_insn = shallow_copy_rtx (insn);
|
||||
PATTERN (dummy_insn) = pat;
|
||||
REG_NOTES (dummy_insn) = 0;
|
||||
|
||||
insn_code_number = recog (pat, insn, &num_clobbers_to_add);
|
||||
insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
|
||||
|
||||
/* If it isn't, there is the possibility that we previously had an insn
|
||||
that clobbered some register as a side effect, but the combined
|
||||
@@ -9630,15 +9723,14 @@ recog_for_combine (pnewpat, insn, pnotes)
|
||||
if (pos == 1)
|
||||
pat = XVECEXP (pat, 0, 0);
|
||||
|
||||
insn_code_number = recog (pat, insn, &num_clobbers_to_add);
|
||||
PATTERN (dummy_insn) = pat;
|
||||
insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
|
||||
}
|
||||
|
||||
/* Recognize all noop sets, these will be killed by followup pass. */
|
||||
if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
|
||||
insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0;
|
||||
|
||||
REG_NOTES (insn) = old_notes;
|
||||
|
||||
/* If we had any clobbers to add, make a new pattern than contains
|
||||
them. Then check to make sure that all of them are dead. */
|
||||
if (num_clobbers_to_add)
|
||||
@@ -10775,9 +10867,9 @@ simplify_comparison (code, pop0, pop1)
|
||||
&& XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
|
||||
&& (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
|
||||
MODE_INT, 1)) != BLKmode
|
||||
&& ((unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (tmode)
|
||||
|| ((unsigned HOST_WIDE_INT) -const_op
|
||||
<= GET_MODE_MASK (tmode))))
|
||||
&& (((unsigned HOST_WIDE_INT) const_op
|
||||
+ (GET_MODE_MASK (tmode) >> 1) + 1)
|
||||
<= GET_MODE_MASK (tmode)))
|
||||
{
|
||||
op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0));
|
||||
continue;
|
||||
@@ -10794,9 +10886,9 @@ simplify_comparison (code, pop0, pop1)
|
||||
&& XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
|
||||
&& (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
|
||||
MODE_INT, 1)) != BLKmode
|
||||
&& ((unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (tmode)
|
||||
|| ((unsigned HOST_WIDE_INT) -const_op
|
||||
<= GET_MODE_MASK (tmode))))
|
||||
&& (((unsigned HOST_WIDE_INT) const_op
|
||||
+ (GET_MODE_MASK (tmode) >> 1) + 1)
|
||||
<= GET_MODE_MASK (tmode)))
|
||||
{
|
||||
rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
|
||||
rtx add_const = XEXP (XEXP (op0, 0), 1);
|
||||
@@ -10821,10 +10913,18 @@ simplify_comparison (code, pop0, pop1)
|
||||
&& mode_width <= HOST_BITS_PER_WIDE_INT
|
||||
&& (nonzero_bits (XEXP (op0, 0), mode)
|
||||
& (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
|
||||
&& (const_op == 0
|
||||
|| (floor_log2 (const_op) + INTVAL (XEXP (op0, 1))
|
||||
< mode_width)))
|
||||
&& (((unsigned HOST_WIDE_INT) const_op
|
||||
+ (GET_CODE (op0) != LSHIFTRT
|
||||
? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
|
||||
+ 1)
|
||||
: 0))
|
||||
<= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
|
||||
{
|
||||
/* If the shift was logical, then we must make the condition
|
||||
unsigned. */
|
||||
if (GET_CODE (op0) == LSHIFTRT)
|
||||
code = unsigned_condition (code);
|
||||
|
||||
const_op <<= INTVAL (XEXP (op0, 1));
|
||||
op1 = GEN_INT (const_op);
|
||||
op0 = XEXP (op0, 0);
|
||||
@@ -10853,38 +10953,56 @@ simplify_comparison (code, pop0, pop1)
|
||||
|
||||
/* Now make any compound operations involved in this comparison. Then,
|
||||
check for an outmost SUBREG on OP0 that is not doing anything or is
|
||||
paradoxical. The latter case can only occur when it is known that the
|
||||
"extra" bits will be zero. Therefore, it is safe to remove the SUBREG.
|
||||
We can never remove a SUBREG for a non-equality comparison because the
|
||||
sign bit is in a different place in the underlying object. */
|
||||
paradoxical. The latter transformation must only be performed when
|
||||
it is known that the "extra" bits will be the same in op0 and op1 or
|
||||
that they don't matter. There are three cases to consider:
|
||||
|
||||
1. SUBREG_REG (op0) is a register. In this case the bits are don't
|
||||
care bits and we can assume they have any convenient value. So
|
||||
making the transformation is safe.
|
||||
|
||||
2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not defined.
|
||||
In this case the upper bits of op0 are undefined. We should not make
|
||||
the simplification in that case as we do not know the contents of
|
||||
those bits.
|
||||
|
||||
3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is defined and not
|
||||
NIL. In that case we know those bits are zeros or ones. We must
|
||||
also be sure that they are the same as the upper bits of op1.
|
||||
|
||||
We can never remove a SUBREG for a non-equality comparison because
|
||||
the sign bit is in a different place in the underlying object. */
|
||||
|
||||
op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
|
||||
op1 = make_compound_operation (op1, SET);
|
||||
|
||||
if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
|
||||
/* Case 3 above, to sometimes allow (subreg (mem x)), isn't
|
||||
implemented. */
|
||||
&& GET_CODE (SUBREG_REG (op0)) == REG
|
||||
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
|
||||
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
|
||||
&& (code == NE || code == EQ)
|
||||
&& ((GET_MODE_SIZE (GET_MODE (op0))
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))))
|
||||
&& (code == NE || code == EQ))
|
||||
{
|
||||
op0 = SUBREG_REG (op0);
|
||||
op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
|
||||
}
|
||||
if (GET_MODE_SIZE (GET_MODE (op0))
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
|
||||
{
|
||||
op0 = SUBREG_REG (op0);
|
||||
op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
|
||||
}
|
||||
else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
|
||||
<= HOST_BITS_PER_WIDE_INT)
|
||||
&& (nonzero_bits (SUBREG_REG (op0),
|
||||
GET_MODE (SUBREG_REG (op0)))
|
||||
& ~GET_MODE_MASK (GET_MODE (op0))) == 0)
|
||||
{
|
||||
tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1);
|
||||
|
||||
else if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
|
||||
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
|
||||
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
|
||||
&& (code == NE || code == EQ)
|
||||
&& (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
|
||||
<= HOST_BITS_PER_WIDE_INT)
|
||||
&& (nonzero_bits (SUBREG_REG (op0), GET_MODE (SUBREG_REG (op0)))
|
||||
& ~GET_MODE_MASK (GET_MODE (op0))) == 0
|
||||
&& (tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)),
|
||||
op1),
|
||||
(nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
|
||||
& ~GET_MODE_MASK (GET_MODE (op0))) == 0))
|
||||
op0 = SUBREG_REG (op0), op1 = tem;
|
||||
if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
|
||||
& ~GET_MODE_MASK (GET_MODE (op0))) == 0)
|
||||
op0 = SUBREG_REG (op0), op1 = tem;
|
||||
}
|
||||
}
|
||||
|
||||
/* We now do the opposite procedure: Some machines don't have compare
|
||||
insns in all modes. If OP0's mode is an integer mode smaller than a
|
||||
@@ -10902,14 +11020,22 @@ simplify_comparison (code, pop0, pop1)
|
||||
tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (have_insn_for (COMPARE, tmode))
|
||||
{
|
||||
int zero_extended;
|
||||
|
||||
/* If the only nonzero bits in OP0 and OP1 are those in the
|
||||
narrower mode and this is an equality or unsigned comparison,
|
||||
we can use the wider mode. Similarly for sign-extended
|
||||
values, in which case it is true for all comparisons. */
|
||||
if (((code == EQ || code == NE
|
||||
|| code == GEU || code == GTU || code == LEU || code == LTU)
|
||||
&& (nonzero_bits (op0, tmode) & ~GET_MODE_MASK (mode)) == 0
|
||||
&& (nonzero_bits (op1, tmode) & ~GET_MODE_MASK (mode)) == 0)
|
||||
zero_extended = ((code == EQ || code == NE
|
||||
|| code == GEU || code == GTU
|
||||
|| code == LEU || code == LTU)
|
||||
&& (nonzero_bits (op0, tmode)
|
||||
& ~GET_MODE_MASK (mode)) == 0
|
||||
&& ((GET_CODE (op1) == CONST_INT
|
||||
|| (nonzero_bits (op1, tmode)
|
||||
& ~GET_MODE_MASK (mode)) == 0)));
|
||||
|
||||
if (zero_extended
|
||||
|| ((num_sign_bit_copies (op0, tmode)
|
||||
> GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode))
|
||||
&& (num_sign_bit_copies (op1, tmode)
|
||||
@@ -10926,6 +11052,8 @@ simplify_comparison (code, pop0, pop1)
|
||||
XEXP (op0, 1)));
|
||||
|
||||
op0 = gen_lowpart_for_combine (tmode, op0);
|
||||
if (zero_extended && GET_CODE (op1) == CONST_INT)
|
||||
op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
|
||||
op1 = gen_lowpart_for_combine (tmode, op1);
|
||||
break;
|
||||
}
|
||||
@@ -11123,9 +11251,13 @@ record_value_for_reg (reg, insn, value)
|
||||
|
||||
if (value)
|
||||
{
|
||||
enum machine_mode mode = GET_MODE (reg);
|
||||
subst_low_cuid = INSN_CUID (insn);
|
||||
reg_last_set_mode[regno] = GET_MODE (reg);
|
||||
reg_last_set_nonzero_bits[regno] = nonzero_bits (value, GET_MODE (reg));
|
||||
reg_last_set_mode[regno] = mode;
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|
||||
mode = nonzero_bits_mode;
|
||||
reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
|
||||
reg_last_set_sign_bit_copies[regno]
|
||||
= num_sign_bit_copies (value, GET_MODE (reg));
|
||||
}
|
||||
@@ -11612,6 +11744,7 @@ mark_used_regs_combine (x)
|
||||
case CONST_INT:
|
||||
case CONST:
|
||||
case CONST_DOUBLE:
|
||||
case CONST_VECTOR:
|
||||
case PC:
|
||||
case ADDR_VEC:
|
||||
case ADDR_DIFF_VEC:
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/* Concatenate variable number of strings.
|
||||
Copyright (C) 1991, 1994, 2001 Free Software Foundation, Inc.
|
||||
Written by Fred Fish @ Cygnus Support
|
||||
|
||||
This file is part of the libiberty library.
|
||||
Libiberty is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libiberty 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libiberty; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @dots{}, @code{NULL})
|
||||
|
||||
Concatenate zero or more of strings and return the result in freshly
|
||||
@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is
|
||||
available. The argument list is terminated by the first @code{NULL}
|
||||
pointer encountered. Pointers to empty strings are ignored.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
NOTES
|
||||
|
||||
This function uses xmalloc() which is expected to be a front end
|
||||
function to malloc() that deals with low memory situations. In
|
||||
typical use, if malloc() returns NULL then xmalloc() diverts to an
|
||||
error handler routine which never returns, and thus xmalloc will
|
||||
never return a NULL pointer. If the client application wishes to
|
||||
deal with low memory situations itself, it should supply an xmalloc
|
||||
that just directly invokes malloc and blindly returns whatever
|
||||
malloc returns.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "ansidecl.h"
|
||||
#include "libiberty.h"
|
||||
#include <sys/types.h> /* size_t */
|
||||
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
# if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# else
|
||||
# if HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#if HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static inline unsigned long vconcat_length PARAMS ((const char *, va_list));
|
||||
static inline unsigned long
|
||||
vconcat_length (first, args)
|
||||
const char *first;
|
||||
va_list args;
|
||||
{
|
||||
unsigned long length = 0;
|
||||
const char *arg;
|
||||
|
||||
for (arg = first; arg ; arg = va_arg (args, const char *))
|
||||
length += strlen (arg);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static inline char *vconcat_copy PARAMS ((char *, const char *, va_list));
|
||||
static inline char *
|
||||
vconcat_copy (dst, first, args)
|
||||
char *dst;
|
||||
const char *first;
|
||||
va_list args;
|
||||
{
|
||||
char *end = dst;
|
||||
const char *arg;
|
||||
|
||||
for (arg = first; arg ; arg = va_arg (args, const char *))
|
||||
{
|
||||
unsigned long length = strlen (arg);
|
||||
memcpy (end, arg, length);
|
||||
end += length;
|
||||
}
|
||||
*end = '\000';
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* @undocumented concat_length */
|
||||
|
||||
unsigned long
|
||||
concat_length VPARAMS ((const char *first, ...))
|
||||
{
|
||||
unsigned long length;
|
||||
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
length = vconcat_length (first, args);
|
||||
VA_CLOSE (args);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/* @undocumented concat_copy */
|
||||
|
||||
char *
|
||||
concat_copy VPARAMS ((char *dst, const char *first, ...))
|
||||
{
|
||||
char *save_dst;
|
||||
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, char *, dst);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
vconcat_copy (dst, first, args);
|
||||
save_dst = dst; /* With K&R C, dst goes out of scope here. */
|
||||
VA_CLOSE (args);
|
||||
|
||||
return save_dst;
|
||||
}
|
||||
|
||||
char *libiberty_concat_ptr;
|
||||
|
||||
/* @undocumented concat_copy2 */
|
||||
|
||||
char *
|
||||
concat_copy2 VPARAMS ((const char *first, ...))
|
||||
{
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
vconcat_copy (libiberty_concat_ptr, first, args);
|
||||
VA_CLOSE (args);
|
||||
|
||||
return libiberty_concat_ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
concat VPARAMS ((const char *first, ...))
|
||||
{
|
||||
char *newstr;
|
||||
|
||||
/* First compute the size of the result and get sufficient memory. */
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
|
||||
VA_CLOSE (args);
|
||||
|
||||
/* Now copy the individual pieces to the result string. */
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
vconcat_copy (newstr, first, args);
|
||||
VA_CLOSE (args);
|
||||
|
||||
return newstr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @dots{}, @code{NULL})
|
||||
|
||||
Same as @code{concat}, except that if @var{optr} is not @code{NULL} it
|
||||
is freed after the string is created. This is intended to be useful
|
||||
when you're extending an existing string or building up a string in a
|
||||
loop:
|
||||
|
||||
@example
|
||||
str = reconcat (str, "pre-", str, NULL);
|
||||
@end example
|
||||
|
||||
@end deftypefn
|
||||
|
||||
*/
|
||||
|
||||
char *
|
||||
reconcat VPARAMS ((char *optr, const char *first, ...))
|
||||
{
|
||||
char *newstr;
|
||||
|
||||
/* First compute the size of the result and get sufficient memory. */
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, char *, optr);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
|
||||
VA_CLOSE (args);
|
||||
|
||||
/* Now copy the individual pieces to the result string. */
|
||||
VA_OPEN (args, first);
|
||||
VA_FIXEDARG (args, char *, optr);
|
||||
VA_FIXEDARG (args, const char *, first);
|
||||
vconcat_copy (newstr, first, args);
|
||||
if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */
|
||||
free (optr);
|
||||
VA_CLOSE (args);
|
||||
|
||||
return newstr;
|
||||
}
|
||||
|
||||
#ifdef MAIN
|
||||
#define NULLP (char *)0
|
||||
|
||||
/* Simple little test driver. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
printf ("\"\" = \"%s\"\n", concat (NULLP));
|
||||
printf ("\"a\" = \"%s\"\n", concat ("a", NULLP));
|
||||
printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP));
|
||||
printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP));
|
||||
printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP));
|
||||
printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP));
|
||||
printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+247
-78
@@ -207,6 +207,80 @@ gas="$gas_flag"
|
||||
gnu_ld="$gnu_ld_flag"
|
||||
enable_threads=$enable_threads_flag
|
||||
|
||||
# Obsolete configurations.
|
||||
# To avoid some tedious lists, we have a blacklist with a whitelist
|
||||
# embedded within it.
|
||||
case $machine in
|
||||
1750a-* \
|
||||
| a29k-* \
|
||||
| alpha*-*-osf[123]* \
|
||||
| arm-*-riscix* \
|
||||
| c*-convex-* \
|
||||
| clipper-* \
|
||||
| elxsi-* \
|
||||
| i860-* \
|
||||
| i?86-*-aix* \
|
||||
| i?86-*-bsd* \
|
||||
| i?86-*-chorusos* \
|
||||
| i?86-*-dgux* \
|
||||
| i?86-*-freebsd1.* \
|
||||
| i?86-*-isc* \
|
||||
| i?86-*-linux*oldld* \
|
||||
| i?86-*-osf1* \
|
||||
| i?86-*-osfrose* \
|
||||
| i?86-*-rtemscoff* \
|
||||
| i?86-*-sunos* \
|
||||
| i?86-go32-rtems* \
|
||||
| i?86-next-* \
|
||||
| i?86-sequent-bsd* \
|
||||
| i?86-sequent-ptx[12]* \
|
||||
| i?86-sequent-sysv3* \
|
||||
| m68[k0]*-*-lynxos* \
|
||||
| m68[k0]*-*-rtemscoff* \
|
||||
| m68[k0]*-*-sysv3* \
|
||||
| m68[k0]*-altos-* \
|
||||
| m68[k0]*-apollo-* \
|
||||
| m68[k0]*-apple-* \
|
||||
| m68[k0]*-bull-* \
|
||||
| m68[k0]*-convergent-* \
|
||||
| m68[k0]*-isi-* \
|
||||
| m68[k0]*-next-* \
|
||||
| m68[k0]*-sony-* \
|
||||
| m88k-* \
|
||||
| mips-*-bsd* \
|
||||
| mips-*-riscos* \
|
||||
| mips-*-sysv* \
|
||||
| mips-*-ultrix* \
|
||||
| mips-dec-* \
|
||||
| mips-sgi-irix[1234]* \
|
||||
| mips-sony-* \
|
||||
| mips-tandem-* \
|
||||
| ns32k-* \
|
||||
| pj-* \
|
||||
| pjl-* \
|
||||
| romp-* \
|
||||
| sparc-*-rtemsaout* \
|
||||
| we32k-* \
|
||||
)
|
||||
case $machine in
|
||||
mips-sni-sysv4 \
|
||||
| m88k-*-aout* | m88k-*-openbsd* | m88k-*-sysv4* \
|
||||
| ns32k-*-netbsd* | ns32k-*-openbsd* \
|
||||
| romp-*-openbsd* \
|
||||
)
|
||||
# Whitelisted.
|
||||
;;
|
||||
*)
|
||||
if test "x$enable_obsolete" != xyes; then
|
||||
echo "*** Configuration $machine is obsolete." >&2
|
||||
echo "*** Specify --enable-obsolete to build it anyway." >&2
|
||||
echo "*** Support will be REMOVED in the next major release of GCC," >&2
|
||||
echo "*** unless a maintainer comes forward." >&2
|
||||
exit 1
|
||||
fi;;
|
||||
esac
|
||||
esac
|
||||
|
||||
# Set default cpu_type, tm_file, tm_p_file and xm_file so it can be
|
||||
# updated in each machine entry. Also set default extra_headers for some
|
||||
# machines.
|
||||
@@ -243,7 +317,7 @@ ia64-*-*)
|
||||
hppa*-*-* | parisc*-*-*)
|
||||
cpu_type=pa
|
||||
;;
|
||||
m680[02]0-*-*)
|
||||
m680[012]0-*-*)
|
||||
cpu_type=m68k
|
||||
extra_headers=math-68881.h
|
||||
;;
|
||||
@@ -263,6 +337,9 @@ powerpc*-*-*)
|
||||
sparc*-*-*)
|
||||
cpu_type=sparc
|
||||
;;
|
||||
sh64-*-*)
|
||||
cpu_type=sh
|
||||
;;
|
||||
esac
|
||||
|
||||
tm_file=${cpu_type}/${cpu_type}.h
|
||||
@@ -320,7 +397,7 @@ case $machine in
|
||||
fi
|
||||
;;
|
||||
*-*-netbsd*)
|
||||
tmake_file="t-libc-ok t-netbsd"
|
||||
tmake_file="t-slibgcc-elf-ver t-libc-ok t-netbsd"
|
||||
xm_defines=POSIX
|
||||
gas=yes
|
||||
gnu_ld=yes
|
||||
@@ -360,7 +437,7 @@ case $machine in
|
||||
*-*-freebsd6 | *-*-freebsd[6].*) fbsd_tm_file="freebsd6.h";;
|
||||
*) echo 'Please update *-*-freebsd* in gcc/config.gcc'; exit 1;;
|
||||
esac
|
||||
tmake_file=t-freebsd
|
||||
tmake_file="t-slibgcc-elf-ver t-freebsd"
|
||||
xmake_file=none
|
||||
xm_defines=POSIX
|
||||
case x${enable_threads} in
|
||||
@@ -368,6 +445,12 @@ case $machine in
|
||||
x | xyes | xpthreads | xposix)
|
||||
thread_file='posix'
|
||||
tmake_file="${tmake_file} t-freebsd-thread"
|
||||
# Before 5.0, FreeBSD can't bind shared libraries to -lc
|
||||
# when "optionally" threaded via weak pthread_* checks.
|
||||
case $machine in
|
||||
*-*-freebsd[34] | *-*-freebsd[34].*)
|
||||
tmake_file="${tmake_file} t-slibgcc-nolc-override";;
|
||||
esac
|
||||
;;
|
||||
*) echo 'Unknown thread configuration for FreeBSD'; exit 1;;
|
||||
esac
|
||||
@@ -407,7 +490,8 @@ a29k-*-udi | a29k-*-coff)
|
||||
tmake_file=a29k/t-a29kbare
|
||||
;;
|
||||
a29k*-*-rtems*)
|
||||
tm_file=a29k/rtems.h
|
||||
xm_defines=POSIX
|
||||
tm_file="a29k/a29k.h a29k/rtems.h rtems.h"
|
||||
tmake_file="a29k/t-a29kbare t-rtems"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
@@ -587,13 +671,6 @@ arc-*-elf*)
|
||||
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
|
||||
extra_parts="crtinit.o crtfini.o"
|
||||
;;
|
||||
arm*-*-rtems*)
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
|
||||
tmake_file="arm/t-arm-elf t-rtems"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
arm-*-coff* | armel-*-coff*)
|
||||
tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h"
|
||||
tmake_file=arm/t-arm-coff
|
||||
@@ -629,6 +706,9 @@ arm*-*-freebsd*|strongarm*-*-freebsd*)
|
||||
tm_file="dbxelf.h elfos.h ${fbsd_tm_file} arm/elf.h arm/aout.h arm/freebsd.h arm/arm.h"
|
||||
tmake_file="${tmake_file} arm/t-strongarm-elf"
|
||||
;;
|
||||
arm*-*-netbsdelf*)
|
||||
echo "GCC does not yet support the ${machine} target"; exit 1
|
||||
;;
|
||||
arm*-*-netbsd*)
|
||||
tm_file="arm/aout.h arm/arm.h netbsd.h netbsd-aout.h arm/netbsd.h"
|
||||
tmake_file="t-netbsd arm/t-netbsd"
|
||||
@@ -657,6 +737,14 @@ arm*-*-ecos-elf)
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
|
||||
tmake_file=arm/t-arm-elf
|
||||
;;
|
||||
arm*-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
|
||||
tmake_file="arm/t-arm-elf t-rtems"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
arm*-*-elf)
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
|
||||
tmake_file=arm/t-arm-elf
|
||||
@@ -697,8 +785,9 @@ c38-convex-*)
|
||||
use_collect2=yes
|
||||
;;
|
||||
c4x-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="c4x/t-c4x t-rtems"
|
||||
tm_file=c4x/rtems.h
|
||||
tm_file="c4x/c4x.h c4x/rtems.h rtems.h"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
@@ -753,8 +842,9 @@ fr30-*-elf)
|
||||
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
|
||||
;;
|
||||
h8300-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="h8300/t-h8300 t-rtems"
|
||||
tm_file=h8300/rtems.h
|
||||
tm_file="h8300/h8300.h h8300/rtems.h rtems.h"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
@@ -794,32 +884,39 @@ hppa1.1-*-pro*)
|
||||
target_cpu_default="(MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT)"
|
||||
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h"
|
||||
tmake_file="pa/t-bsd pa/t-pro"
|
||||
xmake_file="pa/x-ada"
|
||||
;;
|
||||
hppa1.1-*-osf*)
|
||||
target_cpu_default="MASK_PA_11"
|
||||
tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-osf.h"
|
||||
tmake_file="pa/t-bsd pa/t-pa"
|
||||
xmake_file="pa/x-ada"
|
||||
use_collect2=yes
|
||||
;;
|
||||
hppa1.1-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
target_cpu_default="(MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT)"
|
||||
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h pa/rtems.h"
|
||||
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h pa/rtems.h rtems.h"
|
||||
tmake_file="pa/t-bsd pa/t-pro"
|
||||
xmake_file="pa/x-ada"
|
||||
;;
|
||||
hppa1.0-*-osf*)
|
||||
tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-osf.h"
|
||||
tmake_file="pa/t-bsd pa/t-pa"
|
||||
xmake_file="pa/x-ada"
|
||||
use_collect2=yes
|
||||
;;
|
||||
hppa1.1-*-bsd*)
|
||||
tm_file="${tm_file} pa/pa32-regs.h pa/som.h"
|
||||
target_cpu_default="MASK_PA_11"
|
||||
tmake_file="pa/t-bsd pa/t-pa"
|
||||
xmake_file="pa/x-ada"
|
||||
use_collect2=yes
|
||||
;;
|
||||
hppa1.0-*-bsd*)
|
||||
tm_file="${tm_file} pa/pa32-regs.h pa/som.h"
|
||||
tmake_file="pa/t-bsd pa/t-pa"
|
||||
xmake_file="pa/x-ada"
|
||||
use_collect2=yes
|
||||
;;
|
||||
hppa1.0-*-hpux7*)
|
||||
@@ -873,6 +970,7 @@ hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
|
||||
float_format=i128
|
||||
xm_defines=POSIX
|
||||
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
|
||||
xmake_file="pa/x-ada"
|
||||
if test x$enable_threads = x; then
|
||||
enable_threads=$have_pthread_h
|
||||
fi
|
||||
@@ -889,6 +987,7 @@ hppa1.0-*-hpux10*)
|
||||
float_format=i128
|
||||
xm_defines=POSIX
|
||||
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
|
||||
xmake_file="pa/x-ada"
|
||||
if test x$enable_threads = x; then
|
||||
enable_threads=$have_pthread_h
|
||||
fi
|
||||
@@ -905,6 +1004,7 @@ hppa*64*-*-hpux11*)
|
||||
tm_file="pa/pa64-start.h ${tm_file} pa/pa64-regs.h pa/long_double.h pa/elf.h pa/pa-hpux.h pa/pa-hpux11.h pa/pa-64.h pa/pa64-hpux.h"
|
||||
float_format=i128
|
||||
tmake_file="pa/t-pa64 pa/t-pa-hpux"
|
||||
xmake_file="pa/x-ada"
|
||||
target_cpu_default="(MASK_PA_11|MASK_PA_20|MASK_GAS)"
|
||||
|
||||
# if [ x$enable_threads = x ]; then
|
||||
@@ -923,6 +1023,7 @@ hppa1.1-*-hpux11* | hppa2*-*-hpux11*)
|
||||
float_format=i128
|
||||
xm_defines=POSIX
|
||||
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
|
||||
xmake_file="pa/x-ada"
|
||||
# if test x$enable_threads = x; then
|
||||
# enable_threads=$have_pthread_h
|
||||
# fi
|
||||
@@ -938,6 +1039,7 @@ hppa1.0-*-hpux11*)
|
||||
float_format=i128
|
||||
xm_defines=POSIX
|
||||
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
|
||||
xmake_file="pa/x-ada"
|
||||
# if test x$enable_threads = x; then
|
||||
# enable_threads=$have_pthread_h
|
||||
# fi
|
||||
@@ -982,6 +1084,7 @@ hppa*-*-lites*)
|
||||
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h"
|
||||
target_cpu_default="MASK_PA_11"
|
||||
tmake_file="pa/t-bsd pa/t-pa"
|
||||
xmake_file="pa/x-ada"
|
||||
use_collect2=yes
|
||||
;;
|
||||
hppa*-*-mpeix*)
|
||||
@@ -1221,7 +1324,7 @@ i[34567]86-*-linux*) # Intel 80386's running GNU/Linux
|
||||
x86_64-*-linux*)
|
||||
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h \
|
||||
i386/x86-64.h i386/linux64.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff i386/t-linux64"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
float_format=i386
|
||||
@@ -1281,21 +1384,24 @@ i[34567]86-*-osfrose*) # 386 using OSF/rose
|
||||
extra_objs=halfpic.o
|
||||
;;
|
||||
i[34567]86-go32-rtems*)
|
||||
tm_file=i386/djgpp-rtems.h
|
||||
xm_defines=POSIX
|
||||
tm_file="i386/djgpp.h i386/djgpp-rtems.h rtems.h"
|
||||
tmake_file=t-rtems
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
i[34567]86-*-rtemscoff*)
|
||||
tm_file=i386/rtems.h
|
||||
xm_defines=POSIX
|
||||
tm_file="i386/i386-coff.h i386/rtems.h rtems.h"
|
||||
tmake_file=t-rtems
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
i[34567]86-*-rtems*|i[34567]86-*-rtemself*)
|
||||
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/rtemself.h rtems.h"
|
||||
xm_defines=POSIX
|
||||
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/rtemself.h rtems.h"
|
||||
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
|
||||
tmake_file="i386/t-rtems-i386 i386/t-crtstuff t-rtems"
|
||||
if test x$enable_threads = xyes; then
|
||||
@@ -1319,7 +1425,6 @@ i[34567]86-*-solaris2*)
|
||||
xm_defines="POSIX SMALL_ARG_MAX"
|
||||
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sol2.h"
|
||||
if test x$gas = xyes; then
|
||||
# Only needed if gas does not support -s
|
||||
tm_file="i386/sol2gas.h ${tm_file}"
|
||||
fi
|
||||
tmake_file="i386/t-sol2 t-svr4"
|
||||
@@ -1557,8 +1662,9 @@ i960-*-coff*)
|
||||
cxx_target_objs="i960-c.o"
|
||||
;;
|
||||
i960-*-rtems)
|
||||
xm_defines=POSIX
|
||||
tmake_file="i960/t-960bare t-rtems"
|
||||
tm_file="${tm_file} dbxcoff.h i960/rtems.h"
|
||||
tm_file="${tm_file} dbxcoff.h i960/i960-coff.h i960/rtems.h rtems.h"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
@@ -1591,7 +1697,7 @@ ia64*-*-elf*)
|
||||
float_format=i386
|
||||
;;
|
||||
ia64*-*-freebsd*)
|
||||
tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h ia64/sysv4.h ia64/freebsd.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} ia64/sysv4.h ia64/freebsd.h"
|
||||
target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
|
||||
tmake_file="${tmake_file} ia64/t-ia64"
|
||||
float_format=i386
|
||||
@@ -1932,6 +2038,18 @@ m68k-*-lynxos*)
|
||||
tmake_file=m68k/t-lynx
|
||||
float_format=m68k
|
||||
;;
|
||||
m68010-*-netbsdelf* | m68k*-*-netbsdelf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h m68k/netbsd-elf.h"
|
||||
case $machine in
|
||||
m68010*)
|
||||
target_cpu_default="0"
|
||||
;;
|
||||
*)
|
||||
target_cpu_default="MASK_68020|MASK_68881|MASK_BITFIELD"
|
||||
;;
|
||||
esac
|
||||
float_format=m68k
|
||||
;;
|
||||
m68k*-*-netbsd*)
|
||||
tm_file=m68k/netbsd.h
|
||||
tmake_file=t-netbsd
|
||||
@@ -1991,16 +2109,18 @@ m68k-*-psos*)
|
||||
float_format=m68k
|
||||
;;
|
||||
m68k-*-rtemscoff*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="m68k/t-m68kbare t-rtems"
|
||||
tm_file=m68k/rtems.h
|
||||
tm_file="m68k/m68k-coff.h m68k/rtems.h rtems.h"
|
||||
float_format=m68k
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
m68k-*-rtemself*|m68k-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="m68k/t-m68kbare t-rtems m68k/t-crtstuff"
|
||||
tm_file=m68k/rtemself.h
|
||||
tm_file="m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h m68k/rtemself.h rtems.h"
|
||||
float_format=m68k
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
if test x$enable_threads = xyes; then
|
||||
@@ -2518,14 +2638,16 @@ mips64orion-*-elf*)
|
||||
tmake_file=mips/t-elf
|
||||
;;
|
||||
mips64orion-*-rtems*)
|
||||
tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h"
|
||||
xm_defines=POSIX
|
||||
tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h rtems.h"
|
||||
tmake_file="mips/t-elf t-rtems"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
mips*-*-rtems*)
|
||||
tm_file="mips/elf.h mips/rtems.h"
|
||||
xm_defines=POSIX
|
||||
tm_file="mips/elf.h mips/rtems.h rtems.h"
|
||||
tmake_file="mips/t-elf t-rtems"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
@@ -2602,6 +2724,9 @@ ns32k-pc532-minix*)
|
||||
xm_defines='POSIX HZ=60'
|
||||
use_collect2=yes
|
||||
;;
|
||||
ns32k-*-netbsdelf*)
|
||||
echo "GCC does not yet support the ${machine} target"; exit 1
|
||||
;;
|
||||
ns32k-*-netbsd*)
|
||||
tm_file=ns32k/netbsd.h
|
||||
# On NetBSD, the headers are already okay, except for math.h.
|
||||
@@ -2643,7 +2768,12 @@ powerpc-*-openbsd*)
|
||||
powerpc64-*-linux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux64.h"
|
||||
out_file=rs6000/rs6000.c
|
||||
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
|
||||
tmake_file="rs6000/t-rs6000 t-slibgcc-elf-ver t-linux rs6000/t-linux64"
|
||||
;;
|
||||
powerpc64-*-gnu*)
|
||||
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux64.h rs6000/gnu.h"
|
||||
out_file=rs6000/rs6000.c
|
||||
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
tm_file="${tm_file} rs6000/aix.h rs6000/beos.h rs6000/xcoff.h"
|
||||
@@ -2719,7 +2849,7 @@ powerpc-*-eabi*)
|
||||
;;
|
||||
powerpc-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rtems.h rs6000/rtems.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h rtems.h"
|
||||
tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
@@ -2749,6 +2879,22 @@ powerpc-*-linux*)
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
powerpc-*-gnu-gnualtivec*)
|
||||
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
|
||||
out_file=rs6000/rs6000.c
|
||||
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
powerpc-*-gnu*)
|
||||
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/gnu.h"
|
||||
out_file=rs6000/rs6000.c
|
||||
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
powerpc-wrs-vxworks*)
|
||||
xm_defines=POSIX
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/vxppc.h"
|
||||
@@ -2852,11 +2998,11 @@ s390-*-linux*)
|
||||
fi
|
||||
;;
|
||||
s390x-*-linux*)
|
||||
tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h s390/linux64.h"
|
||||
tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
|
||||
tm_p_file=s390/s390-protos.h
|
||||
md_file=s390/s390.md
|
||||
out_file=s390/s390.c
|
||||
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux s390/t-linux64"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
@@ -2867,17 +3013,29 @@ sh-*-elf*)
|
||||
tm_file="${tm_file} sh/elf.h"
|
||||
float_format=sh
|
||||
;;
|
||||
sh64-*-elf*)
|
||||
tmake_file="sh/t-sh sh/t-elf sh/t-sh64"
|
||||
tm_file="${tm_file} sh/sh.h sh/elf.h sh/sh64.h"
|
||||
float_format=sh
|
||||
extra_headers="../../config/sh/shmedia.h ../../config/sh/ushmedia.h ../../config/sh/sshmedia.h"
|
||||
# Not strictly necessary to check this, but a good idea anyway.
|
||||
if test $machine = $target; then
|
||||
target_requires_64bit_host_wide_int=yes
|
||||
fi
|
||||
;;
|
||||
sh-*-rtemself*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="sh/t-sh sh/t-elf t-rtems"
|
||||
tm_file="${tm_file} sh/elf.h sh/rtemself.h"
|
||||
tm_file="${tm_file} sh/elf.h sh/rtemself.h rtems.h"
|
||||
float_format=sh
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
sh-*-rtems*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="sh/t-sh t-rtems"
|
||||
tm_file="${tm_file} sh/rtems.h"
|
||||
tm_file="${tm_file} sh/rtems.h rtems.h"
|
||||
float_format=sh
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='rtems'
|
||||
@@ -2901,7 +3059,7 @@ sparc-tti-*)
|
||||
;;
|
||||
sparc64-wrs-vxworks*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h sparc/biarch64.h gofast.h sparc/vxsparc64.h"
|
||||
tmake_file=sparc/t-vxsparc64
|
||||
tmake_file="sparc/t-vxsparc64 sparc/t-crtfm"
|
||||
use_collect2=yes
|
||||
;;
|
||||
sparc-wrs-vxworks* | sparclite-wrs-vxworks*)
|
||||
@@ -2914,6 +3072,9 @@ sparc-*-aout*)
|
||||
tmake_file=sparc/t-sparcbare
|
||||
tm_file="sparc/sparc.h aoutos.h sparc/aout.h libgloss.h"
|
||||
;;
|
||||
sparc-*-netbsdelf*)
|
||||
tm_file="${tm_file} elfos.h svr4.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
|
||||
;;
|
||||
sparc-*-netbsd*)
|
||||
tm_file="${tm_file} sparc/aout.h netbsd.h netbsd-aout.h sparc/netbsd.h"
|
||||
tmake_file=t-netbsd
|
||||
@@ -2931,7 +3092,7 @@ sparc-*-bsd*)
|
||||
;;
|
||||
sparc-*-chorusos*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h chorus.h"
|
||||
tmake_file=sparc/t-chorus-elf
|
||||
tmake_file="sparc/t-chorus-elf sparc/t-crtfm"
|
||||
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
|
||||
float_format=i64
|
||||
case x${enable_threads} in
|
||||
@@ -2942,7 +3103,7 @@ sparc-*-chorusos*)
|
||||
;;
|
||||
sparc-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h"
|
||||
tmake_file=sparc/t-elf
|
||||
tmake_file="sparc/t-elf sparc/t-crtfm"
|
||||
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
|
||||
#float_format=i128
|
||||
float_format=i64
|
||||
@@ -2953,14 +3114,14 @@ sparc-*-linux*aout*) # Sparc's running GNU/Linux, a.out
|
||||
;;
|
||||
sparc-*-linux*libc1*) # Sparc's running GNU/Linux, libc5
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1 sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
float_format=sparc
|
||||
;;
|
||||
sparc-*-linux*) # Sparc's running GNU/Linux, libc6
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
@@ -2978,6 +3139,7 @@ sparc-*-lynxos*)
|
||||
tmake_file=sparc/t-sunos41
|
||||
;;
|
||||
sparc-*-rtemsaout*)
|
||||
xm_defines=POSIX
|
||||
tmake_file="sparc/t-sparcbare t-rtems"
|
||||
tm_file="${tm_file} aoutos.h sparc/aout.h sparc/rtems.h rtems.h"
|
||||
if test x$enable_threads = xyes; then
|
||||
@@ -2985,8 +3147,9 @@ sparc-*-rtemsaout*)
|
||||
fi
|
||||
;;
|
||||
sparc-*-rtems*|sparc-*-rtemself*)
|
||||
xm_defines=POSIX
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h sparc/rtemself.h rtems.h"
|
||||
tmake_file="sparc/t-elf t-rtems"
|
||||
tmake_file="sparc/t-elf sparc/t-crtfm t-rtems"
|
||||
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
|
||||
#float_format=i128
|
||||
float_format=i64
|
||||
@@ -2994,22 +3157,23 @@ sparc-*-rtems*|sparc-*-rtemself*)
|
||||
thread_file='rtems'
|
||||
fi
|
||||
;;
|
||||
sparcv9-*-solaris2* | sparc64-*-solaris2*)
|
||||
if test x$gnu_ld = xyes
|
||||
then
|
||||
tm_file="sparc/sol2-sld-64.h sparc/sol2-64.h"
|
||||
else
|
||||
tm_file=sparc/sol2-sld-64.h
|
||||
sparc64-*-solaris2* | sparcv9-*-solaris2*)
|
||||
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sol2-64.h sparc/sol2-bi.h"
|
||||
if test x$gnu_ld = xyes; then
|
||||
tm_file="${tm_file} sparc/sol2-gld.h sparc/sol2-gld-bi.h"
|
||||
fi
|
||||
if test x$gas = xyes; then
|
||||
tm_file="${tm_file} sparc/sol2-gas-bi.h"
|
||||
fi
|
||||
xm_defines=POSIX
|
||||
tmake_file="sparc/t-sol2 sparc/t-sol2-64"
|
||||
tmake_file="sparc/t-sol2 sparc/t-sol2-64 sparc/t-crtfm"
|
||||
if test x$gnu_ld = xyes; then
|
||||
tmake_file="$tmake_file t-slibgcc-elf-ver"
|
||||
else
|
||||
tmake_file="$tmake_file t-slibgcc-sld"
|
||||
fi
|
||||
extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o"
|
||||
float_format=none
|
||||
float_format=i128
|
||||
if test x${enable_threads} = x ; then
|
||||
enable_threads=$have_pthread_h
|
||||
if test x${enable_threads} = x ; then
|
||||
@@ -3027,58 +3191,50 @@ sparcv9-*-solaris2* | sparc64-*-solaris2*)
|
||||
sparc-hal-solaris2*)
|
||||
xm_defines=POSIX
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/hal.h"
|
||||
tmake_file="sparc/t-halos sparc/t-sol2"
|
||||
tmake_file="sparc/t-halos sparc/t-sol2 sparc/t-crtfm"
|
||||
if test x$gnu_ld = xyes; then
|
||||
tm_file="${tm_file} sparc/sol2-gld.h"
|
||||
tmake_file="$tmake_file t-slibgcc-elf-ver"
|
||||
else
|
||||
tmake_file="$tmake_file t-slibgcc-sld"
|
||||
fi
|
||||
extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o"
|
||||
case $machine in
|
||||
*-*-solaris2.[0-4])
|
||||
float_format=i128
|
||||
;;
|
||||
*)
|
||||
float_format=none
|
||||
;;
|
||||
esac
|
||||
float_format=i128
|
||||
thread_file='solaris'
|
||||
;;
|
||||
sparc-*-solaris2*)
|
||||
if test x$gnu_ld = xyes
|
||||
then
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h"
|
||||
else
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sol2-sld.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h"
|
||||
if test x$gnu_ld = xyes; then
|
||||
tm_file="${tm_file} sparc/sol2-gld.h"
|
||||
fi
|
||||
xm_defines=POSIX
|
||||
tmake_file=sparc/t-sol2
|
||||
tmake_file="sparc/t-sol2 sparc/t-crtfm"
|
||||
if test x$gnu_ld = xyes; then
|
||||
tmake_file="$tmake_file t-slibgcc-elf-ver"
|
||||
else
|
||||
tmake_file="$tmake_file t-slibgcc-sld"
|
||||
fi
|
||||
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
|
||||
case $machine in
|
||||
*-*-solaris2.[0-6] | *-*-solaris2.[0-6].*) ;;
|
||||
*-*-solaris2*)
|
||||
if test x$gnu_ld = xyes
|
||||
then
|
||||
tm_file="sparc/sol2-sld-64.h sparc/sol2-64.h"
|
||||
else
|
||||
tm_file="sparc/sol2-sld-64.h"
|
||||
*-*-solaris2.[789])
|
||||
tm_file="sparc/biarch64.h ${tm_file} sparc/sol2-bi.h"
|
||||
if test x$gnu_ld = xyes; then
|
||||
tm_file="${tm_file} sparc/sol2-gld-bi.h"
|
||||
fi
|
||||
if test x$gas = xyes; then
|
||||
tm_file="${tm_file} sparc/sol2-gas-bi.h"
|
||||
fi
|
||||
tmake_file="$tmake_file sparc/t-sol2-64"
|
||||
;;
|
||||
esac
|
||||
case $machine in
|
||||
*-*-solaris2.[0-4])
|
||||
float_format=i128
|
||||
;;
|
||||
*)
|
||||
float_format=none
|
||||
*-*-solaris2.[0-7] | *-*-solaris2.[0-7].*)
|
||||
if test x$gnu_ld = xno; then
|
||||
tm_file="${tm_file} sparc/sol27-sld.h"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
xm_defines=POSIX
|
||||
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
|
||||
float_format=i128
|
||||
if test x${enable_threads} = x; then
|
||||
enable_threads=$have_pthread_h
|
||||
if test x${enable_threads} = x; then
|
||||
@@ -3134,7 +3290,7 @@ sparclite-*-aout*)
|
||||
;;
|
||||
sparclite-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h gofast.h sparc/liteelf.h"
|
||||
tmake_file=sparc/t-sparclite
|
||||
tmake_file="sparc/t-sparclite sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
;;
|
||||
sparc86x-*-aout*)
|
||||
@@ -3143,7 +3299,7 @@ sparc86x-*-aout*)
|
||||
;;
|
||||
sparc86x-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h gofast.h sparc/sp86x-elf.h"
|
||||
tmake_file=sparc/t-sp86x
|
||||
tmake_file="sparc/t-sp86x sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
;;
|
||||
sparc64-*-aout*)
|
||||
@@ -3151,18 +3307,21 @@ sparc64-*-aout*)
|
||||
;;
|
||||
sparc64-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sp64-elf.h"
|
||||
tmake_file="${tmake_file} sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
;;
|
||||
sparc64-*-freebsd*|ultrasparc-*-freebsd*)
|
||||
tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/freebsd.h"
|
||||
tmake_file="${tmake_file} sparc/t-crtfm"
|
||||
xmake_file=none
|
||||
case "x$with_cpu" in
|
||||
xultrasparc) ;;
|
||||
x) with_cpu=ultrasparc ;;
|
||||
*) echo "$with_cpu not supported for freebsd target"; exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
|
||||
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-linux64"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-linux64 sparc/t-crtfm"
|
||||
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
@@ -3171,6 +3330,12 @@ sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
|
||||
fi
|
||||
float_format=sparc
|
||||
;;
|
||||
sparc64-*-netbsd*)
|
||||
tmake_file="${tmake_file} sparc/t-netbsd64"
|
||||
tm_file="sparc/biarch64.h ${tm_file}"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
|
||||
float_format=sparc
|
||||
;;
|
||||
strongarm-*-elf*)
|
||||
tm_file="arm/strongarm-elf.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
|
||||
tmake_file=arm/t-strongarm-elf
|
||||
@@ -3197,7 +3362,8 @@ thumb*-*-*)
|
||||
*** when the -mthumb switch is given to the compiler." 1>&2; exit 1; }
|
||||
;;
|
||||
v850-*-rtems*)
|
||||
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} v850/rtems.h"
|
||||
xm_defines=POSIX
|
||||
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} v850/v850.h v850/rtems.h rtems.h"
|
||||
tmake_file="v850/t-v850 t-rtems"
|
||||
if test x$stabs = xyes
|
||||
then
|
||||
@@ -3228,6 +3394,9 @@ vax-*-sysv*) # VAXen running system V
|
||||
xm_defines=POSIX
|
||||
float_format=vax
|
||||
;;
|
||||
vax-*-netbsdelf*)
|
||||
echo "GCC does not yet support the ${machine} target"; exit 1
|
||||
;;
|
||||
vax-*-netbsd*)
|
||||
tm_file="${tm_file} netbsd.h netbsd-aout.h vax/netbsd.h"
|
||||
tmake_file=t-netbsd
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* config.in. Generated automatically from configure.in by autoheader 2.13. */
|
||||
/* config.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
@@ -529,8 +529,8 @@
|
||||
/* Define if your assembler and linker support unaligned PC relative relocs. */
|
||||
#undef HAVE_AS_SPARC_UA_PCREL
|
||||
|
||||
/* Define if the assembler supports 64bit sparc. */
|
||||
#undef AS_SPARC64_FLAG
|
||||
/* Define if your assembler and linker support unaligned PC relative relocs against hidden symbols. */
|
||||
#undef HAVE_AS_SPARC_UA_PCREL_HIDDEN
|
||||
|
||||
/* Define if your assembler supports offsetable %lo(). */
|
||||
#undef HAVE_AS_OFFSETABLE_LO10
|
||||
|
||||
@@ -59,7 +59,7 @@ extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int some_small_symbolic_mem_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int call_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
@@ -90,7 +90,7 @@ extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
|
||||
extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
|
||||
int, int, int));
|
||||
|
||||
extern rtx split_small_symbolic_mem_operand PARAMS ((rtx));
|
||||
extern rtx split_small_symbolic_operand PARAMS ((rtx));
|
||||
|
||||
extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
|
||||
extern rtx get_unaligned_address PARAMS ((rtx, int));
|
||||
@@ -163,6 +163,8 @@ extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
|
||||
#endif
|
||||
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_output_mi_thunk_osf PARAMS ((FILE *, tree,
|
||||
HOST_WIDE_INT, tree));
|
||||
extern void alpha_encode_section_info PARAMS ((tree));
|
||||
#endif /* TREE CODE */
|
||||
|
||||
|
||||
@@ -43,12 +43,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#define CPP_SUBTARGET_SPEC ""
|
||||
#endif
|
||||
|
||||
/* Set the spec to use for signed char. The default tests the above macro
|
||||
but DEC's compiler can't handle the conditional in a "constant"
|
||||
operand. */
|
||||
|
||||
#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
|
||||
|
||||
#define WORD_SWITCH_TAKES_ARG(STR) \
|
||||
(!strcmp (STR, "rpath") || DEFAULT_WORD_SWITCH_TAKES_ARG(STR))
|
||||
|
||||
@@ -2079,7 +2073,8 @@ do { \
|
||||
{"reg_no_subreg_operand", {REG}}, \
|
||||
{"addition_operation", {PLUS}}, \
|
||||
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
|
||||
{"some_small_symbolic_mem_operand", {SET, PARALLEL}},
|
||||
{"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
|
||||
UNSPEC_VOLATILE}},
|
||||
|
||||
/* Define the `__builtin_va_list' type for the ABI. */
|
||||
#define BUILD_VA_LIST_TYPE(VALIST) \
|
||||
@@ -2242,3 +2237,8 @@ do { \
|
||||
|
||||
/* Generate calls to memcpy, etc., not bcopy, etc. */
|
||||
#define TARGET_MEM_FUNCTIONS 1
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
alpha_output_mi_thunk_osf (FILE, THUNK_FNDECL, DELTA, FUNCTION)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
(UNSPEC_LITERAL 11)
|
||||
(UNSPEC_LITUSE 12)
|
||||
(UNSPEC_SIBCALL 13)
|
||||
(UNSPEC_SYMBOL 14)
|
||||
])
|
||||
|
||||
;; UNSPEC_VOLATILE:
|
||||
@@ -518,31 +519,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
(sign_extend:DI (match_dup 1)))]
|
||||
"")
|
||||
|
||||
;; Do addsi3 the way expand_binop would do if we didn't have one. This
|
||||
;; generates better code. We have the anonymous addsi3 pattern below in
|
||||
;; case combine wants to make it.
|
||||
;; Don't say we have addsi3 if optimizing. This generates better code. We
|
||||
;; have the anonymous addsi3 pattern below in case combine wants to make it.
|
||||
(define_expand "addsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
|
||||
(match_operand:SI 2 "add_operand" "")))]
|
||||
""
|
||||
{
|
||||
if (optimize)
|
||||
{
|
||||
rtx op1 = gen_lowpart (DImode, operands[1]);
|
||||
rtx op2 = gen_lowpart (DImode, operands[2]);
|
||||
|
||||
if (! cse_not_expected)
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_adddi3 (tmp, op1, op2));
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
|
||||
}
|
||||
else
|
||||
emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
"! optimize"
|
||||
"")
|
||||
|
||||
(define_insn "*addsi_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
|
||||
@@ -581,6 +565,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
addl %r1,%2,%0
|
||||
subl %r1,%n2,%0")
|
||||
|
||||
(define_insn "*addsi_se2"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
||||
(sign_extend:DI
|
||||
(subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
||||
(match_operand:DI 2 "sext_add_operand" "rI,O"))
|
||||
0)))]
|
||||
""
|
||||
"@
|
||||
addl %r1,%2,%0
|
||||
subl %r1,%n2,%0")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(sign_extend:DI
|
||||
@@ -844,24 +839,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
|
||||
(match_operand:SI 2 "reg_or_8bit_operand" "")))]
|
||||
""
|
||||
{
|
||||
if (optimize)
|
||||
{
|
||||
rtx op1 = gen_lowpart (DImode, operands[1]);
|
||||
rtx op2 = gen_lowpart (DImode, operands[2]);
|
||||
|
||||
if (! cse_not_expected)
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_subdi3 (tmp, op1, op2));
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
|
||||
}
|
||||
else
|
||||
emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
"! optimize"
|
||||
"")
|
||||
|
||||
(define_insn "*subsi_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
@@ -877,6 +856,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
""
|
||||
"subl %r1,%2,%0")
|
||||
|
||||
(define_insn "*subsi_se2"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(sign_extend:DI
|
||||
(subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
(match_operand:DI 2 "reg_or_8bit_operand" "rI"))
|
||||
0)))]
|
||||
""
|
||||
"subl %r1,%2,%0")
|
||||
|
||||
(define_insn "subvsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
||||
@@ -1610,23 +1598,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
}
|
||||
[(set_attr "type" "iadd,shift")])
|
||||
|
||||
;; ??? The following pattern is made by combine, but earlier phases
|
||||
;; (specifically flow) can't handle it. This occurs in jump.c. Deal
|
||||
;; with this in a better way at some point.
|
||||
;;(define_insn ""
|
||||
;; [(set (match_operand:DI 0 "register_operand" "=r")
|
||||
;; (sign_extend:DI
|
||||
;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
;; (match_operand:DI 2 "const_int_operand" "P"))
|
||||
;; 0)))]
|
||||
;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
|
||||
;;{
|
||||
;; if (operands[2] == const1_rtx)
|
||||
;; return "addl %r1,%r1,%0";
|
||||
;; else
|
||||
;; return "s%P2addl %r1,0,%0";
|
||||
;;}
|
||||
;; [(set_attr "type" "iadd")])
|
||||
(define_insn "*ashldi_se"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(sign_extend:DI
|
||||
(subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
(match_operand:DI 2 "const_int_operand" "P"))
|
||||
0)))]
|
||||
"INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
|
||||
{
|
||||
if (operands[2] == const1_rtx)
|
||||
return "addl %r1,%r1,%0";
|
||||
else
|
||||
return "s%P2addl %r1,0,%0";
|
||||
}
|
||||
[(set_attr "type" "iadd")])
|
||||
|
||||
(define_insn "lshrdi3"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
@@ -5111,6 +5096,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
""
|
||||
"call_pal 0x86"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
;; BUGCHK is documented common to OSF/1 and VMS PALcode.
|
||||
;; NT does not document anything at 0x81 -- presumably it would generate
|
||||
;; the equivalent of SIGILL, but this isn't that important.
|
||||
;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
|
||||
(define_insn "trap"
|
||||
[(trap_if (const_int 1) (const_int 0))]
|
||||
"!TARGET_ABI_WINDOWS_NT"
|
||||
"call_pal 0x81"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
;; Finally, we have the basic data motion insns. The byte and word insns
|
||||
;; are done via define_expand. Start with the floating-point insns, since
|
||||
@@ -5292,10 +5287,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
itofs %1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
||||
|
||||
(define_insn "*movsi_nt_vms"
|
||||
(define_insn "*movsi_nt_vms_nofix"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
|
||||
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
|
||||
&& !TARGET_FIX
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
@@ -5310,6 +5306,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
st%, %R1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
|
||||
|
||||
(define_insn "*movsi_nt_vms_fix"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
|
||||
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
|
||||
&& TARGET_FIX
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
bis $31,%1,%0
|
||||
lda %0,%1
|
||||
ldah %0,%h1
|
||||
lda %0,%1
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
cpys %R1,%R1,%0
|
||||
ld%, %0,%1
|
||||
st%, %R1,%0
|
||||
ftois %1,%0
|
||||
itofs %1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
||||
|
||||
(define_insn "*movhi_nobwx"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
||||
(match_operand:HI 1 "input_operand" "rJ,n"))]
|
||||
@@ -5501,10 +5518,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
"operands[2] = pic_offset_table_rtx;")
|
||||
|
||||
(define_split
|
||||
[(match_operand 0 "some_small_symbolic_mem_operand" "")]
|
||||
[(match_operand 0 "some_small_symbolic_operand" "")]
|
||||
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
||||
[(match_dup 0)]
|
||||
"operands[0] = split_small_symbolic_mem_operand (operands[0]);")
|
||||
"operands[0] = split_small_symbolic_operand (operands[0]);")
|
||||
|
||||
(define_insn "movdi_er_high_g"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
@@ -5531,6 +5548,41 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
(const_int 0)] UNSPEC_LITERAL))]
|
||||
"operands[2] = pic_offset_table_rtx;")
|
||||
|
||||
;; With RTL inlining, at -O3, rtl is generated, stored, then actually
|
||||
;; compiled at the end of compilation. In the meantime, someone can
|
||||
;; re-encode-section-info on some symbol changing it e.g. from global
|
||||
;; to local-not-small. If this happens, we'd have emitted a plain
|
||||
;; load rather than a high+losum load and not recognize the insn.
|
||||
;;
|
||||
;; So if rtl inlining is in effect, we delay the global/not-global
|
||||
;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL.
|
||||
|
||||
(define_insn_and_split "movdi_er_maybe_g"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
|
||||
UNSPEC_SYMBOL))]
|
||||
"TARGET_EXPLICIT_RELOCS && flag_inline_functions"
|
||||
"#"
|
||||
""
|
||||
[(set (match_dup 0) (match_dup 1))]
|
||||
{
|
||||
if (local_symbolic_operand (operands[1], Pmode)
|
||||
&& !small_symbolic_operand (operands[1], Pmode))
|
||||
{
|
||||
rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
|
||||
rtx tmp;
|
||||
|
||||
tmp = gen_rtx_HIGH (Pmode, operands[1]);
|
||||
if (reload_completed)
|
||||
tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
|
||||
|
||||
tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn "*movdi_er_nofix"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
|
||||
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
|
||||
@@ -6700,13 +6752,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*exception_receiver_2"
|
||||
[(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
|
||||
UNSPECV_EHR)]
|
||||
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
|
||||
"TARGET_LD_BUGGY_LDGP"
|
||||
"@
|
||||
bis $31,%0,$29
|
||||
ldq $29,%0"
|
||||
[(set_attr "type" "ilog,ild")])
|
||||
"ldq $29,%0"
|
||||
[(set_attr "type" "ild")])
|
||||
|
||||
(define_expand "nonlocal_goto_receiver"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for Alpha Linux-based GNU systems.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Richard Henderson.
|
||||
|
||||
This file is part of GNU CC.
|
||||
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
|
||||
"-D__gnu_linux__ -Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
|
||||
SUB_CPP_PREDEFINES
|
||||
|
||||
/* The GNU C++ standard library requires that these macros be defined. */
|
||||
|
||||
@@ -79,19 +79,5 @@ Boston, MA 02111-1307, USA. */
|
||||
%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
|
||||
|
||||
|
||||
/* Make gcc agree with <machine/ansi.h> */
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_UNSIGNED
|
||||
#define WCHAR_UNSIGNED 0
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#undef WINT_TYPE
|
||||
#define WINT_TYPE "int"
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (NetBSD/alpha ELF)");
|
||||
|
||||
@@ -47,7 +47,8 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC \
|
||||
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat)"
|
||||
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat) \
|
||||
-D__EXTERN_PREFIX"
|
||||
|
||||
/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
|
||||
|
||||
@@ -56,12 +57,13 @@ Boston, MA 02111-1307, USA. */
|
||||
%{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -lc"
|
||||
|
||||
/* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are
|
||||
optimizing, -O1 if we are not. Pass -shared, -non_shared or
|
||||
optimizing, -O1 if we are not. Pass -S to silence `weak symbol
|
||||
multiply defined' warnings. Pass -shared, -non_shared or
|
||||
-call_shared as appropriate. Pass -hidden_symbol so that our
|
||||
constructor and call-frame data structures are not accidentally
|
||||
overridden. */
|
||||
#define LINK_SPEC \
|
||||
"-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \
|
||||
"-G 8 %{O*:-O3} %{!O*:-O1} -S %{static:-non_shared} \
|
||||
%{!static:%{shared:-shared -hidden_symbol _GLOBAL_*} \
|
||||
%{!shared:-call_shared}} %{pg} %{taso} %{rpath*}"
|
||||
|
||||
@@ -93,19 +95,18 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define ASM_OLDAS_SPEC ""
|
||||
|
||||
/* No point in running CPP on our assembler output. */
|
||||
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
|
||||
/* Don't pass -g to GNU as, because some versions don't accept this option. */
|
||||
#define ASM_SPEC "%{malpha-as:-g %(asm_oldas)} -nocpp %{pg}"
|
||||
#else
|
||||
/* In OSF/1 v3.2c, the assembler by default does not output file names which
|
||||
causes mips-tfile to fail. Passing -g to the assembler fixes this problem.
|
||||
??? Strictly speaking, we need -g only if the user specifies -g. Passing
|
||||
it always means that we get slightly larger than necessary object files
|
||||
if the user does not specify -g. If we don't pass -g, then mips-tfile
|
||||
will need to be fixed to work in this case. Pass -O0 since some
|
||||
optimization are broken and don't help us anyway. */
|
||||
#define ASM_SPEC "%{!mgas:-g %(asm_oldas)} -nocpp %{pg} -O0"
|
||||
optimization are broken and don't help us anyway. Pass -nocpp because
|
||||
there's no point in running CPP on our assembler output. */
|
||||
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
|
||||
#define ASM_SPEC "%{malpha-as:-g %(asm_oldas) -nocpp %{pg} -O0}"
|
||||
#else
|
||||
#define ASM_SPEC "%{!mgas:-g %(asm_oldas) -nocpp %{pg} -O0}"
|
||||
#endif
|
||||
|
||||
/* Specify to run a post-processor, mips-tfile after the assembler
|
||||
@@ -209,3 +210,7 @@ __enable_execute_stack (addr) \
|
||||
/* Handle #pragma weak and #pragma pack. */
|
||||
#undef HANDLE_SYSV_PRAGMA
|
||||
#define HANDLE_SYSV_PRAGMA 1
|
||||
|
||||
/* Handle #pragma extern_prefix. Technically only needed for Tru64 5.x,
|
||||
but easier to manipulate preprocessor bits from here. */
|
||||
#define HANDLE_PRAGMA_EXTERN_PREFIX 1
|
||||
|
||||
@@ -20,3 +20,7 @@ vcrt0.o: $(CRT0_S) $(GCC_PASSES)
|
||||
pcrt0.o: $(CRT0_S) $(GCC_PASSES)
|
||||
decc -c /names=as_is $(srcdir)/config/alpha/vms-psxcrt0.c -o pcrt0.o
|
||||
|
||||
MULTILIB_OPTIONS = mcpu=ev6
|
||||
MULTILIB_DIRNAMES = ev6
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
@@ -251,6 +251,12 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
|
||||
alpha_write_verstamp (FILE); \
|
||||
fprintf (FILE, "\t.set noreorder\n"); \
|
||||
fprintf (FILE, "\t.set volatile\n"); \
|
||||
if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
|
||||
{ \
|
||||
fprintf (FILE, "\t.arch %s\n", \
|
||||
(TARGET_CPU_EV6 ? "ev6" \
|
||||
: TARGET_MAX ? "pca56" : "ev56")); \
|
||||
} \
|
||||
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
|
||||
}
|
||||
|
||||
@@ -385,22 +391,14 @@ do { \
|
||||
#define LINK_EH_SPEC "vms-dwarf2eh.o%s "
|
||||
|
||||
#ifdef IN_LIBGCC2
|
||||
#include <libicb.h>
|
||||
#include <pdscdef.h>
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned long handle; \
|
||||
PDSCDEF *pv; \
|
||||
INVO_CONTEXT_BLK invo; \
|
||||
PDSCDEF *pv = *((PDSCDEF **) (CONTEXT)->reg [29]); \
|
||||
\
|
||||
memset (&invo, 0, sizeof (INVO_CONTEXT_BLK)); \
|
||||
\
|
||||
invo.libicb$q_ireg [29] = *((long long *) (CONTEXT)->reg [29]); \
|
||||
invo.libicb$q_ireg [30] = (long long) (CONTEXT)->cfa; \
|
||||
handle = LIB$GET_INVO_HANDLE (&invo); \
|
||||
LIB$GET_INVO_CONTEXT (handle, &invo); \
|
||||
pv = (PDSCDEF *) invo.libicb$ph_procedure_descriptor; \
|
||||
if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */ \
|
||||
pv = *(PDSCDEF **) pv; \
|
||||
\
|
||||
if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK)) \
|
||||
{ \
|
||||
@@ -426,6 +424,19 @@ do { \
|
||||
\
|
||||
goto SUCCESS; \
|
||||
} \
|
||||
else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER)) \
|
||||
{ \
|
||||
(FS)->cfa_offset = pv->pdsc$l_size; \
|
||||
(FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
|
||||
(FS)->retaddr_column = 26; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
(FS)->regs.reg[26].loc.reg = pv->pdsc$b_save_ra; \
|
||||
(FS)->regs.reg[26].how = REG_SAVED_REG; \
|
||||
(FS)->regs.reg[29].loc.reg = pv->pdsc$b_save_fp; \
|
||||
(FS)->regs.reg[29].how = REG_SAVED_REG; \
|
||||
\
|
||||
goto SUCCESS; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
@@ -508,11 +519,17 @@ do { \
|
||||
#define NAME__MAIN "__gccmain"
|
||||
#define SYMBOL__MAIN __gccmain
|
||||
|
||||
#define MD_EXEC_PREFIX "/gnu/lib/gcc-lib/"
|
||||
#define MD_STARTFILE_PREFIX "/gnu/lib/gcc-lib/"
|
||||
|
||||
/* Specify the list of include file directories. */
|
||||
#define INCLUDE_DEFAULTS \
|
||||
{ \
|
||||
{ "/gnu_gxx_include", 0, 1, 1 }, \
|
||||
{ "/gnu_cc_include", 0, 0, 0 }, \
|
||||
{ "/gnu/include", 0, 0, 0 }, \
|
||||
{ 0, 0, 0, 0 } \
|
||||
#define INCLUDE_DEFAULTS \
|
||||
{ \
|
||||
{ "/gnu/lib/gcc-lib/include", 0, 0, 0 }, \
|
||||
{ "/gnu_gxx_include", 0, 1, 1 }, \
|
||||
{ "/gnu_cc_include", 0, 0, 0 }, \
|
||||
{ "/gnu/include", 0, 0, 0 }, \
|
||||
{ 0, 0, 0, 0 } \
|
||||
}
|
||||
|
||||
#define LONGLONG_STANDALONE 1
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Under VMS, directory names cannot contain dots.
|
||||
version:=$(shell echo $(gcc_version) | sed -e 's/\./_/g')
|
||||
|
||||
libsubdir=$(libdir)/gcc-lib
|
||||
|
||||
# Rules for linker and compiler wrappers. These are only useful on
|
||||
# a VMS host.
|
||||
EXTRA_PROGRAMS=ld.exe decc.exe
|
||||
|
||||
@@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */
|
||||
/* Open files in stream mode if not otherwise explicitly specified */
|
||||
#define __UNIX_FOPEN 1
|
||||
|
||||
/* Write to stdout using fputc to avoid record terminators in pipes */
|
||||
#define __UNIX_FWRITE 1
|
||||
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
#define HOST_EXECUTABLE_SUFFIX ".exe"
|
||||
|
||||
@@ -120,6 +120,10 @@ do { \
|
||||
(*ptr++) (); \
|
||||
} while (0)
|
||||
|
||||
/* We really want to put Thumb tables in a read-only data section, but
|
||||
switching to another section during function output is not
|
||||
possible. We could however do what the SPARC does and defer the
|
||||
whole table generation until the end of the function. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
|
||||
#ifndef ARM_OS_NAME
|
||||
@@ -322,8 +326,13 @@ do { \
|
||||
|
||||
/* Output of Dispatch Tables */
|
||||
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
|
||||
fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE))
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
|
||||
do { \
|
||||
if (TARGET_ARM) \
|
||||
fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
|
||||
else \
|
||||
fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
|
||||
} while (0)
|
||||
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
|
||||
fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
|
||||
|
||||
@@ -181,8 +181,16 @@ Boston, MA 02111-1307, USA. */
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE)
|
||||
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
|
||||
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE)
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_ARM) \
|
||||
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE); \
|
||||
else \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d-%LL%d\n", VALUE, REL); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
#undef ASM_OUTPUT_ASCII
|
||||
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
|
||||
|
||||
+173
-160
@@ -266,12 +266,9 @@ int thumb_code = 0;
|
||||
PRINT_OPERAND_ADDRESS. */
|
||||
enum machine_mode output_memory_reference_mode;
|
||||
|
||||
/* Nonzero if the prologue must setup `fp'. */
|
||||
int current_function_anonymous_args;
|
||||
|
||||
/* The register number to be used for the PIC offset register. */
|
||||
const char * arm_pic_register_string = NULL;
|
||||
int arm_pic_register = 9;
|
||||
int arm_pic_register = INVALID_REGNUM;
|
||||
|
||||
/* Set to 1 when a return insn is output, this means that the epilogue
|
||||
is not needed. */
|
||||
@@ -654,8 +651,8 @@ arm_override_options ()
|
||||
|
||||
/* If stack checking is disabled, we can use r10 as the PIC register,
|
||||
which keeps r9 available. */
|
||||
if (flag_pic && !TARGET_APCS_STACK)
|
||||
arm_pic_register = 10;
|
||||
if (flag_pic)
|
||||
arm_pic_register = TARGET_APCS_STACK ? 9 : 10;
|
||||
|
||||
if (TARGET_APCS_FLOAT)
|
||||
warning ("passing floating point arguments in fp regs not yet supported");
|
||||
@@ -716,18 +713,16 @@ arm_override_options ()
|
||||
|
||||
if (arm_pic_register_string != NULL)
|
||||
{
|
||||
int pic_register;
|
||||
|
||||
int pic_register = decode_reg_name (arm_pic_register_string);
|
||||
|
||||
if (!flag_pic)
|
||||
warning ("-mpic-register= is useless without -fpic");
|
||||
|
||||
pic_register = decode_reg_name (arm_pic_register_string);
|
||||
|
||||
/* Prevent the user from choosing an obviously stupid PIC register. */
|
||||
if (pic_register < 0 || call_used_regs[pic_register]
|
||||
|| pic_register == HARD_FRAME_POINTER_REGNUM
|
||||
|| pic_register == STACK_POINTER_REGNUM
|
||||
|| pic_register >= PC_REGNUM)
|
||||
else if (pic_register < 0 || call_used_regs[pic_register]
|
||||
|| pic_register == HARD_FRAME_POINTER_REGNUM
|
||||
|| pic_register == STACK_POINTER_REGNUM
|
||||
|| pic_register >= PC_REGNUM)
|
||||
error ("unable to use '%s' for PIC register", arm_pic_register_string);
|
||||
else
|
||||
arm_pic_register = pic_register;
|
||||
@@ -902,14 +897,14 @@ use_return_insn (iscond)
|
||||
|
||||
func_type = arm_current_func_type ();
|
||||
|
||||
/* Naked functions, volatile functiond and interrupt
|
||||
functions all need special consideration. */
|
||||
if (func_type & (ARM_FT_INTERRUPT | ARM_FT_VOLATILE | ARM_FT_NAKED))
|
||||
/* Naked functions and volatile functions need special
|
||||
consideration. */
|
||||
if (func_type & (ARM_FT_VOLATILE | ARM_FT_NAKED))
|
||||
return 0;
|
||||
|
||||
/* As do variadic functions. */
|
||||
if (current_function_pretend_args_size
|
||||
|| current_function_anonymous_args
|
||||
|| cfun->machine->uses_anonymous_args
|
||||
/* Of if the function calls __builtin_eh_return () */
|
||||
|| ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
|
||||
/* Or if there is no frame pointer and there is a stack adjustment. */
|
||||
@@ -2102,9 +2097,6 @@ arm_encode_call_attribute (decl, flag)
|
||||
int len = strlen (str);
|
||||
char * newstr;
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL)
|
||||
return;
|
||||
|
||||
/* Do not allow weak functions to be treated as short call. */
|
||||
if (DECL_WEAK (decl) && flag == SHORT_CALL_FLAG_CHAR)
|
||||
return;
|
||||
@@ -2318,7 +2310,10 @@ legitimize_pic_address (orig, mode, reg)
|
||||
else
|
||||
emit_insn (gen_pic_load_addr_thumb (address, orig));
|
||||
|
||||
if (GET_CODE (orig) == LABEL_REF && NEED_GOT_RELOC)
|
||||
if ((GET_CODE (orig) == LABEL_REF
|
||||
|| (GET_CODE (orig) == SYMBOL_REF &&
|
||||
ENCODED_SHORT_CALL_ATTR_P (XSTR (orig, 0))))
|
||||
&& NEED_GOT_RELOC)
|
||||
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
|
||||
else
|
||||
{
|
||||
@@ -5334,14 +5329,29 @@ is_jump_table (insn)
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
#ifndef JUMP_TABLES_IN_TEXT_SECTION
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 0
|
||||
#endif
|
||||
|
||||
static HOST_WIDE_INT
|
||||
get_jump_table_size (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx body = PATTERN (insn);
|
||||
int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
|
||||
/* ADDR_VECs only take room if read-only data does into the text
|
||||
section. */
|
||||
if (JUMP_TABLES_IN_TEXT_SECTION
|
||||
#if !defined(READONLY_DATA_SECTION)
|
||||
|| 1
|
||||
#endif
|
||||
)
|
||||
{
|
||||
rtx body = PATTERN (insn);
|
||||
int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
|
||||
|
||||
return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
|
||||
return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move a minipool fix MP from its current location to before MAX_MP.
|
||||
@@ -7139,17 +7149,16 @@ arm_compute_save_reg_mask ()
|
||||
/* Decide if we need to save the link register.
|
||||
Interrupt routines have their own banked link register,
|
||||
so they never need to save it.
|
||||
Otheriwse if we do not use the link register we do not need to save
|
||||
Otherwise if we do not use the link register we do not need to save
|
||||
it. If we are pushing other registers onto the stack however, we
|
||||
can save an instruction in the epilogue by pushing the link register
|
||||
now and then popping it back into the PC. This incurs extra memory
|
||||
accesses though, so we only do it when optimising for size, and only
|
||||
if we know that we will not need a fancy return sequence. */
|
||||
if (! IS_INTERRUPT (func_type)
|
||||
&& (regs_ever_live [LR_REGNUM]
|
||||
if (regs_ever_live [LR_REGNUM]
|
||||
|| (save_reg_mask
|
||||
&& optimize_size
|
||||
&& ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)))
|
||||
&& ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL))
|
||||
save_reg_mask |= 1 << LR_REGNUM;
|
||||
|
||||
if (cfun->machine->lr_save_eliminated)
|
||||
@@ -7207,21 +7216,19 @@ output_return_instruction (operand, really_return, reverse)
|
||||
|
||||
live_regs_mask = arm_compute_save_reg_mask ();
|
||||
|
||||
/* On some ARM architectures it is faster to use LDR rather than LDM to
|
||||
load a single register. On other architectures, the cost is the same.
|
||||
In 26 bit mode we have to use LDM in order to be able to restore the CPSR. */
|
||||
if ((live_regs_mask == (1 << LR_REGNUM))
|
||||
&& ! TARGET_INTERWORK
|
||||
&& ! IS_INTERRUPT (func_type)
|
||||
&& (! really_return || TARGET_APCS_32))
|
||||
if (live_regs_mask)
|
||||
{
|
||||
if (! really_return)
|
||||
sprintf (instr, "ldr%s\t%%|lr, [%%|sp], #4", conditional);
|
||||
const char * return_reg;
|
||||
|
||||
/* If we do not have any special requirements for function exit
|
||||
(eg interworking, or ISR) then we can load the return address
|
||||
directly into the PC. Otherwise we must load it into LR. */
|
||||
if (really_return
|
||||
&& ! TARGET_INTERWORK)
|
||||
return_reg = reg_names[PC_REGNUM];
|
||||
else
|
||||
sprintf (instr, "ldr%s\t%%|pc, [%%|sp], #4", conditional);
|
||||
}
|
||||
else if (live_regs_mask)
|
||||
{
|
||||
return_reg = reg_names[LR_REGNUM];
|
||||
|
||||
if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
|
||||
/* There are two possible reasons for the IP register being saved.
|
||||
Either a stack frame was created, in which case IP contains the
|
||||
@@ -7233,96 +7240,91 @@ output_return_instruction (operand, really_return, reverse)
|
||||
live_regs_mask |= (1 << SP_REGNUM);
|
||||
}
|
||||
|
||||
/* Generate the load multiple instruction to restore the registers. */
|
||||
if (frame_pointer_needed)
|
||||
sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
|
||||
else
|
||||
sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
|
||||
|
||||
for (reg = 0; reg <= SP_REGNUM; reg++)
|
||||
if (live_regs_mask & (1 << reg))
|
||||
{
|
||||
strcat (instr, "%|");
|
||||
strcat (instr, reg_names[reg]);
|
||||
strcat (instr, ", ");
|
||||
}
|
||||
|
||||
if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
|
||||
/* On some ARM architectures it is faster to use LDR rather than
|
||||
LDM to load a single register. On other architectures, the
|
||||
cost is the same. In 26 bit mode, or for exception handlers,
|
||||
we have to use LDM to load the PC so that the CPSR is also
|
||||
restored. */
|
||||
for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
|
||||
{
|
||||
/* If we are not restoring the LR register then we will
|
||||
have added one too many commas to the list above.
|
||||
Replace it with a closing brace. */
|
||||
instr [strlen (instr) - 2] = '}';
|
||||
if (live_regs_mask == (unsigned int)(1 << reg))
|
||||
break;
|
||||
}
|
||||
if (reg <= LAST_ARM_REGNUM
|
||||
&& (reg != LR_REGNUM
|
||||
|| ! really_return
|
||||
|| (TARGET_APCS_32 && ! IS_INTERRUPT (func_type))))
|
||||
{
|
||||
sprintf (instr, "ldr%s\t%%|%s, [%%|sp], #4", conditional,
|
||||
(reg == LR_REGNUM) ? return_reg : reg_names[reg]);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat (instr, "%|");
|
||||
char *p;
|
||||
int first = 1;
|
||||
|
||||
/* At this point there should only be one or two registers left in
|
||||
live_regs_mask: always LR, and possibly PC if we created a stack
|
||||
frame. LR contains the return address. If we do not have any
|
||||
special requirements for function exit (eg interworking, or ISR)
|
||||
then we can load this value directly into the PC and save an
|
||||
instruction. */
|
||||
if (! TARGET_INTERWORK
|
||||
&& ! IS_INTERRUPT (func_type)
|
||||
&& really_return)
|
||||
strcat (instr, reg_names [PC_REGNUM]);
|
||||
/* Generate the load multiple instruction to restore the registers. */
|
||||
if (frame_pointer_needed)
|
||||
sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
|
||||
else
|
||||
strcat (instr, reg_names [LR_REGNUM]);
|
||||
sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
|
||||
|
||||
strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^");
|
||||
p = instr + strlen (instr);
|
||||
|
||||
for (reg = 0; reg <= SP_REGNUM; reg++)
|
||||
if (live_regs_mask & (1 << reg))
|
||||
{
|
||||
int l = strlen (reg_names[reg]);
|
||||
|
||||
if (first)
|
||||
first = 0;
|
||||
else
|
||||
{
|
||||
memcpy (p, ", ", 2);
|
||||
p += 2;
|
||||
}
|
||||
|
||||
memcpy (p, "%|", 2);
|
||||
memcpy (p + 2, reg_names[reg], l);
|
||||
p += l + 2;
|
||||
}
|
||||
|
||||
if (live_regs_mask & (1 << LR_REGNUM))
|
||||
{
|
||||
int l = strlen (return_reg);
|
||||
|
||||
if (! first)
|
||||
{
|
||||
memcpy (p, ", ", 2);
|
||||
p += 2;
|
||||
}
|
||||
|
||||
memcpy (p, "%|", 2);
|
||||
memcpy (p + 2, return_reg, l);
|
||||
strcpy (p + 2 + l, ((TARGET_APCS_32
|
||||
&& !IS_INTERRUPT (func_type))
|
||||
|| !really_return)
|
||||
? "}" : "}^");
|
||||
}
|
||||
else
|
||||
strcpy (p, "}");
|
||||
}
|
||||
|
||||
if (really_return)
|
||||
output_asm_insn (instr, & operand);
|
||||
|
||||
/* See if we need to generate an extra instruction to
|
||||
perform the actual function return. */
|
||||
if (really_return
|
||||
&& func_type != ARM_FT_INTERWORKED
|
||||
&& (live_regs_mask & (1 << LR_REGNUM)) != 0)
|
||||
{
|
||||
/* See if we need to generate an extra instruction to
|
||||
perform the actual function return. */
|
||||
switch ((int) ARM_FUNC_TYPE (func_type))
|
||||
{
|
||||
case ARM_FT_ISR:
|
||||
case ARM_FT_FIQ:
|
||||
output_asm_insn (instr, & operand);
|
||||
|
||||
strcpy (instr, "sub");
|
||||
strcat (instr, conditional);
|
||||
strcat (instr, "s\t%|pc, %|lr, #4");
|
||||
break;
|
||||
|
||||
case ARM_FT_EXCEPTION:
|
||||
output_asm_insn (instr, & operand);
|
||||
|
||||
strcpy (instr, "mov");
|
||||
strcat (instr, conditional);
|
||||
strcat (instr, "s\t%|pc, %|lr");
|
||||
break;
|
||||
|
||||
case ARM_FT_INTERWORKED:
|
||||
output_asm_insn (instr, & operand);
|
||||
|
||||
strcpy (instr, "bx");
|
||||
strcat (instr, conditional);
|
||||
strcat (instr, "\t%|lr");
|
||||
break;
|
||||
|
||||
default:
|
||||
/* The return has already been handled
|
||||
by loading the LR into the PC. */
|
||||
if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
|
||||
{
|
||||
output_asm_insn (instr, & operand);
|
||||
|
||||
strcpy (instr, "mov");
|
||||
strcat (instr, conditional);
|
||||
if (! TARGET_APCS_32)
|
||||
strcat (instr, "s");
|
||||
strcat (instr, "\t%|pc, %|lr");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* The return has already been handled
|
||||
by loading the LR into the PC. */
|
||||
really_return = 0;
|
||||
}
|
||||
}
|
||||
else if (really_return)
|
||||
|
||||
if (really_return)
|
||||
{
|
||||
switch ((int) ARM_FUNC_TYPE (func_type))
|
||||
{
|
||||
@@ -7340,18 +7342,19 @@ output_return_instruction (operand, really_return, reverse)
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
|
||||
conditional, TARGET_APCS_32 ? "" : "s");
|
||||
/* ARMv5 implementations always provide BX, so interworking
|
||||
is the default unless APCS-26 is in use. */
|
||||
if ((insn_flags & FL_ARCH5) != 0 && TARGET_APCS_32)
|
||||
sprintf (instr, "bx%s\t%%|lr", conditional);
|
||||
else
|
||||
sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
|
||||
conditional, TARGET_APCS_32 ? "" : "s");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Nothing to load off the stack, and
|
||||
no return instruction to generate. */
|
||||
return "";
|
||||
|
||||
output_asm_insn (instr, & operand);
|
||||
|
||||
output_asm_insn (instr, & operand);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -7457,9 +7460,9 @@ arm_output_function_prologue (f, frame_size)
|
||||
current_function_args_size,
|
||||
current_function_pretend_args_size, frame_size);
|
||||
|
||||
asm_fprintf (f, "\t%@ frame_needed = %d, current_function_anonymous_args = %d\n",
|
||||
asm_fprintf (f, "\t%@ frame_needed = %d, uses_anonymous_args = %d\n",
|
||||
frame_pointer_needed,
|
||||
current_function_anonymous_args);
|
||||
cfun->machine->uses_anonymous_args);
|
||||
|
||||
if (cfun->machine->lr_save_eliminated)
|
||||
asm_fprintf (f, "\t%@ link register save eliminated.\n");
|
||||
@@ -7479,8 +7482,9 @@ arm_output_epilogue (really_return)
|
||||
int reg;
|
||||
unsigned long saved_regs_mask;
|
||||
unsigned long func_type;
|
||||
/* If we need this, then it will always be at least this much. */
|
||||
int floats_offset = 12;
|
||||
/* Floats_offset is the offset from the "virtual" frame. In an APCS
|
||||
frame that is $fp + 4 for a non-variadic function. */
|
||||
int floats_offset = 0;
|
||||
rtx operands[3];
|
||||
int frame_size = get_frame_size ();
|
||||
FILE * f = asm_out_file;
|
||||
@@ -7517,6 +7521,9 @@ arm_output_epilogue (really_return)
|
||||
|
||||
saved_regs_mask = arm_compute_save_reg_mask ();
|
||||
|
||||
/* XXX We should adjust floats_offset for any anonymous args, and then
|
||||
re-adjust vfp_offset below to compensate. */
|
||||
|
||||
/* Compute how far away the floats will be. */
|
||||
for (reg = 0; reg <= LAST_ARM_REGNUM; reg ++)
|
||||
if (saved_regs_mask & (1 << reg))
|
||||
@@ -7524,6 +7531,8 @@ arm_output_epilogue (really_return)
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
int vfp_offset = 4;
|
||||
|
||||
if (arm_fpu_arch == FP_SOFT2)
|
||||
{
|
||||
for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
|
||||
@@ -7531,7 +7540,7 @@ arm_output_epilogue (really_return)
|
||||
{
|
||||
floats_offset += 12;
|
||||
asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
|
||||
reg, FP_REGNUM, floats_offset);
|
||||
reg, FP_REGNUM, floats_offset - vfp_offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -7548,7 +7557,7 @@ arm_output_epilogue (really_return)
|
||||
if (start_reg - reg == 3)
|
||||
{
|
||||
asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
|
||||
reg, FP_REGNUM, floats_offset);
|
||||
reg, FP_REGNUM, floats_offset - vfp_offset);
|
||||
start_reg = reg - 1;
|
||||
}
|
||||
}
|
||||
@@ -7557,7 +7566,7 @@ arm_output_epilogue (really_return)
|
||||
if (reg != start_reg)
|
||||
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
|
||||
reg + 1, start_reg - reg,
|
||||
FP_REGNUM, floats_offset);
|
||||
FP_REGNUM, floats_offset - vfp_offset);
|
||||
start_reg = reg - 1;
|
||||
}
|
||||
}
|
||||
@@ -7566,7 +7575,7 @@ arm_output_epilogue (really_return)
|
||||
if (reg != start_reg)
|
||||
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
|
||||
reg + 1, start_reg - reg,
|
||||
FP_REGNUM, floats_offset);
|
||||
FP_REGNUM, floats_offset - vfp_offset);
|
||||
}
|
||||
|
||||
/* saved_regs_mask should contain the IP, which at the time of stack
|
||||
@@ -7660,7 +7669,7 @@ arm_output_epilogue (really_return)
|
||||
to load use the LDR instruction - it is faster. */
|
||||
if (saved_regs_mask == (1 << LR_REGNUM))
|
||||
{
|
||||
/* The excpetion handler ignores the LR, so we do
|
||||
/* The exception handler ignores the LR, so we do
|
||||
not really need to load it off the stack. */
|
||||
if (eh_ofs)
|
||||
asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
|
||||
@@ -7686,7 +7695,10 @@ arm_output_epilogue (really_return)
|
||||
REGNO (eh_ofs));
|
||||
#endif
|
||||
|
||||
if (! really_return)
|
||||
if (! really_return
|
||||
|| (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
|
||||
&& current_function_pretend_args_size == 0
|
||||
&& saved_regs_mask & (1 << PC_REGNUM)))
|
||||
return "";
|
||||
|
||||
/* Generate the return instruction. */
|
||||
@@ -7754,7 +7766,6 @@ arm_output_function_epilogue (file, frame_size)
|
||||
abort ();
|
||||
|
||||
/* Reset the ARM-specific per-function variables. */
|
||||
current_function_anonymous_args = 0;
|
||||
after_arm_reorg = 0;
|
||||
}
|
||||
}
|
||||
@@ -8068,7 +8079,7 @@ arm_compute_initial_elimination_offset (from, to)
|
||||
/* FIXME: Not sure about this. Maybe we should always return 0 ? */
|
||||
return (frame_pointer_needed
|
||||
&& current_function_needs_context
|
||||
&& ! current_function_anonymous_args) ? 4 : 0;
|
||||
&& ! cfun->machine->uses_anonymous_args) ? 4 : 0;
|
||||
|
||||
case STACK_POINTER_REGNUM:
|
||||
/* If nothing has been pushed on the stack at all
|
||||
@@ -8209,7 +8220,7 @@ arm_expand_prologue ()
|
||||
else
|
||||
{
|
||||
/* Store the args on the stack. */
|
||||
if (current_function_anonymous_args)
|
||||
if (cfun->machine->uses_anonymous_args)
|
||||
insn = emit_multi_reg_push
|
||||
((0xf0 >> (args_to_push / 4)) & 0xf);
|
||||
else
|
||||
@@ -8245,7 +8256,7 @@ arm_expand_prologue ()
|
||||
if (args_to_push)
|
||||
{
|
||||
/* Push the argument registers, or reserve space for them. */
|
||||
if (current_function_anonymous_args)
|
||||
if (cfun->machine->uses_anonymous_args)
|
||||
insn = emit_multi_reg_push
|
||||
((0xf0 >> (args_to_push / 4)) & 0xf);
|
||||
else
|
||||
@@ -8255,6 +8266,19 @@ arm_expand_prologue ()
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
|
||||
/* If this is an interrupt service routine, and the link register is
|
||||
going to be pushed, subtracting four now will mean that the
|
||||
function return can be done with a single instruction. */
|
||||
if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ)
|
||||
&& (live_regs_mask & (1 << LR_REGNUM)) != 0)
|
||||
{
|
||||
emit_insn (gen_rtx_SET (SImode,
|
||||
gen_rtx_REG (SImode, LR_REGNUM),
|
||||
gen_rtx_PLUS (SImode,
|
||||
gen_rtx_REG (SImode, LR_REGNUM),
|
||||
GEN_INT (-4))));
|
||||
}
|
||||
|
||||
if (live_regs_mask)
|
||||
{
|
||||
insn = emit_multi_reg_push (live_regs_mask);
|
||||
@@ -8609,7 +8633,9 @@ arm_assemble_integer (x, size, aligned_p)
|
||||
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
|
||||
(GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
|
||||
{
|
||||
if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
|
||||
if (GET_CODE (x) == SYMBOL_REF
|
||||
&& (CONSTANT_POOL_ADDRESS_P (x)
|
||||
|| ENCODED_SHORT_CALL_ATTR_P (XSTR (x, 0))))
|
||||
fputs ("(GOTOFF)", asm_out_file);
|
||||
else if (GET_CODE (x) == LABEL_REF)
|
||||
fputs ("(GOTOFF)", asm_out_file);
|
||||
@@ -9139,20 +9165,8 @@ arm_hard_regno_mode_ok (regno, mode)
|
||||
return (NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
|
||||
|
||||
if (regno <= LAST_ARM_REGNUM)
|
||||
/* We allow an SImode or smaller value to be stored in any
|
||||
general purpose register. This does not mean, for example
|
||||
that GCC will choose to store a variable in the stack pointer
|
||||
since it is a fixed register. But it is important to allow
|
||||
access to these special registers, so that they can be
|
||||
referenced from C code via the asm assembler alias, eg:
|
||||
|
||||
register char * stack_ptr asm ("sp");
|
||||
|
||||
For any mode requiring more than one register to hold the
|
||||
value we restrict the choice so that r13, r14, and r15
|
||||
cannot be part of the register set. */
|
||||
return (NUM_REGS (mode) <= 1)
|
||||
|| (regno < (SP_REGNUM - (unsigned) NUM_REGS (mode)));
|
||||
/* We allow any value to be stored in the general regisetrs. */
|
||||
return 1;
|
||||
|
||||
if ( regno == FRAME_POINTER_REGNUM
|
||||
|| regno == ARG_POINTER_REGNUM)
|
||||
@@ -10187,7 +10201,6 @@ thumb_expand_prologue ()
|
||||
if (regno > LAST_LO_REGNUM) /* Very unlikely */
|
||||
{
|
||||
rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
|
||||
rtx insn;
|
||||
|
||||
/* Choose an arbitary, non-argument low register. */
|
||||
reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
|
||||
@@ -10312,7 +10325,7 @@ thumb_output_function_prologue (f, size)
|
||||
|
||||
if (current_function_pretend_args_size)
|
||||
{
|
||||
if (current_function_anonymous_args)
|
||||
if (cfun->machine->uses_anonymous_args)
|
||||
{
|
||||
int num_pushes;
|
||||
|
||||
|
||||
@@ -81,8 +81,6 @@ extern struct rtx_def * pool_vector_label;
|
||||
/* Set to 1 when a return insn is output, this means that the epilogue
|
||||
is not needed. */
|
||||
extern int return_used_this_function;
|
||||
/* Nonzero if the prologue must setup `fp'. */
|
||||
extern int current_function_anonymous_args;
|
||||
|
||||
/* Just in case configure has failed to define anything. */
|
||||
#ifndef TARGET_CPU_DEFAULT
|
||||
@@ -855,7 +853,7 @@ extern const char * structure_size_string;
|
||||
regno <= LAST_ARM_FP_REGNUM; ++regno) \
|
||||
fixed_regs[regno] = call_used_regs[regno] = 1; \
|
||||
} \
|
||||
if (flag_pic) \
|
||||
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
|
||||
{ \
|
||||
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
@@ -1029,6 +1027,13 @@ extern const char * structure_size_string;
|
||||
16, 17, 18, 19, 20, 21, 22, 23, \
|
||||
24, 25, 26 \
|
||||
}
|
||||
|
||||
/* Interrupt functions can only use registers that have already been
|
||||
saved by the prologue, even if they would normally be
|
||||
call-clobbered. */
|
||||
#define HARD_REGNO_RENAME_OK(SRC, DST) \
|
||||
(! IS_INTERRUPT (cfun->machine->func_type) || \
|
||||
regs_ever_live[DST])
|
||||
|
||||
/* Register and constant classes. */
|
||||
|
||||
@@ -1454,6 +1459,8 @@ typedef struct machine_function
|
||||
int lr_save_eliminated;
|
||||
/* Records the type of the current function. */
|
||||
unsigned long func_type;
|
||||
/* Record if the function has a variable argument list. */
|
||||
int uses_anonymous_args;
|
||||
}
|
||||
machine_function;
|
||||
|
||||
@@ -1536,8 +1543,7 @@ typedef struct
|
||||
that way. */
|
||||
#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
|
||||
{ \
|
||||
extern int current_function_anonymous_args; \
|
||||
current_function_anonymous_args = 1; \
|
||||
cfun->machine->uses_anonymous_args = 1; \
|
||||
if ((CUM).nregs < NUM_ARG_REGS) \
|
||||
(PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD; \
|
||||
}
|
||||
@@ -1844,7 +1850,8 @@ typedef struct
|
||||
#define THUMB_LEGITIMATE_CONSTANT_P(X) \
|
||||
( GET_CODE (X) == CONST_INT \
|
||||
|| GET_CODE (X) == CONST_DOUBLE \
|
||||
|| CONSTANT_ADDRESS_P (X))
|
||||
|| CONSTANT_ADDRESS_P (X) \
|
||||
|| flag_pic)
|
||||
|
||||
#define LEGITIMATE_CONSTANT_P(X) \
|
||||
(TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X) : THUMB_LEGITIMATE_CONSTANT_P (X))
|
||||
@@ -1892,9 +1899,9 @@ typedef struct
|
||||
or known to be defined in this file then encode a short call flag.
|
||||
This macro is used inside the ENCODE_SECTION macro. */
|
||||
#define ARM_ENCODE_CALL_TYPE(decl) \
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL) \
|
||||
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') \
|
||||
{ \
|
||||
if (DECL_WEAK (decl)) \
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl)) \
|
||||
arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \
|
||||
else if (! TREE_PUBLIC (decl)) \
|
||||
arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \
|
||||
|
||||
@@ -135,8 +135,12 @@
|
||||
(define_attr "neg_pool_range" "" (const_int 0))
|
||||
|
||||
; An assembler sequence may clobber the condition codes without us knowing.
|
||||
; If such an insn references the pool, then we have no way of knowing how,
|
||||
; so use the most conservative value for pool_range.
|
||||
(define_asm_attributes
|
||||
[(set_attr "conds" "clob")])
|
||||
[(set_attr "conds" "clob")
|
||||
(set_attr "length" "4")
|
||||
(set_attr "pool_range" "250")])
|
||||
|
||||
; TYPE attribute is used to detect floating point instructions which, if
|
||||
; running on a co-processor can run in parallel with other, basic instructions
|
||||
@@ -3959,7 +3963,7 @@
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "*,load,store2")
|
||||
(set_attr "pool_range" "*,1020,*")
|
||||
(set_attr "neg_pool_range" "*,1012,*")]
|
||||
(set_attr "neg_pool_range" "*,1008,*")]
|
||||
)
|
||||
|
||||
;;; ??? This should have alternatives for constants.
|
||||
@@ -4132,27 +4136,6 @@
|
||||
}"
|
||||
)
|
||||
|
||||
(define_expand "movaddr"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "")
|
||||
(match_operand:DI 1 "address_operand" ""))]
|
||||
"TARGET_ARM"
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn "*movaddr_insn"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(match_operand:DI 1 "address_operand" "p"))]
|
||||
"TARGET_ARM
|
||||
&& reload_completed
|
||||
&& (GET_CODE (operands[1]) == LABEL_REF
|
||||
|| (GET_CODE (operands[1]) == CONST
|
||||
&& GET_CODE (XEXP (operands[1], 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
|
||||
&& GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
|
||||
"adr%?\\t%0, %a1"
|
||||
[(set_attr "predicable" "yes")]
|
||||
)
|
||||
|
||||
;; When generating pic, we need to load the symbol offset into a register.
|
||||
;; So that the optimizer does not confuse this with a normal symbol load
|
||||
;; we use an unspec. The offset will be loaded from a constant pool entry,
|
||||
@@ -5110,8 +5093,8 @@
|
||||
(set_attr "predicable" "yes")
|
||||
(set_attr "type"
|
||||
"load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
|
||||
(set_attr "pool_range" "*,*,*,*,252,*,*,1024,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,*,*,244,*,*,1012,*,*,*")]
|
||||
(set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
|
||||
)
|
||||
|
||||
;; Software floating point version. This is essentially the same as movdi.
|
||||
@@ -5126,8 +5109,8 @@
|
||||
"* return output_move_double (operands);"
|
||||
[(set_attr "length" "8,8,8")
|
||||
(set_attr "type" "*,load,store2")
|
||||
(set_attr "pool_range" "252")
|
||||
(set_attr "neg_pool_range" "244")]
|
||||
(set_attr "pool_range" "1020")
|
||||
(set_attr "neg_pool_range" "1008")]
|
||||
)
|
||||
|
||||
;;; ??? This should have alternatives for constants.
|
||||
@@ -5201,7 +5184,7 @@
|
||||
(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
|
||||
(set_attr "pool_range" "*,*,1024,*,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,1012,*,*,*,*")]
|
||||
(set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
|
||||
)
|
||||
|
||||
|
||||
@@ -6655,7 +6638,8 @@
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB
|
||||
&& operands[2] == const0_rtx && (GET_CODE (operands[0]) == SYMBOL_REF)"
|
||||
&& GET_CODE (operands[0]) == SYMBOL_REF
|
||||
&& !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
|
||||
"bl\\t%a0"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "call")]
|
||||
@@ -6668,7 +6652,8 @@
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB
|
||||
&& operands[3] == const0_rtx && (GET_CODE (operands[1]) == SYMBOL_REF)"
|
||||
&& GET_CODE (operands[1]) == SYMBOL_REF
|
||||
&& !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
|
||||
"bl\\t%a1"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "call")]
|
||||
@@ -8297,6 +8282,7 @@
|
||||
"TARGET_ARM
|
||||
&& !BYTES_BIG_ENDIAN
|
||||
&& !TARGET_MMU_TRAPS
|
||||
&& !arm_arch4
|
||||
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
|
||||
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
|
||||
&& (GET_CODE (operands[2]) != REG
|
||||
@@ -8315,6 +8301,7 @@
|
||||
"TARGET_ARM
|
||||
&& !BYTES_BIG_ENDIAN
|
||||
&& !TARGET_MMU_TRAPS
|
||||
&& !arm_arch4
|
||||
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
|
||||
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
|
||||
&& (GET_CODE (operands[2]) != REG
|
||||
@@ -8479,6 +8466,7 @@
|
||||
"TARGET_ARM
|
||||
&& !BYTES_BIG_ENDIAN
|
||||
&& !TARGET_MMU_TRAPS
|
||||
&& !arm_arch4
|
||||
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
|
||||
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
|
||||
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
|
||||
@@ -8499,6 +8487,7 @@
|
||||
"TARGET_ARM
|
||||
&& !BYTES_BIG_ENDIAN
|
||||
&& !TARGET_MMU_TRAPS
|
||||
&& !arm_arch4
|
||||
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
|
||||
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
|
||||
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
|
||||
@@ -8562,6 +8551,7 @@
|
||||
"TARGET_ARM
|
||||
&& !BYTES_BIG_ENDIAN
|
||||
&& !TARGET_MMU_TRAPS
|
||||
&& !arm_arch4
|
||||
&& REGNO (operands[0]) != REGNO(operands[1])
|
||||
&& (GET_CODE (operands[2]) != REG
|
||||
|| REGNO(operands[0]) != REGNO (operands[2]))"
|
||||
@@ -9136,11 +9126,28 @@
|
||||
|
||||
;; Miscellaneous Thumb patterns
|
||||
|
||||
(define_insn "tablejump"
|
||||
(define_expand "tablejump"
|
||||
[(parallel [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
|
||||
(use (label_ref (match_operand 1 "" "")))])]
|
||||
"TARGET_THUMB"
|
||||
"
|
||||
if (flag_pic)
|
||||
{
|
||||
/* Hopefully, CSE will eliminate this copy. */
|
||||
rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
|
||||
rtx reg2 = gen_reg_rtx (SImode);
|
||||
|
||||
emit_insn (gen_addsi3 (reg2, operands[0], reg1));
|
||||
operands[0] = reg2;
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
(define_insn "*thumb_tablejump"
|
||||
[(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
"TARGET_THUMB"
|
||||
"mov pc, %0"
|
||||
"mov\\t%|pc, %0"
|
||||
[(set_attr "length" "2")]
|
||||
)
|
||||
|
||||
|
||||
@@ -72,7 +72,9 @@ Boston, MA 02111-1307, USA. */
|
||||
/* 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. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
/* We put ARM jump tables in the text section, because it makes the code
|
||||
more efficient, but for Thumb it's better to put them out of band. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
|
||||
|
||||
#undef READONLY_DATA_SECTION
|
||||
#define READONLY_DATA_SECTION rdata_section
|
||||
|
||||
@@ -103,7 +103,9 @@ Boston, MA 02111-1307, USA. */
|
||||
/* 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. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
/* We put ARM jump tables in the text section, because it makes the code
|
||||
more efficient, but for Thumb it's better to put them out of band. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
|
||||
|
||||
#ifndef LINK_SPEC
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} -X"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Definitions for ARM running Linux-based GNU systems using ELF
|
||||
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001
|
||||
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Philip Blundell <philb@gnu.org>
|
||||
|
||||
@@ -42,6 +42,10 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
|
||||
|
||||
/* The GNU C++ standard library requires that these macros be defined. */
|
||||
#undef CPLUSPLUS_CPP_SPEC
|
||||
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
|
||||
|
||||
/* Now we define the strings used to build the spec file. */
|
||||
#define LIB_SPEC \
|
||||
"%{shared: -lc} \
|
||||
@@ -87,7 +91,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-Dunix -Dlinux -D__ELF__ \
|
||||
"-Dunix -D__gnu_linux__ -Dlinux -D__ELF__ \
|
||||
-Asystem=unix -Asystem=posix"
|
||||
|
||||
/* Allow #sccs in preprocessor. */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetBSD/arm (RiscBSD) version.
|
||||
/* NetBSD/arm a.out version.
|
||||
Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
|
||||
Contributed by Mark Brinicombe (amb@physig.ph.kcl.ac.uk)
|
||||
|
||||
@@ -77,15 +77,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_UNSIGNED
|
||||
#define WCHAR_UNSIGNED 0
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
|
||||
/* We don't have any limit on the length as out debugger is GDB. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Definitions for RTEMS based ARM systems using ELF
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@@ -19,15 +19,10 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
#undef TARGET_VERSION
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fputs (" (ARM/ELF RTEMS)", stderr);
|
||||
|
||||
#define HAS_INIT_SECTION
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Darm -Darm_elf -Drtems -D__rtems__ -D__ELF__ \
|
||||
-Asystem(rtems) -Acpu(arm) -Amachine(arm)"
|
||||
|
||||
/*#undef INVOKE_main*/
|
||||
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__rtems__ -D__ELF__ -Asystem=rtems"
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#undef DBL_MAX_10_EXP
|
||||
#define DBL_MAX_10_EXP 308
|
||||
|
||||
#if defined(__sparcv9) || defined(__arch64__)
|
||||
#if defined(__sparcv9) || defined(__arch64__) || defined(__LONG_DOUBLE_128__)
|
||||
|
||||
/* Number of base-FLT_RADIX digits in the significand of a long double */
|
||||
#undef LDBL_MANT_DIG
|
||||
|
||||
@@ -423,6 +423,11 @@ extern void i386_pe_unique_section PARAMS ((TREE, int));
|
||||
#undef ASM_COMMENT_START
|
||||
#define ASM_COMMENT_START " #"
|
||||
|
||||
/* DWARF2 Unwinding doesn't work with exception handling yet. To make it
|
||||
work, we need to build a libgcc_s.dll, and dcrt0.o should be changed to
|
||||
call __register_frame_info/__deregister_frame_info. */
|
||||
#define DWARF2_UNWIND_INFO 0
|
||||
|
||||
/* Don't assume anything about the header files. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Configuration for an i386 running RTEMS on top of MS-DOS with
|
||||
DJGPP v2.x.
|
||||
|
||||
Copyright (C) 1996,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1999, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (joel@OARcorp.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
@@ -21,20 +21,15 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "i386/djgpp.h"
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#ifdef CPP_PREDEFINES
|
||||
#undef CPP_PREDEFINES
|
||||
#endif
|
||||
#define CPP_PREDEFINES "-Dunix -DGO32 -DDJGPP=2 -DMSDOS \
|
||||
#define CPP_PREDEFINES "-Dunix -DGO32 -DDJGPP=2 -DMSDOS -D__rtems__ \
|
||||
-Asystem=unix -Asystem=msdos -Asystem=rtems"
|
||||
|
||||
/* Generate calls to memcpy, memcmp and memset. */
|
||||
#ifndef TARGET_MEM_FUNCTIONS
|
||||
#define TARGET_MEM_FUNCTIONS
|
||||
#endif
|
||||
|
||||
/* end of i386/djgpp-rtems.h */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__ELF__ -DMACH -Asystem=mach \
|
||||
-Dunix -Asystem=unix -Asystem=posix -D__GNU__ -Asystem=gnu"
|
||||
-Dunix -Asystem=unix -Asystem=posix -D__gnu_hurd__ -D__GNU__ -Asystem=gnu"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu) \
|
||||
|
||||
@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */
|
||||
-D_M_IX86=300 -D_X86_=1 \
|
||||
-D__stdcall=__attribute__((__stdcall__)) \
|
||||
-D__cdecl=__attribute__((__cdecl__)) \
|
||||
-D__declspec(x)=__attribute__((x)) \
|
||||
-Asystem=unix -Asystem=interix"
|
||||
|
||||
#undef CPP_SPEC
|
||||
@@ -237,6 +238,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef LD_INIT_SWITCH
|
||||
#undef LD_FINI_SWITCH
|
||||
|
||||
#define EH_FRAME_IN_DATA_SECTION
|
||||
|
||||
/* Note that there appears to be two different ways to support const
|
||||
sections at the moment. You can either #define the symbol
|
||||
@@ -410,10 +412,10 @@ extern void i386_pe_unique_section ();
|
||||
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
|
||||
|
||||
#define SUPPORTS_ONE_ONLY 1
|
||||
#endif /* 0 */
|
||||
|
||||
/* Switch into a generic section. */
|
||||
#define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
|
||||
#endif /* 0 */
|
||||
|
||||
/* DWARF2 Unwinding doesn't work with exception handling yet. */
|
||||
#define DWARF2_UNWIND_INFO 0
|
||||
@@ -421,3 +423,11 @@ extern void i386_pe_unique_section ();
|
||||
/* Don't assume anything about the header files. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
||||
|
||||
/* MSVC returns structs of up to 8 bytes via registers. */
|
||||
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
#undef RETURN_IN_MEMORY
|
||||
#define RETURN_IN_MEMORY(TYPE) \
|
||||
(TYPE_MODE (TYPE) == BLKmode || \
|
||||
(AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes(TYPE) > 8 ))
|
||||
|
||||
@@ -169,6 +169,7 @@ extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
|
||||
extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
|
||||
extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
|
||||
extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code));
|
||||
extern void x86_order_regs_for_local_alloc PARAMS ((void));
|
||||
|
||||
|
||||
#ifdef TREE_CODE
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# In order to work around the very problems that force us to now generally
|
||||
# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
|
||||
# By now choosing the same version tags for these specific routines, we
|
||||
# maintain enough binary compatibility to allow future versions of glibc
|
||||
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
|
||||
|
||||
%ifndef __x86_64__
|
||||
%inherit GCC_3.0 GLIBC_2.0
|
||||
GLIBC_2.0 {
|
||||
# Sampling of DImode arithmetic used by (at least) i386 and m68k.
|
||||
__divdi3
|
||||
__moddi3
|
||||
__udivdi3
|
||||
__umoddi3
|
||||
|
||||
# Exception handling support functions used by most everyone.
|
||||
__register_frame
|
||||
__register_frame_table
|
||||
__deregister_frame
|
||||
__register_frame_info
|
||||
__deregister_frame_info
|
||||
__frame_state_for
|
||||
__register_frame_info_table
|
||||
}
|
||||
%endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Definitions for Intel 386 running Linux-based GNU systems using a.out.
|
||||
Copyright (C) 1992, 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1994, 1995, 1997, 1998, 2002 Free Software Foundation, Inc.
|
||||
Contributed by H.J. Lu (hjl@nynexst.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA. */
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Dlinux -Asystem=posix"
|
||||
#define CPP_PREDEFINES "-Dunix -D__gnu_linux__ -Dlinux -Asystem=posix"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Definitions for Intel 386 running Linux-based GNU systems with pre-BFD
|
||||
a.out linkers.
|
||||
Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1997, 1998, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Michael Meissner (meissner@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Dlinux -Asystem=posix"
|
||||
#define CPP_PREDEFINES "-Dunix -D__gnu_linux__ -Dlinux -Asystem=posix"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
|
||||
|
||||
@@ -85,7 +85,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem=posix"
|
||||
#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -Asystem=posix"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#ifdef USE_GNULIBC_1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
|
||||
|
||||
This file is part of GNU CC.
|
||||
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)");
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem(posix)"
|
||||
#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -Asystem(posix)"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT} %{!m32:-D__LONG_MAX__=9223372036854775807L}"
|
||||
@@ -39,10 +39,96 @@ Boston, MA 02111-1307, USA. */
|
||||
done. */
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} %{shared:-shared} \
|
||||
#define LINK_SPEC "%{!m32:-m elf_x86_64 -Y P,/usr/lib64} %{m32:-m elf_i386} \
|
||||
%{shared:-shared} \
|
||||
%{!shared: \
|
||||
%{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}} \
|
||||
%{static:-static}}"
|
||||
%{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
|
||||
%{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
|
||||
%{static:-static}}"
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{m32:%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
|
||||
%{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \
|
||||
crti.o%s %{static:crtbeginT.o%s}\
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}} \
|
||||
%{!m32:%{!shared: \
|
||||
%{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} \
|
||||
%{!p:%{profile:/usr/lib64/gcrt1.o%s} %{!profile:/usr/lib64/crt1.o%s}}}}\
|
||||
/usr/lib64/crti.o%s %{static:crtbeginT.o%s} \
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}}"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC "\
|
||||
%{m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s} \
|
||||
%{!m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s}"
|
||||
|
||||
#define MULTILIB_DEFAULTS { "m64" }
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#ifdef IN_LIBGCC2
|
||||
#include <signal.h>
|
||||
#include <sys/ucontext.h>
|
||||
#endif
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||
struct sigcontext *sc_; \
|
||||
long new_cfa_; \
|
||||
\
|
||||
/* movq __NR_rt_sigreturn, %rax ; syscall */ \
|
||||
if (*(unsigned char *)(pc_+0) == 0x48 \
|
||||
&& *(unsigned long *)(pc_+1) == 0x050f0000000fc0c7) \
|
||||
{ \
|
||||
struct ucontext *uc_ = (CONTEXT)->cfa; \
|
||||
sc_ = (struct sigcontext *) &uc_->uc_mcontext; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
\
|
||||
new_cfa_ = sc_->rsp; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
/* Register 7 is rsp */ \
|
||||
(FS)->cfa_reg = 7; \
|
||||
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
|
||||
\
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
|
||||
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[0].loc.offset = (long)&sc_->rax - new_cfa_; \
|
||||
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[1].loc.offset = (long)&sc_->rbx - new_cfa_; \
|
||||
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[2].loc.offset = (long)&sc_->rcx - new_cfa_; \
|
||||
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[3].loc.offset = (long)&sc_->rdx - new_cfa_; \
|
||||
(FS)->regs.reg[4].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[4].loc.offset = (long)&sc_->rbp - new_cfa_; \
|
||||
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[5].loc.offset = (long)&sc_->rsi - new_cfa_; \
|
||||
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[6].loc.offset = (long)&sc_->rdi - new_cfa_; \
|
||||
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[8].loc.offset = (long)&sc_->r8 - new_cfa_; \
|
||||
(FS)->regs.reg[9].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[9].loc.offset = (long)&sc_->r9 - new_cfa_; \
|
||||
(FS)->regs.reg[10].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[10].loc.offset = (long)&sc_->r10 - new_cfa_; \
|
||||
(FS)->regs.reg[11].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[11].loc.offset = (long)&sc_->r11 - new_cfa_; \
|
||||
(FS)->regs.reg[12].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[12].loc.offset = (long)&sc_->r12 - new_cfa_; \
|
||||
(FS)->regs.reg[13].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[13].loc.offset = (long)&sc_->r13 - new_cfa_; \
|
||||
(FS)->regs.reg[14].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[14].loc.offset = (long)&sc_->r14 - new_cfa_; \
|
||||
(FS)->regs.reg[15].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[15].loc.offset = (long)&sc_->r15 - new_cfa_; \
|
||||
(FS)->retaddr_column = 16; \
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
||||
|
||||
@@ -51,18 +51,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_UNSIGNED
|
||||
#define WCHAR_UNSIGNED 0
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#undef WINT_TYPE
|
||||
#define WINT_TYPE "int"
|
||||
|
||||
#undef ASM_APP_ON
|
||||
#define ASM_APP_ON "#APP\n"
|
||||
|
||||
|
||||
@@ -22,15 +22,6 @@
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_UNSIGNED
|
||||
#define WCHAR_UNSIGNED 0
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#undef ASM_APP_ON
|
||||
#define ASM_APP_ON "#APP\n"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Definitions for rtems targeting an Intel i386 using coff.
|
||||
Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (joel@OARcorp.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
@@ -19,19 +19,7 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "i386/i386-coff.h"
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Drtems -D__rtems__ -Asystem=rtems"
|
||||
|
||||
/* Generate calls to memcpy, memcmp and memset. */
|
||||
#ifndef TARGET_MEM_FUNCTIONS
|
||||
#define TARGET_MEM_FUNCTIONS
|
||||
#endif
|
||||
|
||||
/* Get machine-independent configuration parameters for RTEMS. */
|
||||
#include <rtems.h>
|
||||
|
||||
/* end of i386/rtems.h */
|
||||
#define CPP_PREDEFINES "-D__rtems__ -Asystem=rtems"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* Definitions for Intel 386 running Linux-based GNU systems with ELF format.
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Eric Youngdale.
|
||||
Modified for stabs-in-ELF by H.J. Lu.
|
||||
/* Definitions for rtems targeting a ix86 using ELF.
|
||||
Copyright (C) 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (joel@OARcorp.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@@ -21,65 +19,13 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define LINUX_DEFAULT_ELF
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (i386 RTEMS with ELF)");
|
||||
#include <i386/i386elf.h>
|
||||
|
||||
/* The svr4 ABI for the i386 says that records and unions are returned
|
||||
in memory. */
|
||||
#undef DEFAULT_PCC_STRUCT_RETURN
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 1
|
||||
|
||||
#undef DBX_REGISTER_NUMBER
|
||||
#define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \
|
||||
LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall mcount\n"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "long int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Drtems -D__rtems__ -Asystem=rtems"
|
||||
#define CPP_PREDEFINES "-D__rtems__ -Asystem=rtems \
|
||||
-D__ELF__ -D__i386__ -D__USE_INIT_FINI__"
|
||||
|
||||
/* A C statement (sans semicolon) to output to the stdio stream
|
||||
FILE the assembler definition of uninitialized global DECL named
|
||||
NAME whose size is SIZE bytes and alignment is ALIGN bytes.
|
||||
Try to use asm_output_aligned_bss to implement this macro. */
|
||||
|
||||
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
|
||||
asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
|
||||
|
||||
/* end of i386/rtemself.h */
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu) %{msoft-float:-D_SOFT_FLOAT}"
|
||||
|
||||
@@ -20,9 +20,6 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "i386/i386.h" /* Base i386 target definitions */
|
||||
#include "i386/att.h" /* Use AT&T i386 assembler syntax */
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (i386, SCO OpenServer 5 Syntax)");
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ Boston, MA 02111-1307, USA. */
|
||||
#define ASM_SPEC \
|
||||
"%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s"
|
||||
|
||||
#define CMOV_SUN_AS_SYNTAX 1
|
||||
|
||||
#else /* GAS_REJECTS_MINUS_S */
|
||||
|
||||
/* Same as above, except for -s, unsupported by GNU as. */
|
||||
@@ -73,10 +75,11 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef WINT_TYPE_SIZE
|
||||
#define WINT_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
/* Add "sun" to the list of symbols defined for SVR4. */
|
||||
#define HANDLE_PRAGMA_REDEFINE_EXTNAME 1
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-Dunix -D__svr4__ -D__SVR4 -Dsun -Asystem=svr4"
|
||||
"-Dunix -D__svr4__ -D__SVR4 -Dsun -D__PRAGMA_REDEFINE_EXTNAME -Asystem=svr4"
|
||||
|
||||
/* Solaris 2/Intel as chokes on #line directives. */
|
||||
#undef CPP_SPEC
|
||||
@@ -154,3 +157,6 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef LOCAL_LABEL_PREFIX
|
||||
#define LOCAL_LABEL_PREFIX "."
|
||||
|
||||
/* The Solaris assembler does not support .quad. Do not use it. */
|
||||
#undef ASM_QUAD
|
||||
|
||||
@@ -4,5 +4,3 @@ LIB1ASMFUNCS = _chkstk
|
||||
interix.o: $(srcdir)/config/i386/interix.c
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/interix.c
|
||||
|
||||
# System headers will track gcc's needs.
|
||||
USER_H=
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
|
||||
# override the settings
|
||||
# from t-slibgcc-elf-ver and t-linux
|
||||
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
|
||||
$(srcdir)/config/i386/libgcc-x86_64-glibc.ver
|
||||
|
||||
MULTILIB_OPTIONS = m64/m32
|
||||
MULTILIB_DIRNAMES = 64 32
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
|
||||
|
||||
SHLIB_SLIBDIR_SUFFIXES = 64:64 32:
|
||||
@@ -12,3 +12,43 @@ crtn.o: $(srcdir)/config/i386/sol2-cn.asm $(GCC_PASSES)
|
||||
sed -e '/^!/d' <$(srcdir)/config/i386/sol2-cn.asm >crtn.s
|
||||
$(GCC_FOR_TARGET) -c -o crtn.o crtn.s
|
||||
|
||||
# We want fine grained libraries, so use the new code to build the
|
||||
# floating point emulation libraries.
|
||||
FPBIT = fp-bit.c
|
||||
DPBIT = dp-bit.c
|
||||
|
||||
LIB2FUNCS_EXTRA = xp-bit.c
|
||||
|
||||
dp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#ifdef __LITTLE_ENDIAN__' > dp-bit.c
|
||||
echo '#define FLOAT_BIT_ORDER_MISMATCH' >>dp-bit.c
|
||||
echo '#endif' >> dp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
|
||||
|
||||
fp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define FLOAT' > fp-bit.c
|
||||
echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
|
||||
echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
|
||||
echo '#endif' >> fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
|
||||
|
||||
xp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define EXTENDED_FLOAT_STUBS' > xp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> xp-bit.c
|
||||
|
||||
MULTILIB_OPTIONS = mcpu=i486/mcpu=pentium/mcpu=pentiumpro/mcpu=k6/mcpu=athlon \
|
||||
msoft-float mno-fp-ret-in-387
|
||||
MULTILIB_DIRNAMES= m486 mpentium mpentiumpro k6 athlon soft-float nofp
|
||||
MULTILIB_MATCHES = msoft-float=mno-m80387
|
||||
MULTILIB_EXCEPTIONS = \
|
||||
mno-fp-ret-in-387 \
|
||||
mcpu=i486/*mno-fp-ret-in-387* \
|
||||
mcpu=pentium/*msoft-float* mcpu=pentium/*mno-fp-ret-in-387* \
|
||||
mcpu=pentiumpro/*msoft-float* mcpu=pentiumpro/*mno-fp-ret-in-387* \
|
||||
mcpu=k6/*msoft-float* mcpu=k6/*mno-fp-ret-in-387* \
|
||||
mcpu=athlon/*msoft-float* mcpu=athlon/*mno-fp-ret-in-387*
|
||||
|
||||
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
@@ -73,7 +73,6 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
This is used to align code labels according to Intel recommendations. */
|
||||
|
||||
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
|
||||
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
|
||||
do { \
|
||||
if ((LOG) != 0) { \
|
||||
@@ -81,7 +80,6 @@ Boston, MA 02111-1307, USA. */
|
||||
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/* i386 System V Release 4 uses DWARF debugging info.
|
||||
|
||||
@@ -86,9 +86,9 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "\
|
||||
-D__ia64 -D__ia64__ -D_AIX -D_AIX64 -D_LONGLONG -Dunix \
|
||||
-D__LP64__ -D__ELF__ -Asystem=unix -Asystem=aix -Acpu=ia64 -Amachine=ia64 \
|
||||
-D__64BIT__ -D_LONG_LONG -D_IA64 -D__int128=__size128_t"
|
||||
-D_AIX -D_AIX64 -D_LONGLONG -Dunix \
|
||||
-Asystem=unix -Asystem=aix \
|
||||
-D__64BIT__ -D_LONG_LONG -D_IA64 -D__int128=__size128_t"
|
||||
|
||||
/* The GNU C++ standard library requires that these macros be defined. */
|
||||
#undef CPLUSPLUS_CPP_SPEC
|
||||
@@ -100,10 +100,6 @@ Boston, MA 02111-1307, USA. */
|
||||
-D__LONG_MAX__=9223372036854775807L \
|
||||
%{cpp_cpu}"
|
||||
|
||||
/* ia64-specific options for gas */
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
|
||||
|
||||
/* Define this for shared library support. */
|
||||
|
||||
#undef LINK_SPEC
|
||||
@@ -115,14 +111,8 @@ Boston, MA 02111-1307, USA. */
|
||||
%{!dynamic-linker:-dynamic-linker /usr/lib/ia64l64/libc.so.1}} \
|
||||
%{static:-static}}"
|
||||
|
||||
#define DONT_USE_BUILTIN_SETJMP
|
||||
#define JMP_BUF_SIZE 85
|
||||
|
||||
/* Output any profiling code before the prologue. */
|
||||
|
||||
#undef PROFILE_BEFORE_PROLOGUE
|
||||
#define PROFILE_BEFORE_PROLOGUE 1
|
||||
|
||||
/* A C statement or compound statement to output to FILE some assembler code to
|
||||
call the profiling subroutine `mcount'.
|
||||
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
|
||||
#if ((TARGET_CPU_DEFAULT | TARGET_DEFAULT) & MASK_GNU_AS) != 0
|
||||
/* GNU AS. */
|
||||
#define ASM_SPEC \
|
||||
"%{mno-gnu-as:-N so} %{!mno-gnu-as:-x} %{mconstant-gp} %{mauto-pic}"
|
||||
#undef ASM_EXTRA_SPEC
|
||||
#define ASM_EXTRA_SPEC \
|
||||
"%{mno-gnu-as:-N so} %{!mno-gnu-as:-x}"
|
||||
#else
|
||||
/* Intel ias. */
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC \
|
||||
"%{!mgnu-as:-N so} %{mgnu-as:-x} %{mconstant-gp:-M const_gp}\
|
||||
%{mauto-pic:-M no_plabel}"
|
||||
|
||||
@@ -19,7 +19,6 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC \
|
||||
"%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
|
||||
%{Wl,*:%*} \
|
||||
@@ -32,9 +31,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
|
||||
%{static:-Bstatic}}"
|
||||
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
|
||||
|
||||
|
||||
/************************[ Target stuff ]***********************************/
|
||||
|
||||
@@ -57,10 +53,4 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define TARGET_ELF 1
|
||||
|
||||
#define DONT_USE_BUILTIN_SETJMP
|
||||
#define JMP_BUF_SIZE 76
|
||||
|
||||
/* Output any profiling code before the prologue. */
|
||||
|
||||
#undef PROFILE_BEFORE_PROLOGUE
|
||||
#define PROFILE_BEFORE_PROLOGUE 1
|
||||
|
||||
@@ -27,9 +27,9 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "\
|
||||
-D__IA64__ -D__ia64 -D__ia64__ -D__hpux -D__hpux__ -Dhpux -Dunix \
|
||||
-D__BIG_ENDIAN__ -D_LONGLONG -D__ELF__ \
|
||||
-Asystem=hpux -Asystem=posix -Asystem=unix -Acpu=ia64 -Amachine=ia64 \
|
||||
-D__IA64__ -D__hpux -D__hpux__ -Dhpux -Dunix \
|
||||
-D__BIG_ENDIAN__ -D_LONGLONG \
|
||||
-Asystem=hpux -Asystem=posix -Asystem=unix \
|
||||
-D_UINT128_T"
|
||||
|
||||
/* -D__fpreg=long double is needed to compensate for the lack of __fpreg
|
||||
@@ -40,15 +40,14 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "\
|
||||
%{mcpu=itanium:-D__itanium__} \
|
||||
%{mlp64:-D__LP64__ -D__LONG_MAX__=9223372036854775807L} \
|
||||
%{mlp64:-D__LP64__ -D_LP64 -D__LONG_MAX__=9223372036854775807L} \
|
||||
%{!ansi:%{!std=c*:%{!std=i*: -D_HPUX_SOURCE -D__STDC_EXT__}}} \
|
||||
-D__fpreg=long\\ double \
|
||||
-D__float80=long\\ double \
|
||||
-D__float128=long\\ double"
|
||||
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic} \
|
||||
%{milp32:-milp32} %{mlp64:-mlp64}"
|
||||
#undef ASM_EXTRA_SPEC
|
||||
#define ASM_EXTRA_SPEC "%{milp32:-milp32} %{mlp64:-mlp64}"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
|
||||
@@ -84,7 +83,6 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define POINTERS_EXTEND_UNSIGNED -1
|
||||
|
||||
#define DONT_USE_BUILTIN_SETJMP
|
||||
#define JMP_BUF_SIZE (8 * 76)
|
||||
|
||||
#undef CONST_SECTION_ASM_OP
|
||||
|
||||
@@ -113,6 +113,9 @@ extern int ia64_function_arg_partial_nregs PARAMS((CUMULATIVE_ARGS *,
|
||||
extern void ia64_function_arg_advance PARAMS((CUMULATIVE_ARGS *,
|
||||
enum machine_mode,
|
||||
tree, int));
|
||||
extern int ia64_function_arg_pass_by_reference PARAMS((CUMULATIVE_ARGS *,
|
||||
enum machine_mode,
|
||||
tree, int));
|
||||
extern int ia64_return_in_memory PARAMS((tree));
|
||||
extern void ia64_asm_output_external PARAMS((FILE *, tree, const char *));
|
||||
|
||||
@@ -122,6 +125,7 @@ extern void ia64_encode_section_info PARAMS((tree));
|
||||
extern int ia64_register_move_cost PARAMS((enum machine_mode, enum reg_class,
|
||||
enum reg_class));
|
||||
extern int ia64_epilogue_uses PARAMS((int));
|
||||
extern int ia64_eh_uses PARAMS((int));
|
||||
extern void emit_safe_across_calls PARAMS((FILE *));
|
||||
extern void ia64_init_builtins PARAMS((void));
|
||||
extern void ia64_override_options PARAMS((void));
|
||||
|
||||
+161
-159
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "system.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "tm_p.h"
|
||||
#include "regs.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "real.h"
|
||||
@@ -46,6 +45,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "timevar.h"
|
||||
#include "target.h"
|
||||
#include "target-def.h"
|
||||
#include "tm_p.h"
|
||||
|
||||
/* This is used for communication between ASM_OUTPUT_LABEL and
|
||||
ASM_OUTPUT_LABELREF. */
|
||||
@@ -138,7 +138,6 @@ static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode, int,
|
||||
static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,
|
||||
tree, rtx));
|
||||
static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx));
|
||||
const struct attribute_spec ia64_attribute_table[];
|
||||
static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));
|
||||
static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
@@ -156,6 +155,14 @@ static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
static rtx ia64_cycle_display PARAMS ((int, rtx));
|
||||
|
||||
|
||||
/* Table of valid machine attributes. */
|
||||
static const struct attribute_spec ia64_attribute_table[] =
|
||||
{
|
||||
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
|
||||
{ "syscall_linkage", 0, 0, false, true, true, NULL },
|
||||
{ NULL, 0, 0, false, false, false, NULL }
|
||||
};
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ATTRIBUTE_TABLE
|
||||
#define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
|
||||
@@ -1137,7 +1144,8 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
rtx nextarg;
|
||||
int sibcall_p;
|
||||
{
|
||||
rtx insn, b0, pfs, gp_save, narg_rtx;
|
||||
rtx insn, b0, pfs, gp_save, narg_rtx, dest;
|
||||
bool indirect_p;
|
||||
int narg;
|
||||
|
||||
addr = XEXP (addr, 0);
|
||||
@@ -1164,61 +1172,36 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
return;
|
||||
}
|
||||
|
||||
if (sibcall_p)
|
||||
indirect_p = ! symbolic_operand (addr, VOIDmode);
|
||||
|
||||
if (sibcall_p || (TARGET_CONST_GP && !indirect_p))
|
||||
gp_save = NULL_RTX;
|
||||
else
|
||||
gp_save = ia64_gp_save_reg (setjmp_operand (addr, VOIDmode));
|
||||
|
||||
if (gp_save)
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
|
||||
/* If this is an indirect call, then we have the address of a descriptor. */
|
||||
if (! symbolic_operand (addr, VOIDmode))
|
||||
if (indirect_p)
|
||||
{
|
||||
rtx dest;
|
||||
|
||||
if (! sibcall_p)
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
|
||||
dest = force_reg (DImode, gen_rtx_MEM (DImode, addr));
|
||||
emit_move_insn (pic_offset_table_rtx,
|
||||
gen_rtx_MEM (DImode, plus_constant (addr, 8)));
|
||||
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_pic (dest, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
|
||||
if (! sibcall_p)
|
||||
emit_move_insn (pic_offset_table_rtx, gp_save);
|
||||
}
|
||||
else if (TARGET_CONST_GP)
|
||||
{
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_nopic (addr, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_nopic (retval, addr, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sibcall_p)
|
||||
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0, pfs));
|
||||
else
|
||||
{
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
dest = addr;
|
||||
|
||||
if (! retval)
|
||||
insn = gen_call_pic (addr, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_pic (retval, addr, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_pic (dest, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
|
||||
emit_move_insn (pic_offset_table_rtx, gp_save);
|
||||
}
|
||||
}
|
||||
if (gp_save)
|
||||
emit_move_insn (pic_offset_table_rtx, gp_save);
|
||||
}
|
||||
|
||||
/* Begin the assembly file. */
|
||||
@@ -2040,7 +2023,7 @@ ia64_expand_prologue ()
|
||||
/* We don't need an alloc instruction if we've used no outputs or locals. */
|
||||
if (current_frame_info.n_local_regs == 0
|
||||
&& current_frame_info.n_output_regs == 0
|
||||
&& current_frame_info.n_input_regs <= current_function_args_info.words)
|
||||
&& current_frame_info.n_input_regs <= current_function_args_info.int_regs)
|
||||
{
|
||||
/* If there is no alloc, but there are input registers used, then we
|
||||
need a .regstk directive. */
|
||||
@@ -2873,7 +2856,7 @@ hfa_element_mode (type, nested)
|
||||
return VOIDmode;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
return TYPE_MODE (TREE_TYPE (type));
|
||||
return hfa_element_mode (TREE_TYPE (type), 1);
|
||||
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
@@ -3181,14 +3164,14 @@ ia64_function_arg_advance (cum, mode, type, named)
|
||||
FR registers, then FP values must also go in general registers. This can
|
||||
happen when we have a SFmode HFA. */
|
||||
else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)
|
||||
return;
|
||||
cum->int_regs = cum->words;
|
||||
|
||||
/* If there is a prototype, then FP values go in a FR register when
|
||||
named, and in a GR registeer when unnamed. */
|
||||
else if (cum->prototype)
|
||||
{
|
||||
if (! named)
|
||||
return;
|
||||
cum->int_regs = cum->words;
|
||||
else
|
||||
/* ??? Complex types should not reach here. */
|
||||
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
|
||||
@@ -3196,10 +3179,24 @@ ia64_function_arg_advance (cum, mode, type, named)
|
||||
/* If there is no prototype, then FP values go in both FR and GR
|
||||
registers. */
|
||||
else
|
||||
/* ??? Complex types should not reach here. */
|
||||
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
|
||||
{
|
||||
/* ??? Complex types should not reach here. */
|
||||
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
|
||||
cum->int_regs = cum->words;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
/* Variable sized types are passed by reference. */
|
||||
/* ??? At present this is a GCC extension to the IA-64 ABI. */
|
||||
|
||||
int
|
||||
ia64_function_arg_pass_by_reference (cum, mode, type, named)
|
||||
CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
tree type;
|
||||
int named ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
|
||||
}
|
||||
|
||||
/* Implement va_start. */
|
||||
@@ -3232,6 +3229,13 @@ ia64_va_arg (valist, type)
|
||||
{
|
||||
tree t;
|
||||
|
||||
/* Variable sized types are passed by reference. */
|
||||
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||
{
|
||||
rtx addr = std_expand_builtin_va_arg (valist, build_pointer_type (type));
|
||||
return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
|
||||
}
|
||||
|
||||
/* Arguments with alignment larger than 8 bytes start at the next even
|
||||
boundary. */
|
||||
if (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
|
||||
@@ -4765,6 +4769,7 @@ group_barrier_needed_p (insn)
|
||||
/* We play dependency tricks with the epilogue in order
|
||||
to get proper schedules. Undo this for dv analysis. */
|
||||
case CODE_FOR_epilogue_deallocate_stack:
|
||||
case CODE_FOR_prologue_allocate_stack:
|
||||
pat = XVECEXP (pat, 0, 0);
|
||||
break;
|
||||
|
||||
@@ -5236,21 +5241,22 @@ ia64_single_set (insn)
|
||||
x = COND_EXEC_CODE (x);
|
||||
if (GET_CODE (x) == SET)
|
||||
return x;
|
||||
ret = single_set_2 (insn, x);
|
||||
if (ret == NULL && GET_CODE (x) == PARALLEL)
|
||||
|
||||
/* Special case here prologue_allocate_stack and epilogue_deallocate_stack.
|
||||
Although they are not classical single set, the second set is there just
|
||||
to protect it from moving past FP-relative stack accesses. */
|
||||
switch (recog_memoized (insn))
|
||||
{
|
||||
/* Special case here prologue_allocate_stack and
|
||||
epilogue_deallocate_stack. Although it is not a classical
|
||||
single set, the second set is there just to protect it
|
||||
from moving past FP-relative stack accesses. */
|
||||
if (XVECLEN (x, 0) == 2
|
||||
&& GET_CODE (XVECEXP (x, 0, 0)) == SET
|
||||
&& GET_CODE (XVECEXP (x, 0, 1)) == SET
|
||||
&& GET_CODE (SET_DEST (XVECEXP (x, 0, 1))) == REG
|
||||
&& SET_DEST (XVECEXP (x, 0, 1)) == SET_SRC (XVECEXP (x, 0, 1))
|
||||
&& ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IALU)
|
||||
ret = XVECEXP (x, 0, 0);
|
||||
case CODE_FOR_prologue_allocate_stack:
|
||||
case CODE_FOR_epilogue_deallocate_stack:
|
||||
ret = XVECEXP (x, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = single_set_2 (insn, x);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -5348,6 +5354,7 @@ ia64_adjust_cost (insn, link, dep_insn, cost)
|
||||
if (reg_overlap_mentioned_p (SET_DEST (set), addr))
|
||||
return cost + 1;
|
||||
}
|
||||
|
||||
if ((dep_class == ITANIUM_CLASS_IALU
|
||||
|| dep_class == ITANIUM_CLASS_ILOG
|
||||
|| dep_class == ITANIUM_CLASS_LD)
|
||||
@@ -5355,25 +5362,28 @@ ia64_adjust_cost (insn, link, dep_insn, cost)
|
||||
|| insn_class == ITANIUM_CLASS_MMSHF
|
||||
|| insn_class == ITANIUM_CLASS_MMSHFI))
|
||||
return 3;
|
||||
|
||||
if (dep_class == ITANIUM_CLASS_FMAC
|
||||
&& (insn_class == ITANIUM_CLASS_FMISC
|
||||
|| insn_class == ITANIUM_CLASS_FCVTFX
|
||||
|| insn_class == ITANIUM_CLASS_XMPY))
|
||||
return 7;
|
||||
|
||||
if ((dep_class == ITANIUM_CLASS_FMAC
|
||||
|| dep_class == ITANIUM_CLASS_FMISC
|
||||
|| dep_class == ITANIUM_CLASS_FCVTFX
|
||||
|| dep_class == ITANIUM_CLASS_XMPY)
|
||||
&& insn_class == ITANIUM_CLASS_STF)
|
||||
return 8;
|
||||
|
||||
/* Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
|
||||
but HP engineers say any non-MM operation. */
|
||||
if ((dep_class == ITANIUM_CLASS_MMMUL
|
||||
|| dep_class == ITANIUM_CLASS_MMSHF
|
||||
|| dep_class == ITANIUM_CLASS_MMSHFI)
|
||||
&& (insn_class == ITANIUM_CLASS_LD
|
||||
|| insn_class == ITANIUM_CLASS_ST
|
||||
|| insn_class == ITANIUM_CLASS_IALU
|
||||
|| insn_class == ITANIUM_CLASS_ILOG
|
||||
|| insn_class == ITANIUM_CLASS_ISHF))
|
||||
&& insn_class != ITANIUM_CLASS_MMMUL
|
||||
&& insn_class != ITANIUM_CLASS_MMSHF
|
||||
&& insn_class != ITANIUM_CLASS_MMSHFI)
|
||||
return 4;
|
||||
|
||||
return cost;
|
||||
@@ -5475,32 +5485,6 @@ ia64_emit_insn_before (insn, before)
|
||||
emit_insn_before (insn, before);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Generate a nop insn of the given type. Note we never generate L type
|
||||
nops. */
|
||||
|
||||
static rtx
|
||||
gen_nop_type (t)
|
||||
enum attr_type t;
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case TYPE_M:
|
||||
return gen_nop_m ();
|
||||
case TYPE_I:
|
||||
return gen_nop_i ();
|
||||
case TYPE_B:
|
||||
return gen_nop_b ();
|
||||
case TYPE_F:
|
||||
return gen_nop_f ();
|
||||
case TYPE_X:
|
||||
return gen_nop_x ();
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* When rotating a bundle out of the issue window, insert a bundle selector
|
||||
insn in front of it. DUMP is the scheduling dump file or NULL. START
|
||||
is either 0 or 3, depending on whether we want to emit a bundle selector
|
||||
@@ -5565,8 +5549,8 @@ cycle_end_fill_slots (dump)
|
||||
if (slot > sched_data.split)
|
||||
abort ();
|
||||
if (dump)
|
||||
fprintf (dump, "// Packet needs %s, have %s\n", type_names[packet->t[slot]],
|
||||
type_names[t]);
|
||||
fprintf (dump, "// Packet needs %s, have %s\n",
|
||||
type_names[packet->t[slot]], type_names[t]);
|
||||
sched_data.types[slot] = packet->t[slot];
|
||||
sched_data.insns[slot] = 0;
|
||||
sched_data.stopbit[slot] = 0;
|
||||
@@ -5578,15 +5562,22 @@ cycle_end_fill_slots (dump)
|
||||
|
||||
slot++;
|
||||
}
|
||||
|
||||
/* Do _not_ use T here. If T == TYPE_A, then we'd risk changing the
|
||||
actual slot type later. */
|
||||
sched_data.types[slot] = packet->t[slot];
|
||||
sched_data.insns[slot] = tmp_insns[i];
|
||||
sched_data.stopbit[slot] = 0;
|
||||
slot++;
|
||||
|
||||
/* TYPE_L instructions always fill up two slots. */
|
||||
if (t == TYPE_L)
|
||||
slot++;
|
||||
{
|
||||
sched_data.types[slot] = packet->t[slot];
|
||||
sched_data.insns[slot] = 0;
|
||||
sched_data.stopbit[slot] = 0;
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
|
||||
/* This isn't right - there's no need to pad out until the forced split;
|
||||
@@ -5629,6 +5620,8 @@ rotate_one_bundle (dump)
|
||||
memmove (sched_data.insns,
|
||||
sched_data.insns + 3,
|
||||
sched_data.cur * sizeof *sched_data.insns);
|
||||
sched_data.packet
|
||||
= &packets[(sched_data.packet->t2 - bundle) * NR_BUNDLES];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6060,6 +6053,7 @@ static void
|
||||
maybe_rotate (dump)
|
||||
FILE *dump;
|
||||
{
|
||||
cycle_end_fill_slots (dump);
|
||||
if (sched_data.cur == 6)
|
||||
rotate_two_bundles (dump);
|
||||
else if (sched_data.cur >= 3)
|
||||
@@ -6074,12 +6068,6 @@ static int prev_cycle;
|
||||
value of sched_data.first_slot. */
|
||||
static int prev_first;
|
||||
|
||||
/* The last insn that has been scheduled. At the start of a new cycle
|
||||
we know that we can emit new insns after it; the main scheduling code
|
||||
has already emitted a cycle_display insn after it and is using that
|
||||
as its current last insn. */
|
||||
static rtx last_issued;
|
||||
|
||||
/* Emit NOPs to fill the delay between PREV_CYCLE and CLOCK_VAR. Used to
|
||||
pad out the delay between MM (shifts, etc.) and integer operations. */
|
||||
|
||||
@@ -6090,12 +6078,13 @@ nop_cycles_until (clock_var, dump)
|
||||
{
|
||||
int prev_clock = prev_cycle;
|
||||
int cycles_left = clock_var - prev_clock;
|
||||
bool did_stop = false;
|
||||
|
||||
/* Finish the previous cycle; pad it out with NOPs. */
|
||||
if (sched_data.cur == 3)
|
||||
{
|
||||
rtx t = gen_insn_group_barrier (GEN_INT (3));
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
|
||||
did_stop = true;
|
||||
maybe_rotate (dump);
|
||||
}
|
||||
else if (sched_data.cur > 0)
|
||||
@@ -6114,12 +6103,9 @@ nop_cycles_until (clock_var, dump)
|
||||
int i;
|
||||
for (i = sched_data.cur; i < split; i++)
|
||||
{
|
||||
rtx t;
|
||||
|
||||
t = gen_nop_type (sched_data.packet->t[i]);
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_data.types[i] = sched_data.packet->t[sched_data.cur];
|
||||
sched_data.insns[i] = last_issued;
|
||||
rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
|
||||
sched_data.types[i] = sched_data.packet->t[i];
|
||||
sched_data.insns[i] = t;
|
||||
sched_data.stopbit[i] = 0;
|
||||
}
|
||||
sched_data.cur = split;
|
||||
@@ -6131,12 +6117,9 @@ nop_cycles_until (clock_var, dump)
|
||||
int i;
|
||||
for (i = sched_data.cur; i < 6; i++)
|
||||
{
|
||||
rtx t;
|
||||
|
||||
t = gen_nop_type (sched_data.packet->t[i]);
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_data.types[i] = sched_data.packet->t[sched_data.cur];
|
||||
sched_data.insns[i] = last_issued;
|
||||
rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
|
||||
sched_data.types[i] = sched_data.packet->t[i];
|
||||
sched_data.insns[i] = t;
|
||||
sched_data.stopbit[i] = 0;
|
||||
}
|
||||
sched_data.cur = 6;
|
||||
@@ -6146,8 +6129,8 @@ nop_cycles_until (clock_var, dump)
|
||||
|
||||
if (need_stop || sched_data.cur == 6)
|
||||
{
|
||||
rtx t = gen_insn_group_barrier (GEN_INT (3));
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
|
||||
did_stop = true;
|
||||
}
|
||||
maybe_rotate (dump);
|
||||
}
|
||||
@@ -6155,24 +6138,22 @@ nop_cycles_until (clock_var, dump)
|
||||
cycles_left--;
|
||||
while (cycles_left > 0)
|
||||
{
|
||||
rtx t = gen_bundle_selector (GEN_INT (0));
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
t = gen_nop_type (TYPE_M);
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
t = gen_nop_type (TYPE_I);
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_emit_insn (gen_bundle_selector (GEN_INT (0)));
|
||||
sched_emit_insn (gen_nop_type (TYPE_M));
|
||||
sched_emit_insn (gen_nop_type (TYPE_I));
|
||||
if (cycles_left > 1)
|
||||
{
|
||||
t = gen_insn_group_barrier (GEN_INT (2));
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_emit_insn (gen_insn_group_barrier (GEN_INT (2)));
|
||||
cycles_left--;
|
||||
}
|
||||
t = gen_nop_type (TYPE_I);
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
t = gen_insn_group_barrier (GEN_INT (3));
|
||||
last_issued = emit_insn_after (t, last_issued);
|
||||
sched_emit_insn (gen_nop_type (TYPE_I));
|
||||
sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
|
||||
did_stop = true;
|
||||
cycles_left--;
|
||||
}
|
||||
|
||||
if (did_stop)
|
||||
init_insn_group_barriers ();
|
||||
}
|
||||
|
||||
/* We are about to being issuing insns for this clock cycle.
|
||||
@@ -6198,31 +6179,34 @@ ia64_internal_sched_reorder (dump, sched_verbose, ready, pn_ready,
|
||||
dump_current_packet (dump);
|
||||
}
|
||||
|
||||
/* Work around the pipeline flush that will occurr if the results of
|
||||
an MM instruction are accessed before the result is ready. Intel
|
||||
documentation says this only happens with IALU, ISHF, ILOG, LD,
|
||||
and ST consumers, but experimental evidence shows that *any* non-MM
|
||||
type instruction will incurr the flush. */
|
||||
if (reorder_type == 0 && clock_var > 0 && ia64_final_schedule)
|
||||
{
|
||||
for (insnp = ready; insnp < e_ready; insnp++)
|
||||
{
|
||||
rtx insn = *insnp;
|
||||
rtx insn = *insnp, link;
|
||||
enum attr_itanium_class t = ia64_safe_itanium_class (insn);
|
||||
if (t == ITANIUM_CLASS_IALU || t == ITANIUM_CLASS_ISHF
|
||||
|| t == ITANIUM_CLASS_ILOG
|
||||
|| t == ITANIUM_CLASS_LD || t == ITANIUM_CLASS_ST)
|
||||
{
|
||||
rtx link;
|
||||
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) != REG_DEP_OUTPUT
|
||||
&& REG_NOTE_KIND (link) != REG_DEP_ANTI)
|
||||
|
||||
if (t == ITANIUM_CLASS_MMMUL
|
||||
|| t == ITANIUM_CLASS_MMSHF
|
||||
|| t == ITANIUM_CLASS_MMSHFI)
|
||||
continue;
|
||||
|
||||
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) == 0)
|
||||
{
|
||||
rtx other = XEXP (link, 0);
|
||||
enum attr_itanium_class t0 = ia64_safe_itanium_class (other);
|
||||
if (t0 == ITANIUM_CLASS_MMSHF || t0 == ITANIUM_CLASS_MMMUL)
|
||||
{
|
||||
rtx other = XEXP (link, 0);
|
||||
enum attr_itanium_class t0 = ia64_safe_itanium_class (other);
|
||||
if (t0 == ITANIUM_CLASS_MMSHF
|
||||
|| t0 == ITANIUM_CLASS_MMMUL)
|
||||
{
|
||||
nop_cycles_until (clock_var, sched_verbose ? dump : NULL);
|
||||
goto out;
|
||||
}
|
||||
nop_cycles_until (clock_var, sched_verbose ? dump : NULL);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
@@ -6486,8 +6470,6 @@ ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
|
||||
{
|
||||
enum attr_type t = ia64_safe_type (insn);
|
||||
|
||||
last_issued = insn;
|
||||
|
||||
if (sched_data.last_was_stop)
|
||||
{
|
||||
int t = sched_data.first_slot;
|
||||
@@ -6833,13 +6815,33 @@ ia64_epilogue_uses (regno)
|
||||
}
|
||||
}
|
||||
|
||||
/* Table of valid machine attributes. */
|
||||
const struct attribute_spec ia64_attribute_table[] =
|
||||
/* Return true if REGNO is used by the frame unwinder. */
|
||||
|
||||
int
|
||||
ia64_eh_uses (regno)
|
||||
int regno;
|
||||
{
|
||||
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
|
||||
{ "syscall_linkage", 0, 0, false, true, true, NULL },
|
||||
{ NULL, 0, 0, false, false, false, NULL }
|
||||
};
|
||||
if (! reload_completed)
|
||||
return 0;
|
||||
|
||||
if (current_frame_info.reg_save_b0
|
||||
&& regno == current_frame_info.reg_save_b0)
|
||||
return 1;
|
||||
if (current_frame_info.reg_save_pr
|
||||
&& regno == current_frame_info.reg_save_pr)
|
||||
return 1;
|
||||
if (current_frame_info.reg_save_ar_pfs
|
||||
&& regno == current_frame_info.reg_save_ar_pfs)
|
||||
return 1;
|
||||
if (current_frame_info.reg_save_ar_unat
|
||||
&& regno == current_frame_info.reg_save_ar_unat)
|
||||
return 1;
|
||||
if (current_frame_info.reg_save_ar_lc
|
||||
&& regno == current_frame_info.reg_save_ar_lc)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For ia64, SYMBOL_REF_FLAG set means that it is a function.
|
||||
|
||||
|
||||
@@ -31,12 +31,19 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Run-time target specifications */
|
||||
|
||||
#define CPP_CPU_SPEC "\
|
||||
-Acpu=ia64 -Amachine=ia64 \
|
||||
%{!ansi:%{!std=c*:%{!std=i*:-Dia64}}} -D__ia64 -D__ia64__"
|
||||
#define EXTRA_SPECS \
|
||||
{ "cpp_cpu", CPP_CPU_SPEC }, \
|
||||
{ "asm_extra", ASM_EXTRA_SPEC },
|
||||
|
||||
#define CPP_CPU_SPEC " \
|
||||
-Acpu=ia64 -Amachine=ia64 -D__ia64 -D__ia64__ %{!milp32:-D_LP64 -D__LP64__} \
|
||||
-D__ELF__"
|
||||
|
||||
#define CC1_SPEC "%(cc1_cpu) "
|
||||
|
||||
#define ASM_EXTRA_SPEC ""
|
||||
|
||||
|
||||
/* This declaration should be present. */
|
||||
extern int target_flags;
|
||||
|
||||
@@ -203,6 +210,7 @@ extern const char *ia64_fixed_range_string;
|
||||
defines in other tm.h files. */
|
||||
#define CPP_SPEC \
|
||||
"%{mcpu=itanium:-D__itanium__} %{mbig-endian:-D__BIG_ENDIAN__} \
|
||||
%(cpp_cpu) \
|
||||
-D__LONG_MAX__=9223372036854775807L"
|
||||
|
||||
/* This is always "long" so it doesn't "change" in ILP32 vs. LP64. */
|
||||
@@ -340,7 +348,7 @@ while (0)
|
||||
/* By default, the C++ compiler will use function addresses in the
|
||||
vtable entries. Setting this non-zero tells the compiler to use
|
||||
function descriptors instead. The value of this macro says how
|
||||
many words wide the descriptor is (normally 2). It is assumed
|
||||
many words wide the descriptor is (normally 2). It is assumed
|
||||
that the address of a function descriptor may be treated as a
|
||||
pointer to a function. */
|
||||
#define TARGET_VTABLE_USES_DESCRIPTORS 2
|
||||
@@ -397,7 +405,7 @@ while (0)
|
||||
|
||||
/* Register Basics */
|
||||
|
||||
/* Number of hardware registers known to the compiler.
|
||||
/* Number of hardware registers known to the compiler.
|
||||
We have 128 general registers, 128 floating point registers,
|
||||
64 predicate registers, 8 branch registers, one frame pointer,
|
||||
and several "application" registers. */
|
||||
@@ -459,7 +467,7 @@ while (0)
|
||||
f0: constant 0.0
|
||||
f1: constant 1.0
|
||||
p0: constant true
|
||||
fp: eliminable frame pointer */
|
||||
fp: eliminable frame pointer */
|
||||
|
||||
/* The last 16 stacked regs are reserved for the 8 input and 8 output
|
||||
registers. */
|
||||
@@ -529,12 +537,12 @@ while (0)
|
||||
1, 1, 1, 1, 1, 0, 1 \
|
||||
}
|
||||
|
||||
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
|
||||
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
|
||||
problem which makes CALL_USED_REGISTERS *always* include
|
||||
all the FIXED_REGISTERS. Until this problem has been
|
||||
all the FIXED_REGISTERS. Until this problem has been
|
||||
resolved this macro can be used to overcome this situation.
|
||||
In particular, block_propagate() requires this list
|
||||
be acurate, or we can remove registers which should be live.
|
||||
In particular, block_propagate() requires this list
|
||||
be acurate, or we can remove registers which should be live.
|
||||
This macro is used in regs_invalidated_by_call. */
|
||||
|
||||
#define CALL_REALLY_USED_REGISTERS \
|
||||
@@ -1151,6 +1159,14 @@ enum reg_class
|
||||
in it. */
|
||||
#define ARG_POINTER_REGNUM R_GR(0)
|
||||
|
||||
/* Due to the way varargs and argument spilling happens, the argument
|
||||
pointer is not 16-byte aligned like the stack pointer. */
|
||||
#define INIT_EXPANDERS \
|
||||
do { \
|
||||
if (cfun && cfun->emit->regno_pointer_align) \
|
||||
REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = 64; \
|
||||
} while (0)
|
||||
|
||||
/* The register number for the return address register. For IA-64, this
|
||||
is not actually a pointer as the name suggests, but that's a name that
|
||||
gen_rtx_REG already takes care to keep unique. We modify
|
||||
@@ -1258,7 +1274,8 @@ enum reg_class
|
||||
pointer is passed in whatever way is appropriate for passing a pointer to
|
||||
that type. */
|
||||
|
||||
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
|
||||
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
|
||||
ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* A C type for declaring a variable that is used as the first argument of
|
||||
`FUNCTION_ARG' and other related values. For some target machines, the type
|
||||
@@ -1267,6 +1284,7 @@ enum reg_class
|
||||
typedef struct ia64_args
|
||||
{
|
||||
int words; /* # words of arguments so far */
|
||||
int int_regs; /* # GR registers used so far */
|
||||
int fp_regs; /* # FR registers used so far */
|
||||
int prototype; /* whether function prototyped */
|
||||
} CUMULATIVE_ARGS;
|
||||
@@ -1277,6 +1295,7 @@ typedef struct ia64_args
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
|
||||
do { \
|
||||
(CUM).words = 0; \
|
||||
(CUM).int_regs = 0; \
|
||||
(CUM).fp_regs = 0; \
|
||||
(CUM).prototype = ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)) || (LIBNAME); \
|
||||
} while (0)
|
||||
@@ -1290,6 +1309,7 @@ do { \
|
||||
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
|
||||
do { \
|
||||
(CUM).words = 0; \
|
||||
(CUM).int_regs = 0; \
|
||||
(CUM).fp_regs = 0; \
|
||||
(CUM).prototype = 1; \
|
||||
} while (0)
|
||||
@@ -1355,7 +1375,7 @@ do { \
|
||||
|
||||
#define FUNCTION_VALUE_REGNO_P(REGNO) \
|
||||
(((REGNO) >= GR_RET_FIRST && (REGNO) <= GR_RET_LAST) \
|
||||
|| ((REGNO) >= FR_RET_FIRST && (REGNO) <= FR_RET_LAST))
|
||||
|| ((REGNO) >= FR_RET_FIRST && (REGNO) <= FR_RET_LAST))
|
||||
|
||||
|
||||
/* How Large Values are Returned */
|
||||
@@ -1404,6 +1424,10 @@ do { \
|
||||
|
||||
#define EPILOGUE_USES(REGNO) ia64_epilogue_uses (REGNO)
|
||||
|
||||
/* Nonzero for registers used by the exception handling mechanism. */
|
||||
|
||||
#define EH_USES(REGNO) ia64_eh_uses (REGNO)
|
||||
|
||||
/* Output at beginning of assembler file. */
|
||||
|
||||
#define ASM_FILE_START(FILE) \
|
||||
@@ -1722,7 +1746,7 @@ do { \
|
||||
|| (CLASS) == GR_AND_FR_REGS ? 4 : 10)
|
||||
|
||||
/* A C expression for the cost of a branch instruction. A value of 1 is the
|
||||
default; other values are interpreted relative to that. Used by the
|
||||
default; other values are interpreted relative to that. Used by the
|
||||
if-conversion code as max instruction count. */
|
||||
/* ??? This requires investigation. The primary effect might be how
|
||||
many additional insn groups we run into, vs how good the dynamic
|
||||
@@ -2273,7 +2297,7 @@ do { \
|
||||
fprintf (FILE, "[.%s%d:]\n", PREFIX, NUM)
|
||||
|
||||
/* Use section-relative relocations for debugging offsets. Unlike other
|
||||
targets that fake this by putting the section VMA at 0, IA-64 has
|
||||
targets that fake this by putting the section VMA at 0, IA-64 has
|
||||
proper relocations for them. */
|
||||
#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL) \
|
||||
do { \
|
||||
@@ -2527,4 +2551,11 @@ enum fetchop_code {
|
||||
IA64_ADD_OP, IA64_SUB_OP, IA64_OR_OP, IA64_AND_OP, IA64_XOR_OP, IA64_NAND_OP
|
||||
};
|
||||
|
||||
#define DONT_USE_BUILTIN_SETJMP
|
||||
|
||||
/* Output any profiling code before the prologue. */
|
||||
|
||||
#undef PROFILE_BEFORE_PROLOGUE
|
||||
#define PROFILE_BEFORE_PROLOGUE 1
|
||||
|
||||
/* End of ia64.h */
|
||||
|
||||
@@ -4848,7 +4848,7 @@
|
||||
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
||||
(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
|
||||
(match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
|
||||
(set (match_operand:DI 3 "register_operand" "=r,r,r")
|
||||
(set (match_operand:DI 3 "register_operand" "+r,r,r")
|
||||
(match_dup 3))]
|
||||
""
|
||||
"@
|
||||
@@ -5045,6 +5045,37 @@
|
||||
[(set_attr "itanium_class" "stop_bit")
|
||||
(set_attr "predicable" "no")])
|
||||
|
||||
(define_expand "trap"
|
||||
[(trap_if (const_int 1) (const_int 0))]
|
||||
""
|
||||
"")
|
||||
|
||||
;; ??? We don't have a match-any slot type. Setting the type to unknown
|
||||
;; produces worse code that setting the slot type to A.
|
||||
|
||||
(define_insn "*trap"
|
||||
[(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
|
||||
""
|
||||
"break %0"
|
||||
[(set_attr "itanium_class" "chk_s")])
|
||||
|
||||
(define_expand "conditional_trap"
|
||||
[(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
|
||||
""
|
||||
{
|
||||
operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
|
||||
})
|
||||
|
||||
(define_insn "*conditional_trap"
|
||||
[(trap_if (match_operator 0 "predicate_operator"
|
||||
[(match_operand:BI 1 "register_operand" "c")
|
||||
(const_int 0)])
|
||||
(match_operand 2 "const_int_operand" ""))]
|
||||
""
|
||||
"(%J0) break %2"
|
||||
[(set_attr "itanium_class" "chk_s")
|
||||
(set_attr "predicable" "no")])
|
||||
|
||||
(define_insn "break_f"
|
||||
[(unspec_volatile [(const_int 0)] 3)]
|
||||
""
|
||||
|
||||
@@ -11,12 +11,8 @@
|
||||
|
||||
/* ??? Maybe this should be in sysv4.h? */
|
||||
#define CPP_PREDEFINES "\
|
||||
-D__ia64 -D__ia64__ -D__linux -D__linux__ -D_LONGLONG -Dlinux -Dunix \
|
||||
-D__LP64__ -D__ELF__ -Asystem=linux -Acpu=ia64 -Amachine=ia64"
|
||||
|
||||
/* ??? ia64 gas doesn't accept standard svr4 assembler options? */
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
|
||||
-D__gnu_linux__ -D__linux -D__linux__ -D_LONGLONG \
|
||||
-Dlinux -Dunix -Asystem=linux"
|
||||
|
||||
/* Need to override linux.h STARTFILE_SPEC, since it has crtbeginT.o in. */
|
||||
#undef STARTFILE_SPEC
|
||||
@@ -46,14 +42,8 @@
|
||||
%{static:-static}}"
|
||||
|
||||
|
||||
#define DONT_USE_BUILTIN_SETJMP
|
||||
#define JMP_BUF_SIZE 76
|
||||
|
||||
/* Output any profiling code before the prologue. */
|
||||
|
||||
#undef PROFILE_BEFORE_PROLOGUE
|
||||
#define PROFILE_BEFORE_PROLOGUE 1
|
||||
|
||||
/* Override linux.h LINK_EH_SPEC definition.
|
||||
Signalize that because we have fde-glibc, we don't need all C shared libs
|
||||
linked against -lgcc_s. */
|
||||
@@ -98,10 +88,16 @@
|
||||
(CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
|
||||
(CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
|
||||
(CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
|
||||
(CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
|
||||
(CONTEXT)->bsp = sc_->sc_ar_bsp; \
|
||||
(CONTEXT)->pr = sc_->sc_pr; \
|
||||
(CONTEXT)->psp = sc_->sc_gr[12]; \
|
||||
(CONTEXT)->gp = sc_->sc_gr[1]; \
|
||||
/* Signal frame doesn't have an associated reg. stack frame \
|
||||
other than what we adjust for below. */ \
|
||||
(FS) -> no_reg_stack_frame = 1; \
|
||||
\
|
||||
/* Don't touch the branch registers. The kernel doesn't \
|
||||
/* Don't touch the branch registers o.t. b0. The kernel doesn't \
|
||||
pass the preserved branch registers in the sigcontext but \
|
||||
leaves them intact, so there's no need to do anything \
|
||||
with them here. */ \
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
#undef ASCII_DATA_ASM_OP
|
||||
#define ASCII_DATA_ASM_OP "\tstring\t"
|
||||
|
||||
/* ia64-specific options for gas
|
||||
??? ia64 gas doesn't accept standard svr4 assembler options? */
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic} %(asm_extra)"
|
||||
|
||||
/* ??? Unfortunately, .lcomm doesn't work, because it puts things in either
|
||||
.bss or .sbss, and we can't control the decision of which is used. When
|
||||
I use .lcomm, I get a cryptic "Section group has no member" error from
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
#include "tsystem.h"
|
||||
#include "unwind.h"
|
||||
#include "unwind-ia64.h"
|
||||
#include "ia64intrin.h"
|
||||
|
||||
/* This isn't thread safe, but nice for occasional tests. */
|
||||
#undef ENABLE_MALLOC_CHECKING
|
||||
|
||||
#ifndef __USING_SJLJ_EXCEPTIONS__
|
||||
#define UNW_VER(x) ((x) >> 48)
|
||||
@@ -121,13 +125,24 @@ struct unw_reg_info
|
||||
int when; /* when the register gets saved */
|
||||
};
|
||||
|
||||
struct unw_reg_state {
|
||||
struct unw_reg_state *next; /* next (outer) element on state stack */
|
||||
struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
|
||||
};
|
||||
|
||||
struct unw_labeled_state {
|
||||
struct unw_labeled_state *next; /* next labeled state (or NULL) */
|
||||
unsigned long label; /* label for this state */
|
||||
struct unw_reg_state saved_state;
|
||||
};
|
||||
|
||||
typedef struct unw_state_record
|
||||
{
|
||||
unsigned int first_region : 1; /* is this the first region? */
|
||||
unsigned int done : 1; /* are we done scanning descriptors? */
|
||||
unsigned int any_spills : 1; /* got any register spills? */
|
||||
unsigned int in_body : 1; /* are we inside a body? */
|
||||
|
||||
unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */
|
||||
unsigned char *imask; /* imask of of spill_mask record or NULL */
|
||||
unsigned long pr_val; /* predicate values */
|
||||
unsigned long pr_mask; /* predicate mask */
|
||||
@@ -141,11 +156,8 @@ typedef struct unw_state_record
|
||||
unsigned char gr_save_loc; /* next general register to use for saving */
|
||||
unsigned char return_link_reg; /* branch register for return link */
|
||||
|
||||
struct unw_reg_state {
|
||||
struct unw_reg_state *next;
|
||||
unsigned long label; /* label of this state record */
|
||||
struct unw_reg_info reg[UNW_NUM_REGS];
|
||||
} curr, *stack, *reg_state_list;
|
||||
struct unw_labeled_state *labeled_states; /* list of all labeled states */
|
||||
struct unw_reg_state curr; /* current state */
|
||||
|
||||
_Unwind_Personality_Fn personality;
|
||||
|
||||
@@ -184,9 +196,12 @@ struct _Unwind_Context
|
||||
void *lsda; /* language specific data area */
|
||||
|
||||
/* Preserved state. */
|
||||
unsigned long *bsp_loc; /* previous bsp save location */
|
||||
unsigned long *bsp_loc; /* previous bsp save location
|
||||
Appears to be write-only? */
|
||||
unsigned long *bspstore_loc;
|
||||
unsigned long *pfs_loc;
|
||||
unsigned long *pfs_loc; /* Save location for pfs in current
|
||||
(corr. to sp) frame. Target
|
||||
contains cfm for caller. */
|
||||
unsigned long *pri_unat_loc;
|
||||
unsigned long *unat_loc;
|
||||
unsigned long *lc_loc;
|
||||
@@ -226,29 +241,197 @@ static unsigned char const save_order[] =
|
||||
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
|
||||
/* Unwind decoder routines */
|
||||
/* MASK is a bitmap describing the allocation state of emergency buffers,
|
||||
with bit set indicating free. Return >= 0 if allocation is successful;
|
||||
< 0 if failure. */
|
||||
|
||||
static inline int
|
||||
atomic_alloc (unsigned int *mask)
|
||||
{
|
||||
unsigned int old = *mask, ret, new;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (old == 0)
|
||||
return -1;
|
||||
ret = old & -old;
|
||||
new = old & ~ret;
|
||||
new = __sync_val_compare_and_swap (mask, old, new);
|
||||
if (old == new)
|
||||
break;
|
||||
old = new;
|
||||
}
|
||||
|
||||
return __builtin_ffs (ret) - 1;
|
||||
}
|
||||
|
||||
/* Similarly, free an emergency buffer. */
|
||||
|
||||
static inline void
|
||||
atomic_free (unsigned int *mask, int bit)
|
||||
{
|
||||
__sync_xor_and_fetch (mask, 1 << bit);
|
||||
}
|
||||
|
||||
|
||||
#define SIZE(X) (sizeof(X) / sizeof(*(X)))
|
||||
#define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
|
||||
#define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
|
||||
|
||||
static struct unw_reg_state emergency_reg_state[32];
|
||||
static int emergency_reg_state_free = MASK_FOR (emergency_reg_state);
|
||||
|
||||
static struct unw_labeled_state emergency_labeled_state[8];
|
||||
static int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state);
|
||||
|
||||
#ifdef ENABLE_MALLOC_CHECKING
|
||||
static int reg_state_alloced;
|
||||
static int labeled_state_alloced;
|
||||
#endif
|
||||
|
||||
/* Allocation and deallocation of structures. */
|
||||
|
||||
static struct unw_reg_state *
|
||||
alloc_reg_state (void)
|
||||
{
|
||||
struct unw_reg_state *rs;
|
||||
|
||||
#ifdef ENABLE_MALLOC_CHECKING
|
||||
reg_state_alloced++;
|
||||
#endif
|
||||
|
||||
rs = malloc (sizeof (struct unw_reg_state));
|
||||
if (!rs)
|
||||
{
|
||||
int n = atomic_alloc (&emergency_reg_state_free);
|
||||
if (n >= 0)
|
||||
rs = &emergency_reg_state[n];
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
static void
|
||||
free_reg_state (struct unw_reg_state *rs)
|
||||
{
|
||||
#ifdef ENABLE_MALLOC_CHECKING
|
||||
reg_state_alloced--;
|
||||
#endif
|
||||
|
||||
if (PTR_IN (emergency_reg_state, rs))
|
||||
atomic_free (&emergency_reg_state_free, rs - emergency_reg_state);
|
||||
else
|
||||
free (rs);
|
||||
}
|
||||
|
||||
static struct unw_labeled_state *
|
||||
alloc_label_state (void)
|
||||
{
|
||||
struct unw_labeled_state *ls;
|
||||
|
||||
#ifdef ENABLE_MALLOC_CHECKING
|
||||
labeled_state_alloced++;
|
||||
#endif
|
||||
|
||||
ls = malloc(sizeof(struct unw_labeled_state));
|
||||
if (!ls)
|
||||
{
|
||||
int n = atomic_alloc (&emergency_labeled_state_free);
|
||||
if (n >= 0)
|
||||
ls = &emergency_labeled_state[n];
|
||||
}
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
static void
|
||||
free_label_state (struct unw_labeled_state *ls)
|
||||
{
|
||||
#ifdef ENABLE_MALLOC_CHECKING
|
||||
labeled_state_alloced--;
|
||||
#endif
|
||||
|
||||
if (PTR_IN (emergency_labeled_state, ls))
|
||||
atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls);
|
||||
else
|
||||
free (ls);
|
||||
}
|
||||
|
||||
/* Routines to manipulate the state stack. */
|
||||
|
||||
static void
|
||||
push (struct unw_state_record *sr)
|
||||
{
|
||||
struct unw_reg_state *rs;
|
||||
|
||||
rs = malloc (sizeof (struct unw_reg_state));
|
||||
struct unw_reg_state *rs = alloc_reg_state ();
|
||||
memcpy (rs, &sr->curr, sizeof (*rs));
|
||||
rs->next = sr->stack;
|
||||
sr->stack = rs;
|
||||
sr->curr.next = rs;
|
||||
}
|
||||
|
||||
static void
|
||||
pop (struct unw_state_record *sr)
|
||||
{
|
||||
struct unw_reg_state *rs;
|
||||
struct unw_reg_state *rs = sr->curr.next;
|
||||
|
||||
rs = sr->stack;
|
||||
sr->stack = rs->next;
|
||||
free (rs);
|
||||
if (!rs)
|
||||
abort ();
|
||||
memcpy (&sr->curr, rs, sizeof(*rs));
|
||||
free_reg_state (rs);
|
||||
}
|
||||
|
||||
/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
|
||||
|
||||
static struct unw_reg_state *
|
||||
dup_state_stack (struct unw_reg_state *rs)
|
||||
{
|
||||
struct unw_reg_state *copy, *prev = NULL, *first = NULL;
|
||||
|
||||
while (rs)
|
||||
{
|
||||
copy = alloc_reg_state ();
|
||||
memcpy (copy, rs, sizeof(*copy));
|
||||
if (first)
|
||||
prev->next = copy;
|
||||
else
|
||||
first = copy;
|
||||
rs = rs->next;
|
||||
prev = copy;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
/* Free all stacked register states (but not RS itself). */
|
||||
static void
|
||||
free_state_stack (struct unw_reg_state *rs)
|
||||
{
|
||||
struct unw_reg_state *p, *next;
|
||||
|
||||
for (p = rs->next; p != NULL; p = next)
|
||||
{
|
||||
next = p->next;
|
||||
free_reg_state (p);
|
||||
}
|
||||
rs->next = NULL;
|
||||
}
|
||||
|
||||
/* Free all labeled states. */
|
||||
|
||||
static void
|
||||
free_label_states (struct unw_labeled_state *ls)
|
||||
{
|
||||
struct unw_labeled_state *next;
|
||||
|
||||
for (; ls ; ls = next)
|
||||
{
|
||||
next = ls->next;
|
||||
|
||||
free_state_stack (&ls->saved_state);
|
||||
free_label_state (ls);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unwind decoder routines */
|
||||
|
||||
static enum unw_register_index __attribute__((const))
|
||||
decode_abreg (unsigned char abreg, int memory)
|
||||
{
|
||||
@@ -295,8 +478,8 @@ alloc_spill_area (unsigned long *offp, unsigned long regsize,
|
||||
if (reg->where == UNW_WHERE_SPILL_HOME)
|
||||
{
|
||||
reg->where = UNW_WHERE_PSPREL;
|
||||
reg->val = 0x10 - *offp;
|
||||
*offp += regsize;
|
||||
*offp -= regsize;
|
||||
reg->val = *offp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,7 +513,7 @@ finish_prologue (struct unw_state_record *sr)
|
||||
/* First, resolve implicit register save locations
|
||||
(see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
|
||||
|
||||
for (i = 0; i < (int) sizeof(save_order); ++i)
|
||||
for (i = 0; i < (int) sizeof (save_order); ++i)
|
||||
{
|
||||
reg = sr->curr.reg + save_order[i];
|
||||
if (reg->where == UNW_WHERE_GR_SAVE)
|
||||
@@ -363,8 +546,8 @@ finish_prologue (struct unw_state_record *sr)
|
||||
mask = *cp++;
|
||||
kind = (mask >> 2*(3-(t & 3))) & 3;
|
||||
if (kind > 0)
|
||||
spill_next_when(®s[kind - 1], sr->curr.reg + limit[kind - 1],
|
||||
sr->region_start + t);
|
||||
spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1],
|
||||
sr->region_start + t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,12 +555,12 @@ finish_prologue (struct unw_state_record *sr)
|
||||
if (sr->any_spills)
|
||||
{
|
||||
off = sr->spill_offset;
|
||||
alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2,
|
||||
sr->curr.reg + UNW_REG_F31);
|
||||
alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_B1,
|
||||
sr->curr.reg + UNW_REG_B5);
|
||||
alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_R4,
|
||||
sr->curr.reg + UNW_REG_R7);
|
||||
alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2,
|
||||
sr->curr.reg + UNW_REG_F31);
|
||||
alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1,
|
||||
sr->curr.reg + UNW_REG_B5);
|
||||
alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4,
|
||||
sr->curr.reg + UNW_REG_R7);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,23 +575,24 @@ desc_prologue (int body, unw_word rlen, unsigned char mask,
|
||||
int i;
|
||||
|
||||
if (!(sr->in_body || sr->first_region))
|
||||
finish_prologue(sr);
|
||||
finish_prologue (sr);
|
||||
sr->first_region = 0;
|
||||
|
||||
/* Check if we're done. */
|
||||
if (body && sr->when_target < sr->region_start + sr->region_len)
|
||||
if (sr->when_target < sr->region_start + sr->region_len)
|
||||
{
|
||||
sr->done = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sr->epilogue_count; ++i)
|
||||
pop(sr);
|
||||
pop (sr);
|
||||
|
||||
sr->epilogue_count = 0;
|
||||
sr->epilogue_start = UNW_WHEN_NEVER;
|
||||
|
||||
if (!body)
|
||||
push(sr);
|
||||
push (sr);
|
||||
|
||||
sr->region_start += sr->region_len;
|
||||
sr->region_len = rlen;
|
||||
@@ -494,7 +678,8 @@ desc_frgr_mem (unsigned char grmask, unw_word frmask,
|
||||
{
|
||||
if ((frmask & 1) != 0)
|
||||
{
|
||||
set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
|
||||
enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4;
|
||||
set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
|
||||
sr->region_start + sr->region_len - 1, 0);
|
||||
sr->any_spills = 1;
|
||||
}
|
||||
@@ -631,13 +816,15 @@ desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
|
||||
static inline void
|
||||
desc_copy_state (unw_word label, struct unw_state_record *sr)
|
||||
{
|
||||
struct unw_reg_state *rs;
|
||||
struct unw_labeled_state *ls;
|
||||
|
||||
for (rs = sr->reg_state_list; rs; rs = rs->next)
|
||||
for (ls = sr->labeled_states; ls; ls = ls->next)
|
||||
{
|
||||
if (rs->label == label)
|
||||
{
|
||||
memcpy (&sr->curr, rs, sizeof(sr->curr));
|
||||
if (ls->label == label)
|
||||
{
|
||||
free_state_stack (&sr->curr);
|
||||
memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr));
|
||||
sr->curr.next = dup_state_stack (ls->saved_state.next);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -647,13 +834,15 @@ desc_copy_state (unw_word label, struct unw_state_record *sr)
|
||||
static inline void
|
||||
desc_label_state (unw_word label, struct unw_state_record *sr)
|
||||
{
|
||||
struct unw_reg_state *rs;
|
||||
struct unw_labeled_state *ls = alloc_label_state ();
|
||||
|
||||
rs = malloc (sizeof (struct unw_reg_state));
|
||||
memcpy (rs, &sr->curr, sizeof (*rs));
|
||||
rs->label = label;
|
||||
rs->next = sr->reg_state_list;
|
||||
sr->reg_state_list = rs;
|
||||
ls->label = label;
|
||||
memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state));
|
||||
ls->saved_state.next = dup_state_stack (sr->curr.next);
|
||||
|
||||
/* Insert into list of labeled states. */
|
||||
ls->next = sr->labeled_states;
|
||||
sr->labeled_states = ls;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1461,8 +1650,11 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
unsigned long *unw, header, length;
|
||||
unsigned char *insn, *insn_end;
|
||||
unsigned long segment_base;
|
||||
struct unw_reg_info *r;
|
||||
|
||||
memset (fs, 0, sizeof (*fs));
|
||||
for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
|
||||
r->when = UNW_WHEN_NEVER;
|
||||
context->lsda = 0;
|
||||
|
||||
ent = _Unwind_FindTableEntry ((void *) context->rp,
|
||||
@@ -1518,6 +1710,14 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
while (!fs->done && insn < insn_end)
|
||||
insn = unw_decode (insn, fs->in_body, fs);
|
||||
|
||||
free_label_states (fs->labeled_states);
|
||||
free_state_stack (&fs->curr);
|
||||
|
||||
#ifdef ENABLE_MALLOC_CHECKING
|
||||
if (reg_state_alloced || labeled_state_alloced)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
/* If we're in the epilogue, sp has been restored and all values
|
||||
on the memory stack below psp also have been restored. */
|
||||
if (fs->when_target > fs->epilogue_start)
|
||||
@@ -1578,7 +1778,7 @@ uw_update_reg_address (struct _Unwind_Context *context,
|
||||
/* Note that while RVAL can only be 1-5 from normal descriptors,
|
||||
we can want to look at B0 due to having manually unwound a
|
||||
signal frame. */
|
||||
if (rval >= 0 && rval <= 5)
|
||||
if (rval <= 5)
|
||||
addr = context->br_loc[rval];
|
||||
else
|
||||
abort ();
|
||||
@@ -1677,8 +1877,7 @@ uw_update_reg_address (struct _Unwind_Context *context,
|
||||
context->psp = *(unsigned long *)addr;
|
||||
break;
|
||||
|
||||
case UNW_REG_RNAT:
|
||||
case UNW_NUM_REGS:
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
@@ -1720,7 +1919,10 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
|
||||
/* Unwind BSP for the local registers allocated this frame. */
|
||||
/* ??? What to do with stored BSP or BSPSTORE registers. */
|
||||
if (fs->when_target > fs->curr.reg[UNW_REG_PFS].when)
|
||||
/* We assert that we are either at a call site, or we have
|
||||
just unwound through a signal frame. In either case
|
||||
pfs_loc is valid. */
|
||||
if (!(fs -> no_reg_stack_frame))
|
||||
{
|
||||
unsigned long pfs = *context->pfs_loc;
|
||||
unsigned long sol = (pfs >> 7) & 0x7f;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# In order to work around the very problems that force us to now generally
|
||||
# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
|
||||
# By now choosing the same version tags for these specific routines, we
|
||||
# maintain enough binary compatibility to allow future versions of glibc
|
||||
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
|
||||
|
||||
%inherit GCC_3.0 GLIBC_2.0
|
||||
GLIBC_2.0 {
|
||||
# Sampling of DImode arithmetic used by (at least) i386 and m68k.
|
||||
__divdi3
|
||||
__moddi3
|
||||
__udivdi3
|
||||
__umoddi3
|
||||
|
||||
# Exception handling support functions used by most everyone.
|
||||
__register_frame
|
||||
__register_frame_table
|
||||
__deregister_frame
|
||||
__register_frame_info
|
||||
__deregister_frame_info
|
||||
__frame_state_for
|
||||
__register_frame_info_table
|
||||
}
|
||||
@@ -109,3 +109,16 @@
|
||||
/* Handle #pragma weak and #pragma pack. */
|
||||
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
|
||||
|
||||
/* Define some types that are the same on all NetBSD platforms,
|
||||
making them agree with <machine/ansi.h>. */
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#undef WINT_TYPE
|
||||
#define WINT_TYPE "int"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for IBM RS/6000 POWER running AIX.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@@ -27,6 +27,9 @@ Boston, MA 02111-1307, USA. */
|
||||
collect has a chance to see them, so scan the object files directly. */
|
||||
#define COLLECT_EXPORT_LIST
|
||||
|
||||
/* Handle #pragma weak and #pragma pack. */
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
|
||||
/* This is the only version of nm that collect2 can work with. */
|
||||
#define REAL_NM_FILE_NAME "/usr/ucb/nm"
|
||||
|
||||
|
||||
@@ -199,10 +199,6 @@ do { \
|
||||
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
|
||||
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
|
||||
|
||||
/* Since there are separate multilibs for pthreads, determine the
|
||||
thread model based on the command-line arguments. */
|
||||
#define THREAD_MODEL_SPEC "%{pthread:posix}%{!pthread:single}"
|
||||
|
||||
/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
|
||||
@@ -202,10 +202,6 @@ do { \
|
||||
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
|
||||
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
|
||||
|
||||
/* Since there are separate multilibs for pthreads, determine the
|
||||
thread model based on the command-line arguments. */
|
||||
#define THREAD_MODEL_SPEC "%{pthread:posix}%{!pthread:single}"
|
||||
|
||||
/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
@@ -213,10 +209,13 @@ do { \
|
||||
|
||||
/* __WCHAR_TYPE__ is dynamic, so do not define it statically. */
|
||||
#define NO_BUILTIN_WCHAR_TYPE
|
||||
#undef WCHAR_TYPE
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
|
||||
/* Type used for wchar_t, as a string used in a declaration. */
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int")
|
||||
|
||||
/* Width of wchar_t in bits. */
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32)
|
||||
#define MAX_WCHAR_TYPE_SIZE 32
|
||||
|
||||
|
||||
+7563
-1166
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Special support for eabi and SVR4
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Written By Michael Meissner
|
||||
* 64-bit support written by David Edelsohn
|
||||
*
|
||||
* This file 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.
|
||||
*
|
||||
* In addition to the permissions in the GNU General Public License, the
|
||||
* Free Software Foundation gives you unlimited permission to link the
|
||||
* compiled version of this file with other programs, and to distribute
|
||||
* those programs without any restriction coming from the use of this
|
||||
* file. (The General Public License restrictions do apply in other
|
||||
* respects; for example, they cover modification of the file, and
|
||||
* distribution when not linked into another program.)
|
||||
*
|
||||
* This file 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 COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* As a special exception, if you link this library with files
|
||||
* compiled with GCC to produce an executable, this does not cause
|
||||
* the resulting executable to be covered by the GNU General Public License.
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*/
|
||||
|
||||
/* Do any initializations needed for the eabi environment */
|
||||
|
||||
.file "crtsavres.asm"
|
||||
.section ".text"
|
||||
#include "ppc-asm.h"
|
||||
|
||||
#ifndef __powerpc64__
|
||||
|
||||
/* Routines for saving floating point registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the floating point save area. */
|
||||
|
||||
FUNC_START(_savefpr_14) stfd 14,-144(11) /* save fp registers */
|
||||
FUNC_START(_savefpr_15) stfd 15,-136(11)
|
||||
FUNC_START(_savefpr_16) stfd 16,-128(11)
|
||||
FUNC_START(_savefpr_17) stfd 17,-120(11)
|
||||
FUNC_START(_savefpr_18) stfd 18,-112(11)
|
||||
FUNC_START(_savefpr_19) stfd 19,-104(11)
|
||||
FUNC_START(_savefpr_20) stfd 20,-96(11)
|
||||
FUNC_START(_savefpr_21) stfd 21,-88(11)
|
||||
FUNC_START(_savefpr_22) stfd 22,-80(11)
|
||||
FUNC_START(_savefpr_23) stfd 23,-72(11)
|
||||
FUNC_START(_savefpr_24) stfd 24,-64(11)
|
||||
FUNC_START(_savefpr_25) stfd 25,-56(11)
|
||||
FUNC_START(_savefpr_26) stfd 26,-48(11)
|
||||
FUNC_START(_savefpr_27) stfd 27,-40(11)
|
||||
FUNC_START(_savefpr_28) stfd 28,-32(11)
|
||||
FUNC_START(_savefpr_29) stfd 29,-24(11)
|
||||
FUNC_START(_savefpr_30) stfd 30,-16(11)
|
||||
FUNC_START(_savefpr_31) stfd 31,-8(11)
|
||||
blr
|
||||
FUNC_END(_savefpr_31)
|
||||
FUNC_END(_savefpr_30)
|
||||
FUNC_END(_savefpr_29)
|
||||
FUNC_END(_savefpr_28)
|
||||
FUNC_END(_savefpr_27)
|
||||
FUNC_END(_savefpr_26)
|
||||
FUNC_END(_savefpr_25)
|
||||
FUNC_END(_savefpr_24)
|
||||
FUNC_END(_savefpr_23)
|
||||
FUNC_END(_savefpr_22)
|
||||
FUNC_END(_savefpr_21)
|
||||
FUNC_END(_savefpr_20)
|
||||
FUNC_END(_savefpr_19)
|
||||
FUNC_END(_savefpr_18)
|
||||
FUNC_END(_savefpr_17)
|
||||
FUNC_END(_savefpr_16)
|
||||
FUNC_END(_savefpr_15)
|
||||
FUNC_END(_savefpr_14)
|
||||
|
||||
/* Routines for saving integer registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the integer save area. */
|
||||
|
||||
FUNC_START(_savegpr_14) stw 14,-72(11) /* save gp registers */
|
||||
FUNC_START(_savegpr_15) stw 15,-68(11)
|
||||
FUNC_START(_savegpr_16) stw 16,-64(11)
|
||||
FUNC_START(_savegpr_17) stw 17,-60(11)
|
||||
FUNC_START(_savegpr_18) stw 18,-56(11)
|
||||
FUNC_START(_savegpr_19) stw 19,-52(11)
|
||||
FUNC_START(_savegpr_20) stw 20,-48(11)
|
||||
FUNC_START(_savegpr_21) stw 21,-44(11)
|
||||
FUNC_START(_savegpr_22) stw 22,-40(11)
|
||||
FUNC_START(_savegpr_23) stw 23,-36(11)
|
||||
FUNC_START(_savegpr_24) stw 24,-32(11)
|
||||
FUNC_START(_savegpr_25) stw 25,-28(11)
|
||||
FUNC_START(_savegpr_26) stw 26,-24(11)
|
||||
FUNC_START(_savegpr_27) stw 27,-20(11)
|
||||
FUNC_START(_savegpr_28) stw 28,-16(11)
|
||||
FUNC_START(_savegpr_29) stw 29,-12(11)
|
||||
FUNC_START(_savegpr_30) stw 30,-8(11)
|
||||
FUNC_START(_savegpr_31) stw 31,-4(11)
|
||||
blr
|
||||
FUNC_END(_savegpr_31)
|
||||
FUNC_END(_savegpr_30)
|
||||
FUNC_END(_savegpr_29)
|
||||
FUNC_END(_savegpr_28)
|
||||
FUNC_END(_savegpr_27)
|
||||
FUNC_END(_savegpr_26)
|
||||
FUNC_END(_savegpr_25)
|
||||
FUNC_END(_savegpr_24)
|
||||
FUNC_END(_savegpr_23)
|
||||
FUNC_END(_savegpr_22)
|
||||
FUNC_END(_savegpr_21)
|
||||
FUNC_END(_savegpr_20)
|
||||
FUNC_END(_savegpr_19)
|
||||
FUNC_END(_savegpr_18)
|
||||
FUNC_END(_savegpr_17)
|
||||
FUNC_END(_savegpr_16)
|
||||
FUNC_END(_savegpr_15)
|
||||
FUNC_END(_savegpr_14)
|
||||
|
||||
/* Routines for restoring floating point registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the floating point save area. */
|
||||
|
||||
FUNC_START(_restfpr_14) lfd 14,-144(11) /* restore fp registers */
|
||||
FUNC_START(_restfpr_15) lfd 15,-136(11)
|
||||
FUNC_START(_restfpr_16) lfd 16,-128(11)
|
||||
FUNC_START(_restfpr_17) lfd 17,-120(11)
|
||||
FUNC_START(_restfpr_18) lfd 18,-112(11)
|
||||
FUNC_START(_restfpr_19) lfd 19,-104(11)
|
||||
FUNC_START(_restfpr_20) lfd 20,-96(11)
|
||||
FUNC_START(_restfpr_21) lfd 21,-88(11)
|
||||
FUNC_START(_restfpr_22) lfd 22,-80(11)
|
||||
FUNC_START(_restfpr_23) lfd 23,-72(11)
|
||||
FUNC_START(_restfpr_24) lfd 24,-64(11)
|
||||
FUNC_START(_restfpr_25) lfd 25,-56(11)
|
||||
FUNC_START(_restfpr_26) lfd 26,-48(11)
|
||||
FUNC_START(_restfpr_27) lfd 27,-40(11)
|
||||
FUNC_START(_restfpr_28) lfd 28,-32(11)
|
||||
FUNC_START(_restfpr_29) lfd 29,-24(11)
|
||||
FUNC_START(_restfpr_30) lfd 30,-16(11)
|
||||
FUNC_START(_restfpr_31) lfd 31,-8(11)
|
||||
blr
|
||||
FUNC_END(_restfpr_31)
|
||||
FUNC_END(_restfpr_30)
|
||||
FUNC_END(_restfpr_29)
|
||||
FUNC_END(_restfpr_28)
|
||||
FUNC_END(_restfpr_27)
|
||||
FUNC_END(_restfpr_26)
|
||||
FUNC_END(_restfpr_25)
|
||||
FUNC_END(_restfpr_24)
|
||||
FUNC_END(_restfpr_23)
|
||||
FUNC_END(_restfpr_22)
|
||||
FUNC_END(_restfpr_21)
|
||||
FUNC_END(_restfpr_20)
|
||||
FUNC_END(_restfpr_19)
|
||||
FUNC_END(_restfpr_18)
|
||||
FUNC_END(_restfpr_17)
|
||||
FUNC_END(_restfpr_16)
|
||||
FUNC_END(_restfpr_15)
|
||||
FUNC_END(_restfpr_14)
|
||||
|
||||
/* Routines for restoring integer registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the integer restore area. */
|
||||
|
||||
FUNC_START(_restgpr_14) lwz 14,-72(11) /* restore gp registers */
|
||||
FUNC_START(_restgpr_15) lwz 15,-68(11)
|
||||
FUNC_START(_restgpr_16) lwz 16,-64(11)
|
||||
FUNC_START(_restgpr_17) lwz 17,-60(11)
|
||||
FUNC_START(_restgpr_18) lwz 18,-56(11)
|
||||
FUNC_START(_restgpr_19) lwz 19,-52(11)
|
||||
FUNC_START(_restgpr_20) lwz 20,-48(11)
|
||||
FUNC_START(_restgpr_21) lwz 21,-44(11)
|
||||
FUNC_START(_restgpr_22) lwz 22,-40(11)
|
||||
FUNC_START(_restgpr_23) lwz 23,-36(11)
|
||||
FUNC_START(_restgpr_24) lwz 24,-32(11)
|
||||
FUNC_START(_restgpr_25) lwz 25,-28(11)
|
||||
FUNC_START(_restgpr_26) lwz 26,-24(11)
|
||||
FUNC_START(_restgpr_27) lwz 27,-20(11)
|
||||
FUNC_START(_restgpr_28) lwz 28,-16(11)
|
||||
FUNC_START(_restgpr_29) lwz 29,-12(11)
|
||||
FUNC_START(_restgpr_30) lwz 30,-8(11)
|
||||
FUNC_START(_restgpr_31) lwz 31,-4(11)
|
||||
blr
|
||||
FUNC_END(_restgpr_31)
|
||||
FUNC_END(_restgpr_30)
|
||||
FUNC_END(_restgpr_29)
|
||||
FUNC_END(_restgpr_28)
|
||||
FUNC_END(_restgpr_27)
|
||||
FUNC_END(_restgpr_26)
|
||||
FUNC_END(_restgpr_25)
|
||||
FUNC_END(_restgpr_24)
|
||||
FUNC_END(_restgpr_23)
|
||||
FUNC_END(_restgpr_22)
|
||||
FUNC_END(_restgpr_21)
|
||||
FUNC_END(_restgpr_20)
|
||||
FUNC_END(_restgpr_19)
|
||||
FUNC_END(_restgpr_18)
|
||||
FUNC_END(_restgpr_17)
|
||||
FUNC_END(_restgpr_16)
|
||||
FUNC_END(_restgpr_15)
|
||||
FUNC_END(_restgpr_14)
|
||||
|
||||
/* Routines for restoring floating point registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the floating point save area. */
|
||||
/* In addition to restoring the fp registers, it will return to the caller's */
|
||||
/* caller */
|
||||
|
||||
FUNC_START(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */
|
||||
FUNC_START(_restfpr_15_x) lfd 15,-136(11)
|
||||
FUNC_START(_restfpr_16_x) lfd 16,-128(11)
|
||||
FUNC_START(_restfpr_17_x) lfd 17,-120(11)
|
||||
FUNC_START(_restfpr_18_x) lfd 18,-112(11)
|
||||
FUNC_START(_restfpr_19_x) lfd 19,-104(11)
|
||||
FUNC_START(_restfpr_20_x) lfd 20,-96(11)
|
||||
FUNC_START(_restfpr_21_x) lfd 21,-88(11)
|
||||
FUNC_START(_restfpr_22_x) lfd 22,-80(11)
|
||||
FUNC_START(_restfpr_23_x) lfd 23,-72(11)
|
||||
FUNC_START(_restfpr_24_x) lfd 24,-64(11)
|
||||
FUNC_START(_restfpr_25_x) lfd 25,-56(11)
|
||||
FUNC_START(_restfpr_26_x) lfd 26,-48(11)
|
||||
FUNC_START(_restfpr_27_x) lfd 27,-40(11)
|
||||
FUNC_START(_restfpr_28_x) lfd 28,-32(11)
|
||||
FUNC_START(_restfpr_29_x) lfd 29,-24(11)
|
||||
FUNC_START(_restfpr_30_x) lfd 30,-16(11)
|
||||
FUNC_START(_restfpr_31_x) lwz 0,4(11)
|
||||
lfd 31,-8(11)
|
||||
mtlr 0
|
||||
mr 1,11
|
||||
blr
|
||||
FUNC_END(_restfpr_31_x)
|
||||
FUNC_END(_restfpr_30_x)
|
||||
FUNC_END(_restfpr_29_x)
|
||||
FUNC_END(_restfpr_28_x)
|
||||
FUNC_END(_restfpr_27_x)
|
||||
FUNC_END(_restfpr_26_x)
|
||||
FUNC_END(_restfpr_25_x)
|
||||
FUNC_END(_restfpr_24_x)
|
||||
FUNC_END(_restfpr_23_x)
|
||||
FUNC_END(_restfpr_22_x)
|
||||
FUNC_END(_restfpr_21_x)
|
||||
FUNC_END(_restfpr_20_x)
|
||||
FUNC_END(_restfpr_19_x)
|
||||
FUNC_END(_restfpr_18_x)
|
||||
FUNC_END(_restfpr_17_x)
|
||||
FUNC_END(_restfpr_16_x)
|
||||
FUNC_END(_restfpr_15_x)
|
||||
FUNC_END(_restfpr_14_x)
|
||||
|
||||
/* Routines for restoring integer registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the integer restore area. */
|
||||
|
||||
FUNC_START(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */
|
||||
FUNC_START(_restgpr_15_x) lwz 15,-68(11)
|
||||
FUNC_START(_restgpr_16_x) lwz 16,-64(11)
|
||||
FUNC_START(_restgpr_17_x) lwz 17,-60(11)
|
||||
FUNC_START(_restgpr_18_x) lwz 18,-56(11)
|
||||
FUNC_START(_restgpr_19_x) lwz 19,-52(11)
|
||||
FUNC_START(_restgpr_20_x) lwz 20,-48(11)
|
||||
FUNC_START(_restgpr_21_x) lwz 21,-44(11)
|
||||
FUNC_START(_restgpr_22_x) lwz 22,-40(11)
|
||||
FUNC_START(_restgpr_23_x) lwz 23,-36(11)
|
||||
FUNC_START(_restgpr_24_x) lwz 24,-32(11)
|
||||
FUNC_START(_restgpr_25_x) lwz 25,-28(11)
|
||||
FUNC_START(_restgpr_26_x) lwz 26,-24(11)
|
||||
FUNC_START(_restgpr_27_x) lwz 27,-20(11)
|
||||
FUNC_START(_restgpr_28_x) lwz 28,-16(11)
|
||||
FUNC_START(_restgpr_29_x) lwz 29,-12(11)
|
||||
FUNC_START(_restgpr_30_x) lwz 30,-8(11)
|
||||
FUNC_START(_restgpr_31_x) lwz 0,4(11)
|
||||
lwz 31,-4(11)
|
||||
mtlr 0
|
||||
mr 1,11
|
||||
blr
|
||||
FUNC_END(_restgpr_31_x)
|
||||
FUNC_END(_restgpr_30_x)
|
||||
FUNC_END(_restgpr_29_x)
|
||||
FUNC_END(_restgpr_28_x)
|
||||
FUNC_END(_restgpr_27_x)
|
||||
FUNC_END(_restgpr_26_x)
|
||||
FUNC_END(_restgpr_25_x)
|
||||
FUNC_END(_restgpr_24_x)
|
||||
FUNC_END(_restgpr_23_x)
|
||||
FUNC_END(_restgpr_22_x)
|
||||
FUNC_END(_restgpr_21_x)
|
||||
FUNC_END(_restgpr_20_x)
|
||||
FUNC_END(_restgpr_19_x)
|
||||
FUNC_END(_restgpr_18_x)
|
||||
FUNC_END(_restgpr_17_x)
|
||||
FUNC_END(_restgpr_16_x)
|
||||
FUNC_END(_restgpr_15_x)
|
||||
FUNC_END(_restgpr_14_x)
|
||||
|
||||
#else /* __powerpc64__ */
|
||||
|
||||
.section ".text"
|
||||
.align 2
|
||||
|
||||
/* Routines for saving floating point registers, called by the compiler. */
|
||||
|
||||
.fsav:
|
||||
FUNC_START(_savef14) stfd 14,-144(1) /* save fp registers */
|
||||
FUNC_START(_savef15) stfd 15,-136(1)
|
||||
FUNC_START(_savef16) stfd 16,-128(1)
|
||||
FUNC_START(_savef17) stfd 17,-120(1)
|
||||
FUNC_START(_savef18) stfd 18,-112(1)
|
||||
FUNC_START(_savef19) stfd 19,-104(1)
|
||||
FUNC_START(_savef20) stfd 20,-96(1)
|
||||
FUNC_START(_savef21) stfd 21,-88(1)
|
||||
FUNC_START(_savef22) stfd 22,-80(1)
|
||||
FUNC_START(_savef23) stfd 23,-72(1)
|
||||
FUNC_START(_savef24) stfd 24,-64(1)
|
||||
FUNC_START(_savef25) stfd 25,-56(1)
|
||||
FUNC_START(_savef26) stfd 26,-48(1)
|
||||
FUNC_START(_savef27) stfd 27,-40(1)
|
||||
FUNC_START(_savef28) stfd 28,-32(1)
|
||||
FUNC_START(_savef29) stfd 29,-24(1)
|
||||
FUNC_START(_savef30) stfd 30,-16(1)
|
||||
FUNC_START(_savef31) stfd 31,-8(1)
|
||||
blr
|
||||
.LTfsav:
|
||||
.long 0
|
||||
.byte 0,12,0,0,0,0,0,0
|
||||
.long 0
|
||||
.long .LTfsav-.fsav
|
||||
.short 4
|
||||
.ascii "fsav"
|
||||
FUNC_END(_savef31)
|
||||
FUNC_END(_savef30)
|
||||
FUNC_END(_savef29)
|
||||
FUNC_END(_savef28)
|
||||
FUNC_END(_savef27)
|
||||
FUNC_END(_savef26)
|
||||
FUNC_END(_savef25)
|
||||
FUNC_END(_savef24)
|
||||
FUNC_END(_savef23)
|
||||
FUNC_END(_savef22)
|
||||
FUNC_END(_savef21)
|
||||
FUNC_END(_savef20)
|
||||
FUNC_END(_savef19)
|
||||
FUNC_END(_savef18)
|
||||
FUNC_END(_savef17)
|
||||
FUNC_END(_savef16)
|
||||
FUNC_END(_savef15)
|
||||
FUNC_END(_savef14)
|
||||
|
||||
/* Routines for restoring floating point registers, called by the compiler. */
|
||||
|
||||
.fres:
|
||||
FUNC_START(_restf14) lfd 14,-144(1) /* restore fp registers */
|
||||
FUNC_START(_restf15) lfd 15,-136(1)
|
||||
FUNC_START(_restf16) lfd 16,-128(1)
|
||||
FUNC_START(_restf17) lfd 17,-120(1)
|
||||
FUNC_START(_restf18) lfd 18,-112(1)
|
||||
FUNC_START(_restf19) lfd 19,-104(1)
|
||||
FUNC_START(_restf20) lfd 20,-96(1)
|
||||
FUNC_START(_restf21) lfd 21,-88(1)
|
||||
FUNC_START(_restf22) lfd 22,-80(1)
|
||||
FUNC_START(_restf23) lfd 23,-72(1)
|
||||
FUNC_START(_restf24) lfd 24,-64(1)
|
||||
FUNC_START(_restf25) lfd 25,-56(1)
|
||||
FUNC_START(_restf26) lfd 26,-48(1)
|
||||
FUNC_START(_restf27) lfd 27,-40(1)
|
||||
FUNC_START(_restf28) lfd 28,-32(1)
|
||||
FUNC_START(_restf29) lfd 29,-24(1)
|
||||
FUNC_START(_restf30) lfd 30,-16(1)
|
||||
FUNC_START(_restf31) lfd 31,-8(1)
|
||||
blr
|
||||
.LTfres:
|
||||
.long 0
|
||||
.byte 0,12,0,0,0,0,0,0
|
||||
.long 0
|
||||
.long .LTfres-.fres
|
||||
.short 4
|
||||
.ascii "fres"
|
||||
FUNC_END(_restf31)
|
||||
FUNC_END(_restf30)
|
||||
FUNC_END(_restf29)
|
||||
FUNC_END(_restf28)
|
||||
FUNC_END(_restf27)
|
||||
FUNC_END(_restf26)
|
||||
FUNC_END(_restf25)
|
||||
FUNC_END(_restf24)
|
||||
FUNC_END(_restf23)
|
||||
FUNC_END(_restf22)
|
||||
FUNC_END(_restf21)
|
||||
FUNC_END(_restf20)
|
||||
FUNC_END(_restf19)
|
||||
FUNC_END(_restf18)
|
||||
FUNC_END(_restf17)
|
||||
FUNC_END(_restf16)
|
||||
FUNC_END(_restf15)
|
||||
FUNC_END(_restf14)
|
||||
|
||||
#endif
|
||||
@@ -35,6 +35,9 @@ Boston, MA 02111-1307, USA. */
|
||||
#define TARGET_TOC 0
|
||||
#define TARGET_NO_TOC 1
|
||||
|
||||
/* Handle #pragma weak and #pragma pack. */
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
|
||||
/* The Darwin ABI always includes AltiVec, can't be (validly) turned
|
||||
off. */
|
||||
|
||||
@@ -57,8 +60,8 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef FRAME_POINTER_REGNUM
|
||||
#define FRAME_POINTER_REGNUM 30
|
||||
|
||||
#undef PIC_OFFSET_TABLE_REGNUM
|
||||
#define PIC_OFFSET_TABLE_REGNUM 31
|
||||
#undef RS6000_PIC_OFFSET_TABLE_REGNUM
|
||||
#define RS6000_PIC_OFFSET_TABLE_REGNUM 31
|
||||
|
||||
/* Pad the outgoing args area to 16 bytes instead of the usual 8. */
|
||||
|
||||
@@ -218,7 +221,10 @@ Boston, MA 02111-1307, USA. */
|
||||
&& TYPE_FIELDS (STRUCT) != 0 \
|
||||
&& DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
|
||||
? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
|
||||
: (TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
|
||||
? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
|
||||
: MAX ((COMPUTED), (SPECIFIED)))
|
||||
|
||||
/* XXX: Darwin supports neither .quad, or .llong, but it also doesn't
|
||||
support 64 bit powerpc either, so this just keeps things happy. */
|
||||
#define DOUBLE_INT_ASM_OP "\t.quad\t"
|
||||
@@ -227,3 +233,7 @@ Boston, MA 02111-1307, USA. */
|
||||
space/speed. */
|
||||
#undef MAX_LONG_TYPE_SIZE
|
||||
#define MAX_LONG_TYPE_SIZE 32
|
||||
|
||||
/* For binary compatibility with 2.95; Darwin C APIs use bool from
|
||||
stdbool.h, which was an int-sized enum in 2.95. */
|
||||
#define BOOL_TYPE_SIZE INT_TYPE_SIZE
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Written By Michael Meissner
|
||||
* 64-bit support written by David Edelsohn
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -297,365 +296,4 @@ FUNC_START(__eabi_uconvert)
|
||||
|
||||
FUNC_END(__eabi_uconvert)
|
||||
|
||||
/* Routines for saving floating point registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the floating point save area. */
|
||||
|
||||
FUNC_START(_savefpr_14) stfd 14,-144(11) /* save fp registers */
|
||||
FUNC_START(_savefpr_15) stfd 15,-136(11)
|
||||
FUNC_START(_savefpr_16) stfd 16,-128(11)
|
||||
FUNC_START(_savefpr_17) stfd 17,-120(11)
|
||||
FUNC_START(_savefpr_18) stfd 18,-112(11)
|
||||
FUNC_START(_savefpr_19) stfd 19,-104(11)
|
||||
FUNC_START(_savefpr_20) stfd 20,-96(11)
|
||||
FUNC_START(_savefpr_21) stfd 21,-88(11)
|
||||
FUNC_START(_savefpr_22) stfd 22,-80(11)
|
||||
FUNC_START(_savefpr_23) stfd 23,-72(11)
|
||||
FUNC_START(_savefpr_24) stfd 24,-64(11)
|
||||
FUNC_START(_savefpr_25) stfd 25,-56(11)
|
||||
FUNC_START(_savefpr_26) stfd 26,-48(11)
|
||||
FUNC_START(_savefpr_27) stfd 27,-40(11)
|
||||
FUNC_START(_savefpr_28) stfd 28,-32(11)
|
||||
FUNC_START(_savefpr_29) stfd 29,-24(11)
|
||||
FUNC_START(_savefpr_30) stfd 30,-16(11)
|
||||
FUNC_START(_savefpr_31) stfd 31,-8(11)
|
||||
blr
|
||||
FUNC_END(_savefpr_31)
|
||||
FUNC_END(_savefpr_30)
|
||||
FUNC_END(_savefpr_29)
|
||||
FUNC_END(_savefpr_28)
|
||||
FUNC_END(_savefpr_27)
|
||||
FUNC_END(_savefpr_26)
|
||||
FUNC_END(_savefpr_25)
|
||||
FUNC_END(_savefpr_24)
|
||||
FUNC_END(_savefpr_23)
|
||||
FUNC_END(_savefpr_22)
|
||||
FUNC_END(_savefpr_21)
|
||||
FUNC_END(_savefpr_20)
|
||||
FUNC_END(_savefpr_19)
|
||||
FUNC_END(_savefpr_18)
|
||||
FUNC_END(_savefpr_17)
|
||||
FUNC_END(_savefpr_16)
|
||||
FUNC_END(_savefpr_15)
|
||||
FUNC_END(_savefpr_14)
|
||||
|
||||
/* Routines for saving integer registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the integer save area. */
|
||||
|
||||
FUNC_START(_savegpr_14) stw 14,-72(11) /* save gp registers */
|
||||
FUNC_START(_savegpr_15) stw 15,-68(11)
|
||||
FUNC_START(_savegpr_16) stw 16,-64(11)
|
||||
FUNC_START(_savegpr_17) stw 17,-60(11)
|
||||
FUNC_START(_savegpr_18) stw 18,-56(11)
|
||||
FUNC_START(_savegpr_19) stw 19,-52(11)
|
||||
FUNC_START(_savegpr_20) stw 20,-48(11)
|
||||
FUNC_START(_savegpr_21) stw 21,-44(11)
|
||||
FUNC_START(_savegpr_22) stw 22,-40(11)
|
||||
FUNC_START(_savegpr_23) stw 23,-36(11)
|
||||
FUNC_START(_savegpr_24) stw 24,-32(11)
|
||||
FUNC_START(_savegpr_25) stw 25,-28(11)
|
||||
FUNC_START(_savegpr_26) stw 26,-24(11)
|
||||
FUNC_START(_savegpr_27) stw 27,-20(11)
|
||||
FUNC_START(_savegpr_28) stw 28,-16(11)
|
||||
FUNC_START(_savegpr_29) stw 29,-12(11)
|
||||
FUNC_START(_savegpr_30) stw 30,-8(11)
|
||||
FUNC_START(_savegpr_31) stw 31,-4(11)
|
||||
blr
|
||||
FUNC_END(_savegpr_31)
|
||||
FUNC_END(_savegpr_30)
|
||||
FUNC_END(_savegpr_29)
|
||||
FUNC_END(_savegpr_28)
|
||||
FUNC_END(_savegpr_27)
|
||||
FUNC_END(_savegpr_26)
|
||||
FUNC_END(_savegpr_25)
|
||||
FUNC_END(_savegpr_24)
|
||||
FUNC_END(_savegpr_23)
|
||||
FUNC_END(_savegpr_22)
|
||||
FUNC_END(_savegpr_21)
|
||||
FUNC_END(_savegpr_20)
|
||||
FUNC_END(_savegpr_19)
|
||||
FUNC_END(_savegpr_18)
|
||||
FUNC_END(_savegpr_17)
|
||||
FUNC_END(_savegpr_16)
|
||||
FUNC_END(_savegpr_15)
|
||||
FUNC_END(_savegpr_14)
|
||||
|
||||
/* Routines for restoring floating point registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the floating point save area. */
|
||||
|
||||
FUNC_START(_restfpr_14) lfd 14,-144(11) /* restore fp registers */
|
||||
FUNC_START(_restfpr_15) lfd 15,-136(11)
|
||||
FUNC_START(_restfpr_16) lfd 16,-128(11)
|
||||
FUNC_START(_restfpr_17) lfd 17,-120(11)
|
||||
FUNC_START(_restfpr_18) lfd 18,-112(11)
|
||||
FUNC_START(_restfpr_19) lfd 19,-104(11)
|
||||
FUNC_START(_restfpr_20) lfd 20,-96(11)
|
||||
FUNC_START(_restfpr_21) lfd 21,-88(11)
|
||||
FUNC_START(_restfpr_22) lfd 22,-80(11)
|
||||
FUNC_START(_restfpr_23) lfd 23,-72(11)
|
||||
FUNC_START(_restfpr_24) lfd 24,-64(11)
|
||||
FUNC_START(_restfpr_25) lfd 25,-56(11)
|
||||
FUNC_START(_restfpr_26) lfd 26,-48(11)
|
||||
FUNC_START(_restfpr_27) lfd 27,-40(11)
|
||||
FUNC_START(_restfpr_28) lfd 28,-32(11)
|
||||
FUNC_START(_restfpr_29) lfd 29,-24(11)
|
||||
FUNC_START(_restfpr_30) lfd 30,-16(11)
|
||||
FUNC_START(_restfpr_31) lfd 31,-8(11)
|
||||
blr
|
||||
FUNC_END(_restfpr_31)
|
||||
FUNC_END(_restfpr_30)
|
||||
FUNC_END(_restfpr_29)
|
||||
FUNC_END(_restfpr_28)
|
||||
FUNC_END(_restfpr_27)
|
||||
FUNC_END(_restfpr_26)
|
||||
FUNC_END(_restfpr_25)
|
||||
FUNC_END(_restfpr_24)
|
||||
FUNC_END(_restfpr_23)
|
||||
FUNC_END(_restfpr_22)
|
||||
FUNC_END(_restfpr_21)
|
||||
FUNC_END(_restfpr_20)
|
||||
FUNC_END(_restfpr_19)
|
||||
FUNC_END(_restfpr_18)
|
||||
FUNC_END(_restfpr_17)
|
||||
FUNC_END(_restfpr_16)
|
||||
FUNC_END(_restfpr_15)
|
||||
FUNC_END(_restfpr_14)
|
||||
|
||||
/* Routines for restoring integer registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the integer restore area. */
|
||||
|
||||
FUNC_START(_restgpr_14) lwz 14,-72(11) /* restore gp registers */
|
||||
FUNC_START(_restgpr_15) lwz 15,-68(11)
|
||||
FUNC_START(_restgpr_16) lwz 16,-64(11)
|
||||
FUNC_START(_restgpr_17) lwz 17,-60(11)
|
||||
FUNC_START(_restgpr_18) lwz 18,-56(11)
|
||||
FUNC_START(_restgpr_19) lwz 19,-52(11)
|
||||
FUNC_START(_restgpr_20) lwz 20,-48(11)
|
||||
FUNC_START(_restgpr_21) lwz 21,-44(11)
|
||||
FUNC_START(_restgpr_22) lwz 22,-40(11)
|
||||
FUNC_START(_restgpr_23) lwz 23,-36(11)
|
||||
FUNC_START(_restgpr_24) lwz 24,-32(11)
|
||||
FUNC_START(_restgpr_25) lwz 25,-28(11)
|
||||
FUNC_START(_restgpr_26) lwz 26,-24(11)
|
||||
FUNC_START(_restgpr_27) lwz 27,-20(11)
|
||||
FUNC_START(_restgpr_28) lwz 28,-16(11)
|
||||
FUNC_START(_restgpr_29) lwz 29,-12(11)
|
||||
FUNC_START(_restgpr_30) lwz 30,-8(11)
|
||||
FUNC_START(_restgpr_31) lwz 31,-4(11)
|
||||
blr
|
||||
FUNC_END(_restgpr_31)
|
||||
FUNC_END(_restgpr_30)
|
||||
FUNC_END(_restgpr_29)
|
||||
FUNC_END(_restgpr_28)
|
||||
FUNC_END(_restgpr_27)
|
||||
FUNC_END(_restgpr_26)
|
||||
FUNC_END(_restgpr_25)
|
||||
FUNC_END(_restgpr_24)
|
||||
FUNC_END(_restgpr_23)
|
||||
FUNC_END(_restgpr_22)
|
||||
FUNC_END(_restgpr_21)
|
||||
FUNC_END(_restgpr_20)
|
||||
FUNC_END(_restgpr_19)
|
||||
FUNC_END(_restgpr_18)
|
||||
FUNC_END(_restgpr_17)
|
||||
FUNC_END(_restgpr_16)
|
||||
FUNC_END(_restgpr_15)
|
||||
FUNC_END(_restgpr_14)
|
||||
|
||||
/* Routines for restoring floating point registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the floating point save area. */
|
||||
/* In addition to restoring the fp registers, it will return to the caller's */
|
||||
/* caller */
|
||||
|
||||
FUNC_START(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */
|
||||
FUNC_START(_restfpr_15_x) lfd 15,-136(11)
|
||||
FUNC_START(_restfpr_16_x) lfd 16,-128(11)
|
||||
FUNC_START(_restfpr_17_x) lfd 17,-120(11)
|
||||
FUNC_START(_restfpr_18_x) lfd 18,-112(11)
|
||||
FUNC_START(_restfpr_19_x) lfd 19,-104(11)
|
||||
FUNC_START(_restfpr_20_x) lfd 20,-96(11)
|
||||
FUNC_START(_restfpr_21_x) lfd 21,-88(11)
|
||||
FUNC_START(_restfpr_22_x) lfd 22,-80(11)
|
||||
FUNC_START(_restfpr_23_x) lfd 23,-72(11)
|
||||
FUNC_START(_restfpr_24_x) lfd 24,-64(11)
|
||||
FUNC_START(_restfpr_25_x) lfd 25,-56(11)
|
||||
FUNC_START(_restfpr_26_x) lfd 26,-48(11)
|
||||
FUNC_START(_restfpr_27_x) lfd 27,-40(11)
|
||||
FUNC_START(_restfpr_28_x) lfd 28,-32(11)
|
||||
FUNC_START(_restfpr_29_x) lfd 29,-24(11)
|
||||
FUNC_START(_restfpr_30_x) lfd 30,-16(11)
|
||||
FUNC_START(_restfpr_31_x) lwz 0,4(11)
|
||||
lfd 31,-8(11)
|
||||
mtlr 0
|
||||
mr 1,11
|
||||
blr
|
||||
FUNC_END(_restfpr_31_x)
|
||||
FUNC_END(_restfpr_30_x)
|
||||
FUNC_END(_restfpr_29_x)
|
||||
FUNC_END(_restfpr_28_x)
|
||||
FUNC_END(_restfpr_27_x)
|
||||
FUNC_END(_restfpr_26_x)
|
||||
FUNC_END(_restfpr_25_x)
|
||||
FUNC_END(_restfpr_24_x)
|
||||
FUNC_END(_restfpr_23_x)
|
||||
FUNC_END(_restfpr_22_x)
|
||||
FUNC_END(_restfpr_21_x)
|
||||
FUNC_END(_restfpr_20_x)
|
||||
FUNC_END(_restfpr_19_x)
|
||||
FUNC_END(_restfpr_18_x)
|
||||
FUNC_END(_restfpr_17_x)
|
||||
FUNC_END(_restfpr_16_x)
|
||||
FUNC_END(_restfpr_15_x)
|
||||
FUNC_END(_restfpr_14_x)
|
||||
|
||||
/* Routines for restoring integer registers, called by the compiler. */
|
||||
/* Called with r11 pointing to the stack header word of the caller of the */
|
||||
/* function, just beyond the end of the integer restore area. */
|
||||
|
||||
FUNC_START(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */
|
||||
FUNC_START(_restgpr_15_x) lwz 15,-68(11)
|
||||
FUNC_START(_restgpr_16_x) lwz 16,-64(11)
|
||||
FUNC_START(_restgpr_17_x) lwz 17,-60(11)
|
||||
FUNC_START(_restgpr_18_x) lwz 18,-56(11)
|
||||
FUNC_START(_restgpr_19_x) lwz 19,-52(11)
|
||||
FUNC_START(_restgpr_20_x) lwz 20,-48(11)
|
||||
FUNC_START(_restgpr_21_x) lwz 21,-44(11)
|
||||
FUNC_START(_restgpr_22_x) lwz 22,-40(11)
|
||||
FUNC_START(_restgpr_23_x) lwz 23,-36(11)
|
||||
FUNC_START(_restgpr_24_x) lwz 24,-32(11)
|
||||
FUNC_START(_restgpr_25_x) lwz 25,-28(11)
|
||||
FUNC_START(_restgpr_26_x) lwz 26,-24(11)
|
||||
FUNC_START(_restgpr_27_x) lwz 27,-20(11)
|
||||
FUNC_START(_restgpr_28_x) lwz 28,-16(11)
|
||||
FUNC_START(_restgpr_29_x) lwz 29,-12(11)
|
||||
FUNC_START(_restgpr_30_x) lwz 30,-8(11)
|
||||
FUNC_START(_restgpr_31_x) lwz 0,4(11)
|
||||
lwz 31,-4(11)
|
||||
mtlr 0
|
||||
mr 1,11
|
||||
blr
|
||||
FUNC_END(_restgpr_31_x)
|
||||
FUNC_END(_restgpr_30_x)
|
||||
FUNC_END(_restgpr_29_x)
|
||||
FUNC_END(_restgpr_28_x)
|
||||
FUNC_END(_restgpr_27_x)
|
||||
FUNC_END(_restgpr_26_x)
|
||||
FUNC_END(_restgpr_25_x)
|
||||
FUNC_END(_restgpr_24_x)
|
||||
FUNC_END(_restgpr_23_x)
|
||||
FUNC_END(_restgpr_22_x)
|
||||
FUNC_END(_restgpr_21_x)
|
||||
FUNC_END(_restgpr_20_x)
|
||||
FUNC_END(_restgpr_19_x)
|
||||
FUNC_END(_restgpr_18_x)
|
||||
FUNC_END(_restgpr_17_x)
|
||||
FUNC_END(_restgpr_16_x)
|
||||
FUNC_END(_restgpr_15_x)
|
||||
FUNC_END(_restgpr_14_x)
|
||||
|
||||
#else /* __powerpc64__ */
|
||||
|
||||
.section ".text"
|
||||
.align 2
|
||||
|
||||
/* Routines for saving floating point registers, called by the compiler. */
|
||||
|
||||
.fsav:
|
||||
FUNC_START(_savef14) stfd 14,-144(1) /* save fp registers */
|
||||
FUNC_START(_savef15) stfd 15,-136(1)
|
||||
FUNC_START(_savef16) stfd 16,-128(1)
|
||||
FUNC_START(_savef17) stfd 17,-120(1)
|
||||
FUNC_START(_savef18) stfd 18,-112(1)
|
||||
FUNC_START(_savef19) stfd 19,-104(1)
|
||||
FUNC_START(_savef20) stfd 20,-96(1)
|
||||
FUNC_START(_savef21) stfd 21,-88(1)
|
||||
FUNC_START(_savef22) stfd 22,-80(1)
|
||||
FUNC_START(_savef23) stfd 23,-72(1)
|
||||
FUNC_START(_savef24) stfd 24,-64(1)
|
||||
FUNC_START(_savef25) stfd 25,-56(1)
|
||||
FUNC_START(_savef26) stfd 26,-48(1)
|
||||
FUNC_START(_savef27) stfd 27,-40(1)
|
||||
FUNC_START(_savef28) stfd 28,-32(1)
|
||||
FUNC_START(_savef29) stfd 29,-24(1)
|
||||
FUNC_START(_savef30) stfd 30,-16(1)
|
||||
FUNC_START(_savef31) stfd 31,-8(1)
|
||||
blr
|
||||
.LTfsav:
|
||||
.long 0
|
||||
.byte 0,12,0,0,0,0,0,0
|
||||
.long 0
|
||||
.long .LTfsav-.fsav
|
||||
.short 4
|
||||
.ascii "fsav"
|
||||
FUNC_END(_savef31)
|
||||
FUNC_END(_savef30)
|
||||
FUNC_END(_savef29)
|
||||
FUNC_END(_savef28)
|
||||
FUNC_END(_savef27)
|
||||
FUNC_END(_savef26)
|
||||
FUNC_END(_savef25)
|
||||
FUNC_END(_savef24)
|
||||
FUNC_END(_savef23)
|
||||
FUNC_END(_savef22)
|
||||
FUNC_END(_savef21)
|
||||
FUNC_END(_savef20)
|
||||
FUNC_END(_savef19)
|
||||
FUNC_END(_savef18)
|
||||
FUNC_END(_savef17)
|
||||
FUNC_END(_savef16)
|
||||
FUNC_END(_savef15)
|
||||
FUNC_END(_savef14)
|
||||
|
||||
/* Routines for restoring floating point registers, called by the compiler. */
|
||||
|
||||
.fres:
|
||||
FUNC_START(_restf14) lfd 14,-144(1) /* restore fp registers */
|
||||
FUNC_START(_restf15) lfd 15,-136(1)
|
||||
FUNC_START(_restf16) lfd 16,-128(1)
|
||||
FUNC_START(_restf17) lfd 17,-120(1)
|
||||
FUNC_START(_restf18) lfd 18,-112(1)
|
||||
FUNC_START(_restf19) lfd 19,-104(1)
|
||||
FUNC_START(_restf20) lfd 20,-96(1)
|
||||
FUNC_START(_restf21) lfd 21,-88(1)
|
||||
FUNC_START(_restf22) lfd 22,-80(1)
|
||||
FUNC_START(_restf23) lfd 23,-72(1)
|
||||
FUNC_START(_restf24) lfd 24,-64(1)
|
||||
FUNC_START(_restf25) lfd 25,-56(1)
|
||||
FUNC_START(_restf26) lfd 26,-48(1)
|
||||
FUNC_START(_restf27) lfd 27,-40(1)
|
||||
FUNC_START(_restf28) lfd 28,-32(1)
|
||||
FUNC_START(_restf29) lfd 29,-24(1)
|
||||
FUNC_START(_restf30) lfd 30,-16(1)
|
||||
FUNC_START(_restf31) lfd 31,-8(1)
|
||||
blr
|
||||
.LTfres:
|
||||
.long 0
|
||||
.byte 0,12,0,0,0,0,0,0
|
||||
.long 0
|
||||
.long .LTfres-.fres
|
||||
.short 4
|
||||
.ascii "fres"
|
||||
FUNC_END(_restf31)
|
||||
FUNC_END(_restf30)
|
||||
FUNC_END(_restf29)
|
||||
FUNC_END(_restf28)
|
||||
FUNC_END(_restf27)
|
||||
FUNC_END(_restf26)
|
||||
FUNC_END(_restf25)
|
||||
FUNC_END(_restf24)
|
||||
FUNC_END(_restf23)
|
||||
FUNC_END(_restf22)
|
||||
FUNC_END(_restf21)
|
||||
FUNC_END(_restf20)
|
||||
FUNC_END(_restf19)
|
||||
FUNC_END(_restf18)
|
||||
FUNC_END(_restf17)
|
||||
FUNC_END(_restf16)
|
||||
FUNC_END(_restf15)
|
||||
FUNC_END(_restf14)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for powerpc machines running GNU.
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC 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.
|
||||
|
||||
GNU CC 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 GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_OS_DEFAULT_SPEC
|
||||
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_gnu)"
|
||||
|
||||
#undef STARTFILE_DEFAULT_SPEC
|
||||
#define STARTFILE_DEFAULT_SPEC "%(startfile_gnu)"
|
||||
|
||||
#undef ENDFILE_DEFAULT_SPEC
|
||||
#define ENDFILE_DEFAULT_SPEC "%(endfile_gnu)"
|
||||
|
||||
#undef LINK_START_DEFAULT_SPEC
|
||||
#define LINK_START_DEFAULT_SPEC "%(link_start_gnu)"
|
||||
|
||||
#undef LINK_OS_DEFAULT_SPEC
|
||||
#define LINK_OS_DEFAULT_SPEC "%(link_os_gnu)"
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU)");
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for 64 bit powerpc linux.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@@ -87,10 +87,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef JUMP_TABLES_IN_TEXT_SECTION
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
|
||||
/* Define cutoff for using external functions to save floating point. */
|
||||
#undef FP_SAVE_INLINE
|
||||
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
|
||||
|
||||
/* 64-bit PowerPC Linux always has GPR13 fixed. */
|
||||
#define FIXED_R13 1
|
||||
|
||||
@@ -142,9 +138,29 @@ Boston, MA 02111-1307, USA. */
|
||||
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
|
||||
|
||||
#undef LINK_OS_LINUX_SPEC
|
||||
#ifndef CROSS_COMPILE
|
||||
#define LINK_OS_LINUX_SPEC "-m elf64ppc %{!shared: %{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
|
||||
%{!dynamic-linker:-dynamic-linker /lib64/ld.so.1}}}"
|
||||
#else
|
||||
#define LINK_OS_LINUX_SPEC "-m elf64ppc %{!shared: %{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker ld.so.1}}}"
|
||||
#endif
|
||||
|
||||
#ifndef CROSS_COMPILE
|
||||
#undef STARTFILE_LINUX_SPEC
|
||||
#define STARTFILE_LINUX_SPEC "\
|
||||
%{!shared: %{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} \
|
||||
%{!p:/usr/lib64/crt1.o%s}}} /usr/lib64/crti.o%s \
|
||||
%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
#endif
|
||||
|
||||
#ifndef CROSS_COMPILE
|
||||
#undef ENDFILE_LINUX_SPEC
|
||||
#define ENDFILE_LINUX_SPEC "\
|
||||
%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s"
|
||||
#endif
|
||||
|
||||
#undef TOC_SECTION_ASM_OP
|
||||
#define TOC_SECTION_ASM_OP "\t.section\t\".toc\",\"aw\""
|
||||
@@ -208,17 +224,6 @@ Boston, MA 02111-1307, USA. */
|
||||
&& ! DECL_WEAK (DECL)) \
|
||||
SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
|
||||
|
||||
/* This macro gets just the user-specified name
|
||||
out of the string in a SYMBOL_REF. Discard
|
||||
a leading * or @. */
|
||||
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
|
||||
do { \
|
||||
const char *_name = (SYMBOL_NAME); \
|
||||
while (*_name == '*' || *_name == '@') \
|
||||
_name++; \
|
||||
(VAR) = _name; \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME.
|
||||
`assemble_name' uses this. */
|
||||
|
||||
@@ -245,32 +250,39 @@ do { \
|
||||
fputs (DOUBLE_INT_ASM_OP, (FILE)); \
|
||||
putc ('.', (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
putc ('\n', (FILE)); \
|
||||
fputs (DOUBLE_INT_ASM_OP, (FILE)); \
|
||||
fputs (".TOC.@tocbase, 0\n\t.previous\n", (FILE)); \
|
||||
\
|
||||
if (TREE_PUBLIC (DECL)) \
|
||||
fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
fputs (",24\n\t.type\t.", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
fputs (",@function\n", (FILE)); \
|
||||
if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL)) \
|
||||
{ \
|
||||
if (DECL_WEAK (DECL)) \
|
||||
fputs ("\t.weak\t", (FILE)); \
|
||||
else \
|
||||
fputs ("\t.globl\t", (FILE)); \
|
||||
putc ('.', (FILE)); \
|
||||
fputs ("\t.globl\t.", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
putc ('\n', (FILE)); \
|
||||
} \
|
||||
fputs (TYPE_ASM_OP, (FILE)); \
|
||||
putc ('.', (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
putc (',', (FILE)); \
|
||||
fprintf ((FILE), TYPE_OPERAND_FMT, "function"); \
|
||||
putc ('\n', (FILE)); \
|
||||
ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL)); \
|
||||
putc ('.', (FILE)); \
|
||||
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* This is how to declare the size of a function. */
|
||||
#undef ASM_DECLARE_FUNCTION_SIZE
|
||||
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
if (!flag_inhibit_size_directive) \
|
||||
{ \
|
||||
fputs ("\t.size\t.", (FILE)); \
|
||||
assemble_name ((FILE), (FNAME)); \
|
||||
fputs (",.-.", (FILE)); \
|
||||
assemble_name ((FILE), (FNAME)); \
|
||||
putc ('\n', (FILE)); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Return non-zero if this entry is to be written into the constant
|
||||
pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF
|
||||
or a CONST containing one of them. If -mfp-in-toc (the default),
|
||||
|
||||
@@ -64,3 +64,8 @@ Boston, MA 02111-1307, USA. */
|
||||
structure return convention. */
|
||||
#undef DRAFT_V4_STRUCT_RET
|
||||
#define DRAFT_V4_STRUCT_RET 1
|
||||
|
||||
/* Use STABS debugging information by default. DWARF2 makes a mess of
|
||||
the 1.5.2 linker. */
|
||||
#undef PREFERRED_DEBUGGING_TYPE
|
||||
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
|
||||
|
||||
@@ -161,6 +161,7 @@ GLUE(.L,name): \
|
||||
|
||||
#elif defined (__powerpc64__)
|
||||
#define FUNC_NAME(name) GLUE(.,name)
|
||||
#define JUMP_TARGET(name) FUNC_NAME(name)
|
||||
#define FUNC_START(name) \
|
||||
.section ".opd","aw"; \
|
||||
name: \
|
||||
|
||||
@@ -40,6 +40,7 @@ extern int cc_reg_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int cc_reg_not_cr0_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_short_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_neg_short_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_aligned_short_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_arith_cint_operand PARAMS ((rtx, enum machine_mode));
|
||||
@@ -51,6 +52,7 @@ extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
|
||||
extern int easy_fp_constant PARAMS ((rtx, enum machine_mode));
|
||||
extern int zero_fp_constant PARAMS ((rtx, enum machine_mode));
|
||||
extern int zero_constant PARAMS ((rtx, enum machine_mode));
|
||||
extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode));
|
||||
|
||||
+551
-167
File diff suppressed because it is too large
Load Diff
@@ -191,7 +191,7 @@ extern int target_flags;
|
||||
function, and one less allocable register. */
|
||||
#define MASK_MINIMAL_TOC 0x00000200
|
||||
|
||||
/* Nonzero for the 64bit model: ints, longs, and pointers are 64 bits. */
|
||||
/* Nonzero for the 64bit model: longs and pointers are 64 bits. */
|
||||
#define MASK_64BIT 0x00000400
|
||||
|
||||
/* Disable use of FPRs. */
|
||||
@@ -604,6 +604,9 @@ extern int rs6000_altivec_abi;
|
||||
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
|
||||
#endif
|
||||
|
||||
/* Work around rs6000_long_double_type_size dependency in ada/targtyps.c. */
|
||||
#define WIDEST_HARDWARE_FP_SIZE 64
|
||||
|
||||
/* Width in bits of a pointer.
|
||||
See also the macro `Pmode' defined below. */
|
||||
#define POINTER_SIZE (TARGET_32BIT ? 32 : 64)
|
||||
@@ -626,9 +629,6 @@ extern int rs6000_altivec_abi;
|
||||
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
|
||||
((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : ALIGN)
|
||||
|
||||
/* Handle #pragma pack. */
|
||||
#define HANDLE_PRAGMA_PACK 1
|
||||
|
||||
/* Alignment of field after `int : 0' in a structure. */
|
||||
#define EMPTY_FIELD_BOUNDARY 32
|
||||
|
||||
@@ -638,10 +638,13 @@ extern int rs6000_altivec_abi;
|
||||
/* A bitfield declared as `int' forces `int' alignment for the struct. */
|
||||
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||
|
||||
/* Make strings word-aligned so strcpy from constants will be faster. */
|
||||
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
|
||||
(TREE_CODE (EXP) == STRING_CST \
|
||||
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
|
||||
/* Make strings word-aligned so strcpy from constants will be faster.
|
||||
Make vector constants quadword aligned. */
|
||||
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
|
||||
(TREE_CODE (EXP) == STRING_CST \
|
||||
&& (ALIGN) < BITS_PER_WORD \
|
||||
? BITS_PER_WORD \
|
||||
: (ALIGN))
|
||||
|
||||
/* Make arrays of chars word-aligned for the same reasons.
|
||||
Align vectors to 128 bits. */
|
||||
@@ -759,7 +762,7 @@ extern int rs6000_altivec_abi;
|
||||
#define XER_REGNO 76
|
||||
#define FIRST_ALTIVEC_REGNO 77
|
||||
#define LAST_ALTIVEC_REGNO 108
|
||||
#define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO)
|
||||
#define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1)
|
||||
#define VRSAVE_REGNO 109
|
||||
|
||||
/* List the order in which to allocate registers. Each register must be
|
||||
@@ -957,18 +960,24 @@ extern int rs6000_altivec_abi;
|
||||
for (i = 32; i < 64; i++) \
|
||||
fixed_regs[i] = call_used_regs[i] \
|
||||
= call_really_used_regs[i] = 1; \
|
||||
if (DEFAULT_ABI == ABI_V4 && flag_pic == 1) \
|
||||
fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_really_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
if (DEFAULT_ABI == ABI_DARWIN && flag_pic) \
|
||||
global_regs[PIC_OFFSET_TABLE_REGNUM] \
|
||||
= fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_really_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
if (DEFAULT_ABI == ABI_V4 \
|
||||
&& PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM \
|
||||
&& flag_pic == 1) \
|
||||
fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
if (DEFAULT_ABI == ABI_DARWIN \
|
||||
&& PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
|
||||
global_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
if (! TARGET_ALTIVEC) \
|
||||
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) \
|
||||
fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; \
|
||||
{ \
|
||||
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) \
|
||||
fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; \
|
||||
call_really_used_regs[VRSAVE_REGNO] = 1; \
|
||||
} \
|
||||
if (TARGET_ALTIVEC_ABI) \
|
||||
for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) \
|
||||
call_used_regs[i] = call_really_used_regs[i] = 1; \
|
||||
@@ -1199,14 +1208,14 @@ enum reg_class
|
||||
'Q' means that is a memory operand that is just an offset from a reg.
|
||||
'R' is for AIX TOC entries.
|
||||
'S' is a constant that can be placed into a 64-bit mask operand
|
||||
'T' is a consatnt that can be placed into a 32-bit mask operand
|
||||
'T' is a constant that can be placed into a 32-bit mask operand
|
||||
'U' is for V.4 small data references. */
|
||||
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
|
||||
: (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \
|
||||
: (C) == 'S' ? mask64_operand (OP, VOIDmode) \
|
||||
: (C) == 'T' ? mask_operand (OP, VOIDmode) \
|
||||
: (C) == 'S' ? mask64_operand (OP, DImode) \
|
||||
: (C) == 'T' ? mask_operand (OP, SImode) \
|
||||
: (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \
|
||||
&& small_data_operand (OP, GET_MODE (OP))) \
|
||||
: 0)
|
||||
@@ -1539,7 +1548,7 @@ typedef struct rs6000_stack {
|
||||
On RS/6000, these are r3-r10 and fp1-fp13.
|
||||
On AltiVec, v2 - v13 are used for passing vectors. */
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \
|
||||
(((unsigned)((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \
|
||||
|| (TARGET_ALTIVEC && \
|
||||
(unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_NUM_REG)) \
|
||||
|| ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
|
||||
@@ -1591,8 +1600,7 @@ typedef struct rs6000_args
|
||||
#define RS6000_ARG_SIZE(MODE, TYPE) \
|
||||
((MODE) != BLKmode \
|
||||
? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
|
||||
: ((unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) \
|
||||
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
|
||||
: (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
@@ -1711,6 +1719,14 @@ typedef struct rs6000_args
|
||||
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
|
||||
rs6000_va_arg (valist, type)
|
||||
|
||||
/* For AIX, the rule is that structures are passed left-aligned in
|
||||
their stack slot. However, GCC does not presently do this:
|
||||
structures which are the same size as integer types are passed
|
||||
right-aligned, as if they were in fact integers. This only
|
||||
matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
|
||||
ABI_V4 does not use std_expand_builtin_va_arg. */
|
||||
#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
|
||||
|
||||
/* Define this macro to be a nonzero value if the location where a function
|
||||
argument is passed depends on whether or not it is a named argument. */
|
||||
#define STRICT_ARGUMENT_NAMING 1
|
||||
@@ -1736,7 +1752,7 @@ typedef struct rs6000_args
|
||||
|
||||
#define EPILOGUE_USES(REGNO) \
|
||||
((reload_completed && (REGNO) == LINK_REGISTER_REGNUM) \
|
||||
|| (REGNO) == VRSAVE_REGNO \
|
||||
|| (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO) \
|
||||
|| (current_function_calls_eh_return \
|
||||
&& TARGET_AIX \
|
||||
&& (REGNO) == TOC_REGISTER))
|
||||
@@ -1968,7 +1984,8 @@ typedef struct rs6000_args
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
|
||||
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
|
||||
&& (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0) \
|
||||
&& (! ALTIVEC_VECTOR_MODE (MODE) \
|
||||
|| (GET_CODE (XEXP (X,1)) == CONST_INT && INTVAL (XEXP (X,1)) == 0)) \
|
||||
&& (((MODE) != DFmode && (MODE) != DImode) \
|
||||
|| (TARGET_32BIT \
|
||||
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
|
||||
@@ -2086,7 +2103,8 @@ do { \
|
||||
this macro is not defined, it is up to the machine-dependent files
|
||||
to allocate such a register (if necessary). */
|
||||
|
||||
#define PIC_OFFSET_TABLE_REGNUM 30
|
||||
#define RS6000_PIC_OFFSET_TABLE_REGNUM 30
|
||||
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
|
||||
|
||||
#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
|
||||
|
||||
@@ -2415,43 +2433,71 @@ extern int toc_initialized;
|
||||
#define RS6000_WEAK 0
|
||||
#endif
|
||||
|
||||
/* This implementes the `alias' attribute. */
|
||||
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target) \
|
||||
do { \
|
||||
const char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
|
||||
char * name = IDENTIFIER_POINTER (target); \
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL \
|
||||
&& DEFAULT_ABI == ABI_AIX) \
|
||||
{ \
|
||||
if (TREE_PUBLIC (decl)) \
|
||||
{ \
|
||||
if (RS6000_WEAK && DECL_WEAK (decl)) \
|
||||
{ \
|
||||
fputs ("\t.weak .", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fputs ("\t.globl .", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fputs ("\t.lglobl .", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
fputs ("\t.set .", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
fputs (",.", FILE); \
|
||||
assemble_name (FILE, name); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
ASM_OUTPUT_DEF (FILE, alias, name); \
|
||||
} while (0)
|
||||
#if RS6000_WEAK
|
||||
/* Used in lieu of ASM_WEAKEN_LABEL. */
|
||||
#define ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL) \
|
||||
do \
|
||||
{ \
|
||||
fputs ("\t.weak\t", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
|
||||
&& DEFAULT_ABI == ABI_AIX) \
|
||||
{ \
|
||||
fputs ("\n\t.weak\t.", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
} \
|
||||
fputc ('\n', (FILE)); \
|
||||
if (VAL) \
|
||||
{ \
|
||||
ASM_OUTPUT_DEF ((FILE), (NAME), (VAL)); \
|
||||
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
|
||||
&& DEFAULT_ABI == ABI_AIX) \
|
||||
{ \
|
||||
fputs ("\t.set\t.", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
fputs (",.", (FILE)); \
|
||||
assemble_name ((FILE), (VAL)); \
|
||||
fputc ('\n', (FILE)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* This implements the `alias' attribute. */
|
||||
#undef ASM_OUTPUT_DEF_FROM_DECLS
|
||||
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
|
||||
do \
|
||||
{ \
|
||||
const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
|
||||
const char *name = IDENTIFIER_POINTER (TARGET); \
|
||||
if (TREE_CODE (DECL) == FUNCTION_DECL \
|
||||
&& DEFAULT_ABI == ABI_AIX) \
|
||||
{ \
|
||||
if (TREE_PUBLIC (DECL)) \
|
||||
{ \
|
||||
if (!RS6000_WEAK || !DECL_WEAK (DECL)) \
|
||||
{ \
|
||||
fputs ("\t.globl\t.", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
} \
|
||||
else if (TARGET_XCOFF) \
|
||||
{ \
|
||||
fputs ("\t.lglobl\t.", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
fputs ("\t.set\t.", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
fputs (",.", FILE); \
|
||||
assemble_name (FILE, name); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
ASM_OUTPUT_DEF (FILE, alias, name); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Output to assembler file text saying following lines
|
||||
may contain character constants, extra white space, comments, etc. */
|
||||
@@ -2706,6 +2752,10 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
|
||||
/* Define the codes that are matched by predicates in rs6000.c. */
|
||||
|
||||
#define PREDICATE_CODES \
|
||||
{"any_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
|
||||
LABEL_REF, SUBREG, REG, MEM, PARALLEL}}, \
|
||||
{"zero_constant", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
|
||||
LABEL_REF, SUBREG, REG, MEM}}, \
|
||||
{"short_cint_operand", {CONST_INT}}, \
|
||||
{"u_short_cint_operand", {CONST_INT}}, \
|
||||
{"non_short_cint_operand", {CONST_INT}}, \
|
||||
@@ -2715,6 +2765,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
|
||||
{"cc_reg_not_cr0_operand", {SUBREG, REG}}, \
|
||||
{"reg_or_short_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_aligned_short_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_arith_cint_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
@@ -2761,6 +2812,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
|
||||
GT, LEU, LTU, GEU, GTU}}, \
|
||||
{"boolean_operator", {AND, IOR, XOR}}, \
|
||||
{"boolean_or_operator", {IOR, XOR}}, \
|
||||
{"altivec_register_operand", {REG}}, \
|
||||
{"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
|
||||
|
||||
/* uncomment for disabling the corresponding default options */
|
||||
@@ -2938,19 +2990,6 @@ enum rs6000_builtins
|
||||
ALTIVEC_BUILTIN_VUPKLSB,
|
||||
ALTIVEC_BUILTIN_VUPKLPX,
|
||||
ALTIVEC_BUILTIN_VUPKLSH,
|
||||
ALTIVEC_BUILTIN_VCMPBFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQUB_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQUH_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQUW_P,
|
||||
ALTIVEC_BUILTIN_VCMPGEFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTSB_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTSH_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTSW_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTUB_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTUH_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTUW_P,
|
||||
ALTIVEC_BUILTIN_MTVSCR,
|
||||
ALTIVEC_BUILTIN_MFVSCR,
|
||||
ALTIVEC_BUILTIN_DSSALL,
|
||||
@@ -2970,5 +3009,25 @@ enum rs6000_builtins
|
||||
ALTIVEC_BUILTIN_STVEBX,
|
||||
ALTIVEC_BUILTIN_STVEHX,
|
||||
ALTIVEC_BUILTIN_STVEWX,
|
||||
ALTIVEC_BUILTIN_STVXL
|
||||
ALTIVEC_BUILTIN_STVXL,
|
||||
ALTIVEC_BUILTIN_VCMPBFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQUB_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQUH_P,
|
||||
ALTIVEC_BUILTIN_VCMPEQUW_P,
|
||||
ALTIVEC_BUILTIN_VCMPGEFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTFP_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTSB_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTSH_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTSW_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTUB_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTUH_P,
|
||||
ALTIVEC_BUILTIN_VCMPGTUW_P,
|
||||
ALTIVEC_BUILTIN_ABSS_V4SI,
|
||||
ALTIVEC_BUILTIN_ABSS_V8HI,
|
||||
ALTIVEC_BUILTIN_ABSS_V16QI,
|
||||
ALTIVEC_BUILTIN_ABS_V4SI,
|
||||
ALTIVEC_BUILTIN_ABS_V4SF,
|
||||
ALTIVEC_BUILTIN_ABS_V8HI,
|
||||
ALTIVEC_BUILTIN_ABS_V16QI
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user