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:
commit
a922fa645e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96264
File diff suppressed because it is too large
Load Diff
3781
contrib/gcc/ChangeLog.lib
Normal file
3781
contrib/gcc/ChangeLog.lib
Normal file
File diff suppressed because it is too large
Load Diff
10110
contrib/gcc/FSFChangeLog.10
Normal file
10110
contrib/gcc/FSFChangeLog.10
Normal file
File diff suppressed because it is too large
Load Diff
14493
contrib/gcc/FSFChangeLog.11
Normal file
14493
contrib/gcc/FSFChangeLog.11
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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!! ### */
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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; }
|
||||
;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
236
contrib/gcc/concat.c
Normal file
236
contrib/gcc/concat.c
Normal file
@ -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
|
@ -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) \
|
||||
|
@ -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
|
||||
|
25
contrib/gcc/config/i386/libgcc-x86_64-glibc.ver
Normal file
25
contrib/gcc/config/i386/libgcc-x86_64-glibc.ver
Normal file
@ -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=
|
||||
|
15
contrib/gcc/config/i386/t-linux64
Normal file
15
contrib/gcc/config/i386/t-linux64
Normal file
@ -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));
|
||||
|
@ -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;
|
||||
|
23
contrib/gcc/config/libgcc-glibc.ver
Normal file
23
contrib/gcc/config/libgcc-glibc.ver
Normal file
@ -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
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
407
contrib/gcc/config/rs6000/crtsavres.asm
Normal file
407
contrib/gcc/config/rs6000/crtsavres.asm
Normal file
@ -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
|
||||
|
38
contrib/gcc/config/rs6000/gnu.h
Normal file
38
contrib/gcc/config/rs6000/gnu.h
Normal file
@ -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));
|
||||
|
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
Loading…
Reference in New Issue
Block a user