summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2005-06-03 04:02:20 +0000
committerkan <kan@FreeBSD.org>2005-06-03 04:02:20 +0000
commit17d0aa6eb2050531034d5fd72e59df4a5ebdd64e (patch)
treedc04596dd574786e48bfdb08626f8333c6aa3e3c
parentff647fd5f2288c34f81130b9002d20a025a5a388 (diff)
downloadFreeBSD-src-17d0aa6eb2050531034d5fd72e59df4a5ebdd64e.zip
FreeBSD-src-17d0aa6eb2050531034d5fd72e59df4a5ebdd64e.tar.gz
Merge conflicts for GCC 3.4.4.
-rw-r--r--contrib/gcc/c-common.c94
-rw-r--r--contrib/gcc/c-format.c80
-rw-r--r--contrib/gcc/c-opts.c38
-rw-r--r--contrib/gcc/c.opt8
-rw-r--r--contrib/gcc/config/freebsd-spec.h32
-rw-r--r--contrib/gcc/config/i386/freebsd.h13
-rw-r--r--contrib/gcc/config/i386/i386.c132
-rw-r--r--contrib/gcc/config/i386/i386.h14
-rw-r--r--contrib/gcc/function.c81
-rw-r--r--contrib/gcc/gcc.c18
-rw-r--r--contrib/gcc/toplev.c13
11 files changed, 343 insertions, 180 deletions
diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c
index 0d3bdae..50516f4 100644
--- a/contrib/gcc/c-common.c
+++ b/contrib/gcc/c-common.c
@@ -775,7 +775,6 @@ static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
bool *);
-static tree vector_size_helper (tree, tree);
static void check_function_nonnull (tree, tree);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -1146,7 +1145,7 @@ fname_decl (unsigned int rid, tree id)
input_line = saved_lineno;
}
if (!ix && !current_function_decl)
- pedwarn ("%J'%D' is not defined outside of function scope", decl, decl);
+ pedwarn ("'%D' is not defined outside of function scope", decl);
return decl;
}
@@ -4651,7 +4650,10 @@ handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
else
for (j = 0; j < NUM_MACHINE_MODES; j++)
if (!strcmp (p, GET_MODE_NAME (j)))
- mode = (enum machine_mode) j;
+ {
+ mode = (enum machine_mode) j;
+ break;
+ }
if (mode == VOIDmode)
error ("unknown machine mode `%s'", p);
@@ -4684,8 +4686,44 @@ handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
mode);
*node = ptr_type;
}
+ else if (TREE_CODE (type) == ENUMERAL_TYPE)
+ {
+ /* For enumeral types, copy the precision from the integer
+ type returned above. If not an INTEGER_TYPE, we can't use
+ this mode for this type. */
+ if (TREE_CODE (typefm) != INTEGER_TYPE)
+ {
+ error ("cannot use mode %qs for enumeral types", p);
+ return NULL_TREE;
+ }
+
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ type = build_type_copy (type);
+
+ /* We cannot use layout_type here, because that will attempt
+ to re-layout all variants, corrupting our original. */
+ TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+ TYPE_MIN_VALUE (type) = TYPE_MIN_VALUE (typefm);
+ TYPE_MAX_VALUE (type) = TYPE_MAX_VALUE (typefm);
+ TYPE_SIZE (type) = TYPE_SIZE (typefm);
+ TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (typefm);
+ TYPE_MODE (type) = TYPE_MODE (typefm);
+ if (!TYPE_USER_ALIGN (type))
+ TYPE_ALIGN (type) = TYPE_ALIGN (typefm);
+
+ *node = type;
+ }
+ else if (VECTOR_MODE_P (mode)
+ ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
+ : TREE_CODE (type) != TREE_CODE (typefm))
+
+ {
+ error ("mode `%s' applied to inappropriate type", p);
+ return NULL_TREE;
+ }
else
- *node = typefm;
+ *node = typefm;
+
/* No need to layout the type here. The caller should do this. */
}
}
@@ -5254,57 +5292,11 @@ handle_vector_size_attribute (tree *node, tree name, tree args,
}
/* Build back pointers if needed. */
- *node = vector_size_helper (*node, new_type);
+ *node = reconstruct_complex_type (*node, new_type);
return NULL_TREE;
}
-/* HACK. GROSS. This is absolutely disgusting. I wish there was a
- better way.
-
- If we requested a pointer to a vector, build up the pointers that
- we stripped off while looking for the inner type. Similarly for
- return values from functions.
-
- The argument "type" is the top of the chain, and "bottom" is the
- new type which we will point to. */
-
-static tree
-vector_size_helper (tree type, tree bottom)
-{
- tree inner, outer;
-
- if (POINTER_TYPE_P (type))
- {
- inner = vector_size_helper (TREE_TYPE (type), bottom);
- outer = build_pointer_type (inner);
- }
- else if (TREE_CODE (type) == ARRAY_TYPE)
- {
- inner = vector_size_helper (TREE_TYPE (type), bottom);
- outer = build_array_type (inner, TYPE_DOMAIN (type));
- }
- else if (TREE_CODE (type) == FUNCTION_TYPE)
- {
- inner = vector_size_helper (TREE_TYPE (type), bottom);
- outer = build_function_type (inner, TYPE_ARG_TYPES (type));
- }
- else if (TREE_CODE (type) == METHOD_TYPE)
- {
- inner = vector_size_helper (TREE_TYPE (type), bottom);
- outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
- inner,
- TYPE_ARG_TYPES (type));
- }
- else
- return bottom;
-
- TREE_READONLY (outer) = TREE_READONLY (type);
- TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
-
- return outer;
-}
-
/* Handle the "nonnull" attribute. */
static tree
handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
diff --git a/contrib/gcc/c-format.c b/contrib/gcc/c-format.c
index 5ca1607..34327a9 100644
--- a/contrib/gcc/c-format.c
+++ b/contrib/gcc/c-format.c
@@ -2600,9 +2600,27 @@ init_dynamic_asm_fprintf_info (void)
length modifier to work, one must have issued: "typedef
HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
prior to using that modifier. */
- if (!(hwi = maybe_get_identifier ("__gcc_host_wide_int__"))
- || !(hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi))))
+ hwi = maybe_get_identifier ("__gcc_host_wide_int__");
+ if (!hwi)
+ {
+ error ("'__gcc_host_wide_int__' is not defined as a type");
+ return;
+ }
+ hwi = identifier_global_value (hwi);
+ if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
+ {
+ error ("'__gcc_host_wide_int__' is not defined as a type");
+ return;
+ }
+ hwi = DECL_ORIGINAL_TYPE (hwi);
+ if (!hwi)
abort ();
+ if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
+ {
+ error ("'__gcc_host_wide_int__' is not defined as 'long'"
+ " or 'long long'");
+ return;
+ }
/* Create a new (writable) copy of asm_fprintf_length_specs. */
new_asm_fprintf_length_specs = xmemdup (asm_fprintf_length_specs,
@@ -2645,19 +2663,71 @@ init_dynamic_diag_info (void)
However we don't force a hard ICE because we may see only one
or the other type. */
if ((loc = maybe_get_identifier ("location_t")))
- loc = TREE_TYPE (identifier_global_value (loc));
+ {
+ loc = identifier_global_value (loc);
+ if (loc)
+ {
+ if (TREE_CODE (loc) != TYPE_DECL)
+ {
+ error ("'location_t' is not defined as a type");
+ loc = 0;
+ }
+ else
+ loc = TREE_TYPE (loc);
+ }
+ }
/* We need to grab the underlying `union tree_node' so peek into
an extra type level. */
if ((t = maybe_get_identifier ("tree")))
- t = TREE_TYPE (TREE_TYPE (identifier_global_value (t)));
+ {
+ t = identifier_global_value (t);
+ if (t)
+ {
+ if (TREE_CODE (t) != TYPE_DECL)
+ {
+ error ("'tree' is not defined as a type");
+ t = 0;
+ }
+ else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+ {
+ error ("'tree' is not defined as a pointer type");
+ t = 0;
+ }
+ else
+ t = TREE_TYPE (TREE_TYPE (t));
+ }
+ }
/* Find the underlying type for HOST_WIDE_INT. For the %w
length modifier to work, one must have issued: "typedef
HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
prior to using that modifier. */
if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
- hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi));
+ {
+ hwi = identifier_global_value (hwi);
+ if (hwi)
+ {
+ if (TREE_CODE (hwi) != TYPE_DECL)
+ {
+ error ("'__gcc_host_wide_int__' is not defined as a type");
+ hwi = 0;
+ }
+ else
+ {
+ hwi = DECL_ORIGINAL_TYPE (hwi);
+ if (!hwi)
+ abort ();
+ if (hwi != long_integer_type_node
+ && hwi != long_long_integer_type_node)
+ {
+ error ("'__gcc_host_wide_int__' is not defined"
+ " as 'long' or 'long long'");
+ hwi = 0;
+ }
+ }
+ }
+ }
/* Assign the new data for use. */
diff --git a/contrib/gcc/c-opts.c b/contrib/gcc/c-opts.c
index 9977f3a..84f86cb 100644
--- a/contrib/gcc/c-opts.c
+++ b/contrib/gcc/c-opts.c
@@ -188,10 +188,10 @@ defer_opt (enum opt_code code, const char *arg)
/* Common initialization before parsing options. */
unsigned int
-c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
+c_common_init_options (unsigned int argc, const char **argv)
{
static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
- unsigned int result;
+ unsigned int i, result;
/* This is conditionalized only because that is the way the front
ends used to do it. Maybe this should be unconditional? */
@@ -224,17 +224,25 @@ c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
result = lang_flags[c_language];
- /* If potentially preprocessing Fortran we have to accept its front
- end options since the driver passes most of them through. */
-#ifdef CL_F77
- if (c_language == clk_c && argc > 2
- && !strcmp (argv[2], "-traditional-cpp" ))
+ if (c_language == clk_c)
{
- permit_fortran_options = true;
- result |= CL_F77;
- }
+ for (i = 1; i < argc; i++)
+ {
+ /* If preprocessing assembly language, accept any of the C-family
+ front end options since the driver may pass them through. */
+ if (! strcmp (argv[i], "-lang-asm"))
+ result |= CL_C | CL_ObjC | CL_CXX | CL_ObjCXX;
+#ifdef CL_F77
+ /* If potentially preprocessing Fortran we have to accept its
+ front end options since the driver may them through. */
+ else if (! strcmp (argv[i], "-traditional-cpp"))
+ {
+ permit_fortran_options = true;
+ result |= CL_F77;
+ }
#endif
-
+ }
+ }
return result;
}
@@ -1165,8 +1173,12 @@ c_common_post_options (const char **pfilename)
*pfilename = this_input_filename
= cpp_read_main_file (parse_in, in_fnames[0]);
+ /* Don't do any compilation or preprocessing if there is no input file. */
if (this_input_filename == NULL)
- return true;
+ {
+ errorcount++;
+ return false;
+ }
if (flag_working_directory
&& flag_preprocess_only && ! flag_no_line_commands)
@@ -1355,11 +1367,13 @@ sanitize_cpp_opts (void)
/* Disable -dD, -dN and -dI if normal output is suppressed. Allow
-dM since at least glibc relies on -M -dM to work. */
+ /* Also, flag_no_output implies flag_no_line_commands, always. */
if (flag_no_output)
{
if (flag_dump_macros != 'M')
flag_dump_macros = 0;
flag_dump_includes = 0;
+ flag_no_line_commands = 1;
}
cpp_opts->unsigned_char = !flag_signed_char;
diff --git a/contrib/gcc/c.opt b/contrib/gcc/c.opt
index 5343289..0568463 100644
--- a/contrib/gcc/c.opt
+++ b/contrib/gcc/c.opt
@@ -407,7 +407,7 @@ Give strings the type \"array of char\"
ansi
C ObjC C++ ObjC++
-A synonym for -std=c89. In a future version of GCC it will become synonymous with -std=c99 instead
+A synonym for -std=c89 (for C) or -std=c++98 (for C++).
d
C ObjC C++ ObjC++ Joined
@@ -790,7 +790,7 @@ Deprecated in favor of -std=gnu99
std=iso9899:1990
C ObjC
-Deprecated in favor of -std=c89
+Conform to the ISO 1990 C standard
std=iso9899:199409
C ObjC
@@ -798,11 +798,11 @@ Conform to the ISO 1990 C standard as amended in 1994
std=iso9899:1999
C ObjC
-Deprecated in favor of -std=c99
+Conform to the ISO 1999 C standard
std=iso9899:199x
C ObjC
-Deprecated in favor of -std=c99
+Deprecated in favor of -std=iso9899:1999
traditional-cpp
C ObjC C++ ObjC++
diff --git a/contrib/gcc/config/freebsd-spec.h b/contrib/gcc/config/freebsd-spec.h
index 5c27804..e0a5b66 100644
--- a/contrib/gcc/config/freebsd-spec.h
+++ b/contrib/gcc/config/freebsd-spec.h
@@ -130,15 +130,15 @@ Boston, MA 02111-1307, USA. */
required by the user-land thread model. Before __FreeBSD_version
500016, select the appropriate libc, depending on whether we're
doing profiling or need threads support. At __FreeBSD_version
- 500016 and later, thread libraries can be linked with libc. To
- make matters interesting, we can't actually use __FreeBSD_version
- provided by <osreldate.h> directly since it breaks cross-compiling.
- As a final twist, make it a hard error if -pthread is provided on
- the command line and gcc was configured with --disable-threads
- (this will help avoid bug reports from users complaining about
- threading when they misconfigured the gcc bootstrap but are later
- consulting FreeBSD manual pages that refer to the mythical -pthread
- option). */
+ 500016 and later, when threads support is requested include both
+ -lc and the threading lib instead of only -lc_r. To make matters
+ interesting, we can't actually use __FreeBSD_version provided by
+ <osreldate.h> directly since it breaks cross-compiling. As a final
+ twist, make it a hard error if -pthread is provided on the command
+ line and gcc was configured with --disable-threads (this will help
+ avoid bug reports from users complaining about threading when they
+ misconfigured the gcc bootstrap but are later consulting FreeBSD
+ manual pages that refer to the mythical -pthread option). */
/* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate
libc, depending on whether we're doing profiling or need threads support.
@@ -154,13 +154,7 @@ is built with the --enable-threads configure-time option.} \
}"
#else
#include <sys/param.h>
-#if __FreeBSD_version >= 500016
-#define FBSD_LIB_SPEC " \
- %{!shared: \
- %{!pg: %{pthread:-lpthread} -lc} \
- %{pg: %{pthread:-lpthread_p} -lc_p} \
- }"
-#else
+#if __FreeBSD_version < 500016
#define FBSD_LIB_SPEC " \
%{!shared: \
%{!pg: \
@@ -170,6 +164,12 @@ is built with the --enable-threads configure-time option.} \
%{!pthread:-lc_p} \
%{pthread:-lc_r_p}} \
}"
+#else
+#define FBSD_LIB_SPEC " \
+ %{!shared: \
+ %{!pg: %{pthread:-lpthread} -lc} \
+ %{pg: %{pthread:-lpthread_p} -lc_p} \
+ }"
#endif
#endif
diff --git a/contrib/gcc/config/i386/freebsd.h b/contrib/gcc/config/i386/freebsd.h
index 12f513e..261f739 100644
--- a/contrib/gcc/config/i386/freebsd.h
+++ b/contrib/gcc/config/i386/freebsd.h
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* $FreeBSD$ */
+-/* $FreeBSD$ */
#undef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) %{profile:-p}"
@@ -113,15 +113,8 @@ Boston, MA 02111-1307, USA. */
/* FreeBSD sets the rounding precision of the FPU to 53 bits. Let the
compiler get the contents of <float.h> and std::numeric_limits correct. */
-#define SUBTARGET_OVERRIDE_OPTIONS \
- do { \
- if (!TARGET_64BIT) { \
- REAL_MODE_FORMAT (XFmode) \
- = &ieee_extended_intel_96_round_53_format; \
- REAL_MODE_FORMAT (TFmode) \
- = &ieee_extended_intel_96_round_53_format; \
- } \
- } while (0)
+#undef TARGET_96_ROUND_53_LONG_DOUBLE
+#define TARGET_96_ROUND_53_LONG_DOUBLE (!TARGET_64BIT)
/* Tell final.c that we don't need a label passed to mcount. */
#define NO_PROFILE_COUNTERS 1
diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c
index 2e6b411..d0040fb 100644
--- a/contrib/gcc/config/i386/i386.c
+++ b/contrib/gcc/config/i386/i386.c
@@ -526,7 +526,14 @@ const int x86_sse_typeless_stores = m_ATHLON_K8;
const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
const int x86_use_ffreep = m_ATHLON_K8;
const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6;
-const int x86_inter_unit_moves = ~(m_ATHLON_K8);
+
+/* ??? HACK! The following is a lie. SSE can hold e.g. SImode, and
+ indeed *must* be able to hold SImode so that SSE2 shifts are able
+ to work right. But this can result in some mighty surprising
+ register allocation when building kernels. Turning this off should
+ make us less likely to all-of-the-sudden select an SSE register. */
+const int x86_inter_unit_moves = 0; /* ~(m_ATHLON_K8) */
+
const int x86_ext_80387_constants = m_K6 | m_ATHLON | m_PENT4 | m_PPRO;
/* In case the average insn count for single function invocation is
@@ -2540,6 +2547,34 @@ function_arg_advance (CUMULATIVE_ARGS *cum, /* current arg information */
return;
}
+/* A subroutine of function_arg. We want to pass a parameter whose nominal
+ type is MODE in REGNO. We try to minimize ABI variation, so MODE may not
+ actually be valid for REGNO with the current ISA. In this case, ALT_MODE
+ is used instead. It must be the same size as MODE, and must be known to
+ be valid for REGNO. Finally, ORIG_MODE is the original mode of the
+ parameter, as seen by the type system. This may be different from MODE
+ when we're mucking with things minimizing ABI variations.
+
+ Returns a REG or a PARALLEL as appropriate. */
+
+static rtx
+gen_reg_or_parallel (enum machine_mode mode, enum machine_mode alt_mode,
+ enum machine_mode orig_mode, unsigned int regno)
+{
+ rtx tmp;
+
+ if (HARD_REGNO_MODE_OK (regno, mode))
+ tmp = gen_rtx_REG (mode, regno);
+ else
+ {
+ tmp = gen_rtx_REG (alt_mode, regno);
+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
+ tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
+ }
+
+ return tmp;
+}
+
/* Define where to put the arguments to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -2554,12 +2589,11 @@ function_arg_advance (CUMULATIVE_ARGS *cum, /* current arg information */
(otherwise it is an extra parameter matching an ellipsis). */
rtx
-function_arg (CUMULATIVE_ARGS *cum, /* current arg information */
- enum machine_mode mode, /* current arg mode */
- tree type, /* type of the argument or 0 if lib support */
- int named) /* != 0 for normal args, == 0 for ... args */
+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
+ tree type, int named)
{
- rtx ret = NULL_RTX;
+ enum machine_mode mode = orig_mode;
+ rtx ret = NULL_RTX;
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
@@ -2632,7 +2666,8 @@ function_arg (CUMULATIVE_ARGS *cum, /* current arg information */
"changes the ABI");
}
if (cum->sse_nregs)
- ret = gen_rtx_REG (mode, cum->sse_regno + FIRST_SSE_REG);
+ ret = gen_reg_or_parallel (mode, TImode, orig_mode,
+ cum->sse_regno + FIRST_SSE_REG);
}
break;
case V8QImode:
@@ -2648,7 +2683,8 @@ function_arg (CUMULATIVE_ARGS *cum, /* current arg information */
"changes the ABI");
}
if (cum->mmx_nregs)
- ret = gen_rtx_REG (mode, cum->mmx_regno + FIRST_MMX_REG);
+ ret = gen_reg_or_parallel (mode, DImode, orig_mode,
+ cum->mmx_regno + FIRST_MMX_REG);
}
break;
}
@@ -4323,6 +4359,12 @@ aligned_operand (rtx op, enum machine_mode mode)
/* Didn't find one -- this must be an aligned address. */
return 1;
}
+
+int
+compare_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return GET_CODE (op) == COMPARE;
+}
/* Initialize the table of extra 80387 mathematical constants. */
@@ -5779,45 +5821,40 @@ ix86_find_base_term (rtx x)
bool
legitimate_constant_p (rtx x)
{
- rtx inner;
-
switch (GET_CODE (x))
{
- case SYMBOL_REF:
- /* TLS symbols are not constant. */
- if (tls_symbolic_operand (x, Pmode))
- return false;
- break;
-
case CONST:
- inner = XEXP (x, 0);
-
- /* Offsets of TLS symbols are never valid.
- Discourage CSE from creating them. */
- if (GET_CODE (inner) == PLUS
- && tls_symbolic_operand (XEXP (inner, 0), Pmode))
- return false;
+ x = XEXP (x, 0);
- if (GET_CODE (inner) == PLUS
- || GET_CODE (inner) == MINUS)
+ if (GET_CODE (x) == PLUS)
{
- if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT)
return false;
- inner = XEXP (inner, 0);
+ x = XEXP (x, 0);
}
/* Only some unspecs are valid as "constants". */
- if (GET_CODE (inner) == UNSPEC)
- switch (XINT (inner, 1))
+ if (GET_CODE (x) == UNSPEC)
+ switch (XINT (x, 1))
{
case UNSPEC_TPOFF:
case UNSPEC_NTPOFF:
- return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
+ return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
case UNSPEC_DTPOFF:
- return local_dynamic_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
+ return local_dynamic_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
default:
return false;
}
+
+ /* We must have drilled down to a symbol. */
+ if (!symbolic_operand (x, Pmode))
+ return false;
+ /* FALLTHRU */
+
+ case SYMBOL_REF:
+ /* TLS symbols are never valid. */
+ if (tls_symbolic_operand (x, Pmode))
+ return false;
break;
default:
@@ -10613,10 +10650,11 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
else if (GET_CODE (operand) == CONST_DOUBLE)
{
REAL_VALUE_TYPE r;
- long l[3];
+ long l[4];
REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
real_to_target (l, &r, mode);
+
/* Do not use shift by 32 to avoid warning on 32bit systems. */
if (HOST_BITS_PER_WIDE_INT >= 64)
parts[0]
@@ -10626,6 +10664,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
DImode);
else
parts[0] = immed_double_const (l[0], l[1], DImode);
+
if (upper_mode == SImode)
parts[1] = gen_int_mode (l[2], SImode);
else if (HOST_BITS_PER_WIDE_INT >= 64)
@@ -14901,10 +14940,29 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
if (FP_REGNO_P (regno))
return VALID_FP_MODE_P (mode);
if (SSE_REGNO_P (regno))
- return (TARGET_SSE ? VALID_SSE_REG_MODE (mode) : 0);
+ {
+ /* HACK! We didn't change all of the constraints for SSE1 for the
+ scalar modes on the branch. Fortunately, they're not required
+ for ABI compatibility. */
+ if (!TARGET_SSE2 && !VECTOR_MODE_P (mode))
+ return VALID_SSE_REG_MODE (mode);
+
+ /* We implement the move patterns for all vector modes into and
+ out of SSE registers, even when no operation instructions
+ are available. */
+ return (VALID_SSE_REG_MODE (mode)
+ || VALID_SSE2_REG_MODE (mode)
+ || VALID_MMX_REG_MODE (mode)
+ || VALID_MMX_REG_MODE_3DNOW (mode));
+ }
if (MMX_REGNO_P (regno))
- return (TARGET_MMX
- ? VALID_MMX_REG_MODE (mode) || VALID_MMX_REG_MODE_3DNOW (mode) : 0);
+ {
+ /* We implement the move patterns for 3DNOW modes even in MMX mode,
+ so if the register is available at all, then we can move data of
+ the given mode into or out of it. */
+ return (VALID_MMX_REG_MODE (mode)
+ || VALID_MMX_REG_MODE_3DNOW (mode));
+ }
/* We handle both integer and floats in the general purpose registers.
In future we should be able to handle vector modes as well. */
if (!VALID_INT_MODE_P (mode) && !VALID_FP_MODE_P (mode))
@@ -15240,7 +15298,9 @@ ix86_rtx_costs (rtx x, int code, int outer_code, int *total)
return false;
case FLOAT_EXTEND:
- if (!TARGET_SSE_MATH || !VALID_SSE_REG_MODE (mode))
+ if (!TARGET_SSE_MATH
+ || mode == XFmode
+ || (mode == DFmode && !TARGET_SSE2))
*total = 0;
return false;
diff --git a/contrib/gcc/config/i386/i386.h b/contrib/gcc/config/i386/i386.h
index 92132d1..694cc53 100644
--- a/contrib/gcc/config/i386/i386.h
+++ b/contrib/gcc/config/i386/i386.h
@@ -454,6 +454,10 @@ extern int x86_prefetch_sse;
redefines this to 1. */
#define TARGET_MACHO 0
+/* Subtargets may reset this to 1 in order to enable 96-bit long double
+ with the rounding mode forced to 53 bits. */
+#define TARGET_96_ROUND_53_LONG_DOUBLE 0
+
/* This macro is similar to `TARGET_SWITCHES' but defines names of
command options that have values. Its definition is an
initializer with a subgrouping for each command option.
@@ -1068,14 +1072,11 @@ do { \
#define VALID_SSE2_REG_MODE(MODE) \
((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \
- || (MODE) == V2DImode)
+ || (MODE) == V2DImode || (MODE) == DFmode)
#define VALID_SSE_REG_MODE(MODE) \
((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
- || (MODE) == SFmode || (MODE) == TFmode \
- /* Always accept SSE2 modes so that xmmintrin.h compiles. */ \
- || VALID_SSE2_REG_MODE (MODE) \
- || (TARGET_SSE2 && ((MODE) == DFmode || VALID_MMX_REG_MODE (MODE))))
+ || (MODE) == SFmode || (MODE) == TFmode)
#define VALID_MMX_REG_MODE_3DNOW(MODE) \
((MODE) == V2SFmode || (MODE) == SFmode)
@@ -2999,7 +3000,8 @@ do { \
{"zero_extended_scalar_load_operand", {MEM}}, \
{"vector_move_operand", {CONST_VECTOR, SUBREG, REG, MEM}}, \
{"no_seg_address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
- LABEL_REF, SUBREG, REG, MEM, PLUS, MULT}},
+ LABEL_REF, SUBREG, REG, MEM, PLUS, MULT}}, \
+ {"compare_operator", {COMPARE}},
/* A list of predicates that do special things with modes, and so
should not elicit warnings for VOIDmode match_operand. */
diff --git a/contrib/gcc/function.c b/contrib/gcc/function.c
index 0ecde22..4ff8f6a 100644
--- a/contrib/gcc/function.c
+++ b/contrib/gcc/function.c
@@ -238,7 +238,7 @@ static rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
struct function *);
static struct temp_slot *find_temp_slot_from_address (rtx);
static void put_reg_into_stack (struct function *, rtx, tree, enum machine_mode,
- enum machine_mode, int, unsigned int, int, htab_t);
+ unsigned int, bool, bool, bool, htab_t);
static void schedule_fixup_var_refs (struct function *, rtx, tree, enum machine_mode,
htab_t);
static void fixup_var_refs (rtx, enum machine_mode, int, rtx, htab_t);
@@ -508,6 +508,7 @@ get_frame_size (void)
ALIGN controls the amount of alignment for the address of the slot:
0 means according to MODE,
-1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
+ -2 means use BITS_PER_UNIT,
positive specifies alignment boundary in bits.
We do not round to stack_boundary here.
@@ -545,6 +546,8 @@ assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
size = CEIL_ROUND (size, alignment);
}
+ else if (align == -2)
+ alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */
else
alignment = align / BITS_PER_UNIT;
@@ -1293,9 +1296,9 @@ put_var_into_stack (tree decl, int rescan)
enum machine_mode promoted_mode, decl_mode;
struct function *function = 0;
tree context;
- int can_use_addressof;
- int volatilep = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
- int usedp = (TREE_USED (decl)
+ bool can_use_addressof_p;
+ bool volatile_p = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
+ bool used_p = (TREE_USED (decl)
|| (TREE_CODE (decl) != SAVE_EXPR && DECL_INITIAL (decl) != 0));
context = decl_function_context (decl);
@@ -1342,7 +1345,7 @@ put_var_into_stack (tree decl, int rescan)
/* If this variable lives in the current function and we don't need to put it
in the stack for the sake of setjmp or the non-locality, try to keep it in
a register until we know we actually need the address. */
- can_use_addressof
+ can_use_addressof_p
= (function == 0
&& ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
&& optimize > 0
@@ -1355,7 +1358,8 @@ put_var_into_stack (tree decl, int rescan)
/* If we can't use ADDRESSOF, make sure we see through one we already
generated. */
- if (! can_use_addressof && GET_CODE (reg) == MEM
+ if (! can_use_addressof_p
+ && GET_CODE (reg) == MEM
&& GET_CODE (XEXP (reg, 0)) == ADDRESSOF)
reg = XEXP (XEXP (reg, 0), 0);
@@ -1363,11 +1367,11 @@ put_var_into_stack (tree decl, int rescan)
if (GET_CODE (reg) == REG)
{
- if (can_use_addressof)
+ if (can_use_addressof_p)
gen_mem_addressof (reg, decl, rescan);
else
- put_reg_into_stack (function, reg, TREE_TYPE (decl), promoted_mode,
- decl_mode, volatilep, 0, usedp, 0);
+ put_reg_into_stack (function, reg, TREE_TYPE (decl), decl_mode,
+ 0, volatile_p, used_p, false, 0);
}
else if (GET_CODE (reg) == CONCAT)
{
@@ -1383,14 +1387,14 @@ put_var_into_stack (tree decl, int rescan)
#ifdef FRAME_GROWS_DOWNWARD
/* Since part 0 should have a lower address, do it second. */
put_reg_into_stack (function, hipart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, false, 0);
put_reg_into_stack (function, lopart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, true, 0);
#else
put_reg_into_stack (function, lopart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, false, 0);
put_reg_into_stack (function, hipart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, true, 0);
#endif
/* Change the CONCAT into a combined MEM for both parts. */
@@ -1411,7 +1415,7 @@ put_var_into_stack (tree decl, int rescan)
/* Prevent sharing of rtl that might lose. */
if (GET_CODE (XEXP (reg, 0)) == PLUS)
XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
- if (usedp && rescan)
+ if (used_p && rescan)
{
schedule_fixup_var_refs (function, reg, TREE_TYPE (decl),
promoted_mode, 0);
@@ -1425,20 +1429,24 @@ put_var_into_stack (tree decl, int rescan)
/* Subroutine of put_var_into_stack. This puts a single pseudo reg REG
into the stack frame of FUNCTION (0 means the current function).
+ TYPE is the user-level data type of the value hold in the register.
DECL_MODE is the machine mode of the user-level data type.
- PROMOTED_MODE is the machine mode of the register.
- VOLATILE_P is nonzero if this is for a "volatile" decl.
- USED_P is nonzero if this reg might have already been used in an insn. */
+ ORIGINAL_REGNO must be set if the real regno is not visible in REG.
+ VOLATILE_P is true if this is for a "volatile" decl.
+ USED_P is true if this reg might have already been used in an insn.
+ CONSECUTIVE_P is true if the stack slot assigned to reg must be
+ consecutive with the previous stack slot. */
static void
put_reg_into_stack (struct function *function, rtx reg, tree type,
- enum machine_mode promoted_mode,
- enum machine_mode decl_mode, int volatile_p,
- unsigned int original_regno, int used_p, htab_t ht)
+ enum machine_mode decl_mode, unsigned int original_regno,
+ bool volatile_p, bool used_p, bool consecutive_p,
+ htab_t ht)
{
struct function *func = function ? function : cfun;
- rtx new = 0;
+ enum machine_mode mode = GET_MODE (reg);
unsigned int regno = original_regno;
+ rtx new = 0;
if (regno == 0)
regno = REGNO (reg);
@@ -1451,7 +1459,8 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
}
if (new == 0)
- new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
+ new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode),
+ consecutive_p ? -2 : 0, func);
PUT_CODE (reg, MEM);
PUT_MODE (reg, decl_mode);
@@ -1473,7 +1482,7 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
}
if (used_p)
- schedule_fixup_var_refs (function, reg, type, promoted_mode, ht);
+ schedule_fixup_var_refs (function, reg, type, mode, ht);
}
/* Make sure that all refs to the variable, previously made
@@ -1641,7 +1650,7 @@ fixup_var_refs_insns_with_hash (htab_t ht, rtx var, enum machine_mode promoted_m
tmp.key = var;
ime = htab_find (ht, &tmp);
for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
- if (INSN_P (XEXP (insn_list, 0)))
+ if (INSN_P (XEXP (insn_list, 0)) && !INSN_DELETED_P (XEXP (insn_list, 0)))
fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
unsignedp, 1, may_share);
}
@@ -2909,7 +2918,7 @@ static void
put_addressof_into_stack (rtx r, htab_t ht)
{
tree decl, type;
- int volatile_p, used_p;
+ bool volatile_p, used_p;
rtx reg = XEXP (r, 0);
@@ -2928,12 +2937,12 @@ put_addressof_into_stack (rtx r, htab_t ht)
else
{
type = NULL_TREE;
- volatile_p = 0;
- used_p = 1;
+ volatile_p = false;
+ used_p = true;
}
- put_reg_into_stack (0, reg, type, GET_MODE (reg), GET_MODE (reg),
- volatile_p, ADDRESSOF_REGNO (r), used_p, ht);
+ put_reg_into_stack (0, reg, type, GET_MODE (reg), ADDRESSOF_REGNO (r),
+ volatile_p, used_p, false, ht);
}
/* List of replacements made below in purge_addressof_1 when creating
@@ -3653,10 +3662,20 @@ instantiate_decl (rtx x, HOST_WIDE_INT size, int valid_only)
enum machine_mode mode;
rtx addr;
+ if (x == 0)
+ return;
+
+ /* If this is a CONCAT, recurse for the pieces. */
+ if (GET_CODE (x) == CONCAT)
+ {
+ instantiate_decl (XEXP (x, 0), size / 2, valid_only);
+ instantiate_decl (XEXP (x, 1), size / 2, valid_only);
+ return;
+ }
+
/* If this is not a MEM, no need to do anything. Similarly if the
address is a constant or a register that is not a virtual register. */
-
- if (x == 0 || GET_CODE (x) != MEM)
+ if (GET_CODE (x) != MEM)
return;
addr = XEXP (x, 0);
diff --git a/contrib/gcc/gcc.c b/contrib/gcc/gcc.c
index 80d40ff..bc83fa9 100644
--- a/contrib/gcc/gcc.c
+++ b/contrib/gcc/gcc.c
@@ -748,7 +748,7 @@ static const char *cpp_unique_options =
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
@@ -757,8 +757,9 @@ static const char *cpp_unique_options =
options used to set target flags. Those special target flags settings may
in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options =
-"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}";
+"%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
+ %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*}\
+ %{undef}";
/* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */
@@ -769,7 +770,7 @@ static const char *cc1_options =
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
- %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
%{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
@@ -914,7 +915,7 @@ static const struct compiler default_compilers[] =
cc1 %(cpp_unique_options) %(cc1_options)}}}\
%{!fsyntax-only:%(invoke_as)}}}}", 0},
{"-",
- "%{!E:%e-E required when input is from standard input}\
+ "%{!E:%e-E or -x required when input is from standard input}\
%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
{".h", "@c-header", 0},
{"@c-header",
@@ -1644,11 +1645,18 @@ init_spec (void)
#else
"-lgcc_s%M"
#endif
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
+#endif
,
"-lgcc",
"-lgcc_eh"
#ifdef USE_LIBUNWIND_EXCEPTIONS
+# ifdef HAVE_LD_STATIC_DYNAMIC
+ " %{!static:-Bstatic} -lunwind %{!static:-Bdynamic}"
+# else
" -lunwind"
+# endif
#endif
);
diff --git a/contrib/gcc/toplev.c b/contrib/gcc/toplev.c
index c67b2f5..acb44f6 100644
--- a/contrib/gcc/toplev.c
+++ b/contrib/gcc/toplev.c
@@ -1866,6 +1866,9 @@ compile_file (void)
dw2_output_indirect_constants ();
+ /* Flush any pending equate directives. */
+ process_pending_assemble_output_defs ();
+
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
timevar_push (TV_DUMP);
@@ -3662,8 +3665,7 @@ rest_of_compilation (tree decl)
if ((*targetm.binds_local_p) (current_function_decl))
{
int pref = cfun->preferred_stack_boundary;
- if (cfun->recursive_call_emit
- && cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
+ if (cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
pref = cfun->stack_alignment_needed;
cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
= pref;
@@ -4495,8 +4497,6 @@ process_options (void)
static void
backend_init (void)
{
- init_adjust_machine_modes ();
-
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
#ifdef VMS_DEBUGGING_INFO
@@ -4640,6 +4640,11 @@ do_compile (void)
/* Don't do any more if an error has already occurred. */
if (!errorcount)
{
+ /* This must be run always, because it is needed to compute the FP
+ predefined macros, such as __LDBL_MAX__, for targets using non
+ default FP formats. */
+ init_adjust_machine_modes ();
+
/* Set up the back-end if requested. */
if (!no_backend)
backend_init ();
OpenPOWER on IntegriCloud