diff options
author | Alexander Kabaev <kan@FreeBSD.org> | 2005-06-03 04:02:20 +0000 |
---|---|---|
committer | Alexander Kabaev <kan@FreeBSD.org> | 2005-06-03 04:02:20 +0000 |
commit | c3cbf7fdb9688e4d8d9cf93e9561eadd45f1cd78 (patch) | |
tree | dc04596dd574786e48bfdb08626f8333c6aa3e3c /contrib | |
parent | d14a0017703951109256ce8eb36590ba20331baa (diff) | |
download | src-c3cbf7fdb9688e4d8d9cf93e9561eadd45f1cd78.tar.gz src-c3cbf7fdb9688e4d8d9cf93e9561eadd45f1cd78.zip |
Merge conflicts for GCC 3.4.4.
Notes
Notes:
svn path=/head/; revision=146908
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/gcc/c-common.c | 94 | ||||
-rw-r--r-- | contrib/gcc/c-format.c | 80 | ||||
-rw-r--r-- | contrib/gcc/c-opts.c | 38 | ||||
-rw-r--r-- | contrib/gcc/c.opt | 8 | ||||
-rw-r--r-- | contrib/gcc/config/freebsd-spec.h | 32 | ||||
-rw-r--r-- | contrib/gcc/config/i386/freebsd.h | 13 | ||||
-rw-r--r-- | contrib/gcc/config/i386/i386.c | 132 | ||||
-rw-r--r-- | contrib/gcc/config/i386/i386.h | 14 | ||||
-rw-r--r-- | contrib/gcc/function.c | 81 | ||||
-rw-r--r-- | contrib/gcc/gcc.c | 18 | ||||
-rw-r--r-- | contrib/gcc/toplev.c | 13 |
11 files changed, 343 insertions, 180 deletions
diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c index 0d3bdaed1f40..50516f48de5d 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 5ca1607cd7de..34327a93087c 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 9977f3a4580e..84f86cb3b71b 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 5343289a2283..0568463e68fb 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 5c27804ab80d..e0a5b6640f0c 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 12f513e751b2..261f739e0a5a 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 2e6b4112c3ee..d0040fb591d3 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 92132d1e2c0f..694cc5367fe7 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 0ecde22223be..4ff8f6a1d015 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 80d40ff2bea7..bc83fa9ef0c6 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 c67b2f58dfd6..acb44f6952d1 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 (); |