aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2002-10-10 04:40:18 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2002-10-10 04:40:18 +0000
commit423134a002b5ea83b68270c33130754764fa5f4c (patch)
treef505e08c93c8d3d8e51f5dac050b459cce4d4ae2
parent10882802bbbce9d52009a76b83e5508d388df999 (diff)
downloadsrc-423134a002b5ea83b68270c33130754764fa5f4c.tar.gz
src-423134a002b5ea83b68270c33130754764fa5f4c.zip
Gcc 3.2.1-prerelease from the FSF anoncvs repo gcc-3_2-branch on October 9th 2002 20:15 EST.
Notes
Notes: svn path=/vendor/gcc/dist/; revision=104752
-rw-r--r--contrib/gcc/ChangeLog336
-rw-r--r--contrib/gcc/Makefile.in10
-rw-r--r--contrib/gcc/c-decl.c23
-rw-r--r--contrib/gcc/c-objc-common.c8
-rw-r--r--contrib/gcc/calls.c8
-rw-r--r--contrib/gcc/config/arm/arm.h14
-rw-r--r--contrib/gcc/config/arm/arm.md9
-rw-r--r--contrib/gcc/config/i386/i386.c63
-rw-r--r--contrib/gcc/config/i386/i386.h23
-rw-r--r--contrib/gcc/config/i386/linux64.h19
-rw-r--r--contrib/gcc/config/i386/t-linux643
-rw-r--r--contrib/gcc/config/i386/winnt.c19
-rw-r--r--contrib/gcc/config/rs6000/rs6000.md2
-rw-r--r--contrib/gcc/config/sparc/linux64.h67
-rw-r--r--contrib/gcc/config/sparc/sol2-bi.h29
-rw-r--r--contrib/gcc/config/sparc/sparc.c1
-rw-r--r--contrib/gcc/config/sparc/sparc.md25
-rw-r--r--contrib/gcc/config/sparc/t-linux6414
-rw-r--r--contrib/gcc/config/sparc/t-sol2-643
-rw-r--r--contrib/gcc/cp/ChangeLog85
-rw-r--r--contrib/gcc/cp/cp-tree.h26
-rw-r--r--contrib/gcc/cp/decl.c25
-rw-r--r--contrib/gcc/cp/decl2.c39
-rw-r--r--contrib/gcc/cp/init.c5
-rw-r--r--contrib/gcc/cp/pt.c42
-rw-r--r--contrib/gcc/cppinit.c124
-rw-r--r--contrib/gcc/cpplib.c57
-rw-r--r--contrib/gcc/cppmacro.c6
-rw-r--r--contrib/gcc/doc/cpp.texi37
-rw-r--r--contrib/gcc/doc/extend.texi74
-rw-r--r--contrib/gcc/doc/invoke.texi22
-rw-r--r--contrib/gcc/doloop.c93
-rw-r--r--contrib/gcc/expr.c126
-rw-r--r--contrib/gcc/f/version.c2
-rw-r--r--contrib/gcc/flags.h4
-rw-r--r--contrib/gcc/gcc.c370
-rw-r--r--contrib/gcc/genmultilib70
-rw-r--r--contrib/gcc/jump.c12
-rw-r--r--contrib/gcc/libgcc2.c9
-rw-r--r--contrib/gcc/loop.c540
-rw-r--r--contrib/gcc/loop.h3
-rw-r--r--contrib/gcc/mklibgcc.in70
-rw-r--r--contrib/gcc/reload.c32
-rw-r--r--contrib/gcc/reload1.c22
-rw-r--r--contrib/gcc/rtl.h1
-rw-r--r--contrib/gcc/sched-deps.c10
-rw-r--r--contrib/gcc/sibcall.c13
-rw-r--r--contrib/gcc/toplev.c10
-rw-r--r--contrib/gcc/tree.h27
-rw-r--r--contrib/gcc/unroll.c13
-rw-r--r--contrib/gcc/varasm.c2
-rw-r--r--contrib/gcc/version.c2
52 files changed, 1715 insertions, 934 deletions
diff --git a/contrib/gcc/ChangeLog b/contrib/gcc/ChangeLog
index 783f3d13a8cb..44f9438f3e29 100644
--- a/contrib/gcc/ChangeLog
+++ b/contrib/gcc/ChangeLog
@@ -1,3 +1,335 @@
+2002-10-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353
+ * c-decl.c (start_decl): Unconditionally issue error for
+ 'typedef foo = bar'.
+ (finish_decl): Remove special case for TYPE_DECL with initializer.
+
+ * doc/extend.texi: Delete "Naming Types" section. Change all
+ cross-references to that section to refer to "Typeof" instead.
+ Add the useful safe-max()-macro example from "Naming Types" to
+ "Typeof", rewritten using that extension. Add some compatibility
+ notes to "Typeof."
+
+2002-10-02 Richard Henderson <rth@redhat.com>
+
+ PR opt/7124
+ * config/i386/i386.c (ix86_register_move_cost): Increase cost
+ for secondary_memory_needed pairs.
+
+Wed Oct 9 19:09:13 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ PR opt/7912
+ PR opt/7390
+ * i386.c (athlon_cost): Fix the move costs.
+
+2002-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * libgcc2.c (__floatdisf): Properly cure double rounding.
+
+2002-10-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR doc/7484
+ * doc/invoke.texi (Option Summary): List
+ -Wmissing-declarations as a C only option.
+
+2002-10-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/t-linux64 (MULTILIB_OPTIONS): Remove
+ mno-app-regs|mcmodel=medany.
+ (MULTILIB_DIRNAMES, MULTILIB_OSDIRNAMES): Remove alt.
+ (MULTILIB_EXCEPTIONS, MULTILIB_EXCLUSIONS, MULTILIB_MATCHES): Remove.
+ (CRTSTUFF_T_CFLAGS): Define.
+
+2002-09-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c/7411
+ * expr.c (expand_expr) [PLUS]: Simplify after the operands
+ have been expanded in EXPAND_NORMAL mode.
+
+2002-10-06 Richard Henderson <rth@redhat.com>
+
+ * config/rs6000/rs6000.md (load_toc_v4_PIC_2): Fix base constraint.
+
+2002-10-06 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6627
+ * toplev.c (force_align_functions_log): New global variable.
+ * flags.h (force_align_functions_log): Add extern prototype.
+ * varasm.c (assemble_start_function): Use it to force minimum
+ function alignment.
+ * config/i386/i386.h (FUNCTION_BOUNDARY): Set the correct
+ minimum function alignment to one byte.
+ (TARGET_PTRMEMFUNC_VBIT_LOCATION): Store the virtual bit in
+ the least significant bit of vtable member function pointers.
+ * tree.h (enum ptrmemfunc_vbit_where_t): Move definition to
+ here from cp/cp-tree.h.
+
+2002-10-06 Neil Booth <neil@daikokuya.co.uk>
+
+ Debian BTS Bug #157416
+ * cpplib.c (destringize_and_run): Kludge around getting
+ tokens from in-progress macros.
+ (_cpp_do__Pragma): Simplify.
+
+2002-10-06 Frank Ch. Eigler <fche@redhat.com>
+
+ * cppinit.c (init_standard_includes, parse_option): Use strncmp.
+
+2002-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.c (set_multilib_dir): Don't access *end.
+ Use memcpy instead of strncpy. Don't write beyond malloced buffer.
+ (print_multilib_info): Don't show paths starting with ".:".
+ * genmultilib: Add new option, "yes" if multilibs are enabled.
+ Update comments. If multilibs not enabled, print .:${osdirout}
+ for each directory. If multilibs are enabled, always print
+ ${dirout}:${osdirout}, even if the two are the same.
+ * Makefile.in (s-mlib): Pass @enable_multilib@ to genmultilib.
+ Pass all MULTILIB_* variables to genmultilib even if
+ --disable-multilib but MULTILIB_OSDIRNAMES is not empty.
+
+ * gcc.c (print_multi_os_directory): New variable.
+ (option_map): Support --print-multi-os-directory.
+ (struct prefix_list): Add os_multilib field.
+ (multilib_os_dir): New variable.
+ (static_specs): Add multilib_options.
+ (find_a_file): Add multilib argument. Search in GCC or OS multilib
+ subdirs if non-zero.
+ (read_specs, execute): Update callers.
+ (find_file): Likewise. Don't prefix name with multilib_dir, instead
+ pass 1 as multilib option.
+ (display_help): Include --print-multi-os-directory.
+ (add_prefix): Add os_multilib argument. Initialize pl->os_multilib.
+ (process_command): Update callers. Handle --print-multi-os-directory.
+ (do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is
+ set.
+ (main): Update find_a_file and add_prefix callers.
+ Handle print_multi_os_directory.
+ (struct mdswitchstr): New.
+ (mdswitches, n_mdswitches): New variables.
+ (used_arg): Add MULTILIB_DEFAULT switches too if they are not
+ present on the command line nor their mutually incompatible
+ switches.
+ (default_arg): Optimize.
+ (set_multilib_dir): Compute multilib_os_dir. Initialize mdswitches
+ array.
+ (print_multilib_info): Only print GCC multilib dir name, not OS
+ multilib dirname.
+ * genmultilib: Add osdirnames parameter. Output multilib_options
+ variable. If osdirnames is specified, output dirnames as
+ dirname:osdirname.
+ * mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory
+ and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES
+ to compute libgcc_s soname and install path.
+ * Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of
+ SHLIB_SLIBDIR_SUFFIXES to mklibgcc.
+ (s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib
+ argument.
+
+ * config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+ * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64,
+ ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32
+ and -m64.
+ * config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+ * config/sparc/sol2-bi.h (STARTFILE_SPEC32, STARTFILE_SPEC64): Remove.
+ (STARTFILE_ARCH_SPEC): Remove.
+ (STARTFILE_SPEC): Add values-X*.o here.
+ * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+ * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between m32 and
+ !m32.
+ * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+
+2002-10-05 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/8120
+ * doc/cpp.texi: Update documentation of bad use of ##.
+
+Thu Oct 3 23:15:15 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (CPP_SPECS): fix defines for -msse, -msse2, -mpentium2,3.
+
+Thu Oct 3 21:35:36 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Dump loops before clobbering
+ the structure.
+
+ * expr.c (force_operand): Use expand_simple_* to handle more
+ cases.
+
+ * i386.c (q_regs_operand): Use ANY_QI_REG_P.
+
+ * i386.c (override_options): Fix stack alignment.
+ (classify_argument): Handle variable sized types.
+ (ix86_expand_int_movcc): Avoid RTL sharing problem.
+
+ * i386.md (prefetch_sse_rex, prefetch_3dnow_rex): New.
+ (prefetch): Properly handle 64bit case.
+
+ * i386.c (classify_argument): Properly compute word size of the analyzed object.
+
+ * jump.c (reg_or_subregno): New function.
+ * rtl.h (reg_or_subregno): Declare
+ * unroll.c (find_splittable_givs): Handle subregs.
+
+ Richard Sandiford <rsandifo@redhat.com>:
+
+ * expr.c (force_operand): Fix reversed move.
+
+ Andreas Jaeger <aj@suse.de>:
+
+ * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): New.
+
+ Janis Johnson <janis187@us.ibm.com>:
+
+ * loop.c (emit_prefetch_instructions): Several small fixes.
+
+Thu Sep 5 00:34:33 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * loop.c (scan_loop): Don't mark separate insns out of a libcall
+ for moving.
+ (move_movables): Abort if we see the first insn of a libcall.
+
+2002-10-01 David S. Miller <davem@redhat.com>
+
+ PR middle-end/7151
+ * config/sparc/sparc.md (movdi_insn_sp32_v9): Accept 'e' regs.
+ (movdi reg/reg split): Match only on sparc32, and v9 when int regs.
+
+2002-10-01 David S. Miller <davem@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ * reload1.c (gen_reload:SECONDARY_MEMORY_NEEDED): Handle SUBREG.
+ * reload.c (push_reload:SECONDARY_MEMORY_NEEDED): Likewise.
+
+2002-09-30 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (REG_CLASS_NAMES, REG_CLASS_CONTENTS):
+ Add new RL_REGS register class.
+ (PREFERRED_RELOAD_CLASS, PREFERRED_OUTPUT_RELOAD_CLASS):
+ Call xtensa_preferred_reload_class for both input and output reloads.
+ * config/xtensa/xtensa.c (xtensa_regno_to_class): Use new RL_REGS class.
+ (xtensa_preferred_reload_class): Handle output reloads; use RL_REGS
+ instead of either AR_REGS or GR_REGS classes.
+ (xtensa_secondary_reload_class): Use new RL_REGS class.
+ * config/xtensa/xtensa-protos.h (xtensa_preferred_reload_class): Update.
+
+2002-08-21 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * cppinit.c (remove_dup_nonsys_dirs): Fix warning and return value.
+
+2002-08-20 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * cppinit.c (remove_dup_dir): Add head_ptr argument to handle removal
+ at head.
+ (remove_dup_nonsys_dirs): New function.
+ (remove_dup_dirs): Change argument head to head_ptr. Remove warnings.
+ (merge_include_chains): Remove non-system include directories from
+ quote and bracket include chains when they duplicate equivalent system
+ directories.
+ * doc/cpp.texi (-I): Update.
+ * doc/cppopts.texi (-I): Update.
+ * doc/install.texi (--with-local-prefix): Further document usage of
+ this option.
+ * doc/invoke.texi (-I): Update.
+
+2002-09-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (BASE_REG_CLASS): Always return LO_REGS for Thumb.
+ (MODE_BASE_REG_CLASS, case Thumb): Only return BASE_REGS if we know
+ that we have a SImode access, and only then if reload hasn't completed;
+ for all other cases, use LO_REGS.
+
+2002-09-29 David S. Miller <davem@redhat.com>
+
+ * config/sparc/linux64.h (STARTFILE_SPEC32, ENDFILE_SPEC32): Kill
+ hardcoded paths.
+
+2002-09-27 Alexander N. Kabaev <ak03@gte.com>
+
+ PR preprocessor/8055
+ * cppmacro.c (stringify_arg): Do not overflow the buffer
+ with the terminating NUL when the argument to be stringified
+ has no tokens.
+
+2002-09-26 David S. Miller <davem@redhat.com>
+
+ PR optimization/7335
+ * calls.c (emit_library_call_value_1): Passing args by reference
+ converts a CONST function into a PURE one.
+
+2002-09-26 Richard Henderson <rth@redhat.com>
+
+ PR c/7160
+ * sched-deps.c (sched_analyze_insn): Make clobber insns depend
+ on call insns.
+
+2002-09-27 Alan Modra <amodra@bigpond.net.au>
+
+ * doloop.c (doloop_modify_runtime <biv skips initial incr>): Adjust
+ by absolute loop increment, not loop increment.
+
+2002-09-25 David S. Miller <davem@redhat.com>
+
+ PR target/7842
+ * config/sparc/sparc.c (set_extends): SImode ASHIFT does not
+ extend.
+
+2002-09-20 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * config/arm/arm.md (sign_extract_onebit, not_signextract_onebit):
+ Add clobber of the condition code register.
+
+2002-09-18 Richard Earnshaw (rearnsha@arm.com)
+
+ PR optimization/7967
+ * arm.md (ne_zeroextractsi): Add clobber of the condition code
+ register.
+
+2002-09-17 Richard Henderson <rth@redhat.com>
+
+ * sibcall.c (optimize_sibling_and_tail_recursive_call): Also remove
+ RTX_UNCHANGING_P markers for successful tail-recursive replacement.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ PR opt/7515
+ * c-objc-common.c (c_cannot_inline_tree_fn): Don't auto-inline
+ functions that don't bind locally.
+
+2002-09-17 Alan Modra <amodra@bigpond.net.au>
+
+ Merge from mainline.
+ 2002-07-20 Alan Modra <amodra@bigpond.net.au>
+ PR optimization/7130
+ * loop.h (struct loop_info): Add "preconditioned".
+ * unroll.c (unroll_loop): Set it.
+ * doloop.c (doloop_modify_runtime): Correct count for unrolled loops.
+
+ 2002-06-24 Alan Modra <amodra@bigpond.net.au>
+ PR optimization/6984
+ * doloop.c (doloop_valid_p): Correct comment.
+ (doloop_modify_runtime <abs_inc != 1>): Simplify.
+ (doloop_modify_runtime <do-while>): Don't emit code when NE.
+
+2002-09-16 Jeff Law <law@redhat.com>
+
+ * libgcc2.c: Do not include machmode.h.
+
+2002-09-16 Jason Merrill <jason@redhat.com>
+ Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (ix86_handle_dll_attribute): Set
+ DECL_EXTERN and TREE_PUBLIC for dllimported variables here...
+ (i386_pe_mark_dllimport): Not here.
+
2002-09-14 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md ("movdi_internal"): Allow any offsetable
@@ -185,7 +517,7 @@
2002-08-27 Mark Mitchell <mark@codesourcery.com>
* doc/invoke.texi: Document -Wabi.
-
+
2002-08-23 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.c (rs6000_select_section): Treat
@@ -201,7 +533,7 @@
* explow.c (expr_size): Call it.
(int_expr_size): New fn.
* expr.h: Declare it.
- * expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how
+ * expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how
much to store.
2002-08-23 Alan Modra <amodra@bigpond.net.au>
diff --git a/contrib/gcc/Makefile.in b/contrib/gcc/Makefile.in
index ebcbbc2b6af5..5afd30ef0467 100644
--- a/contrib/gcc/Makefile.in
+++ b/contrib/gcc/Makefile.in
@@ -1003,7 +1003,7 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext
SHLIB_MKMAP_OPTS='$(SHLIB_MKMAP_OPTS)' \
SHLIB_MAPFILES='$(SHLIB_MAPFILES)' \
SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \
- SHLIB_SLIBDIR_SUFFIXES='$(SHLIB_SLIBDIR_SUFFIXES)' \
+ MULTILIB_OSDIRNAMES='$(MULTILIB_OSDIRNAMES)' \
mkinstalldirs='$(SHELL) $(srcdir)/mkinstalldirs' \
$(SHELL) mklibgcc > tmp-libgcc.mk
mv tmp-libgcc.mk libgcc.mk
@@ -1037,7 +1037,8 @@ libgcc.a: $(LIBGCC_DEPS)
# switches.
multilib.h: s-mlib; @true
s-mlib: $(srcdir)/genmultilib Makefile
- if test @enable_multilib@ = yes; then \
+ if test @enable_multilib@ = yes \
+ || test -n "$(MULTILIB_OSDIRNAMES)"; then \
$(SHELL) $(srcdir)/genmultilib \
"$(MULTILIB_OPTIONS)" \
"$(MULTILIB_DIRNAMES)" \
@@ -1045,9 +1046,12 @@ s-mlib: $(srcdir)/genmultilib Makefile
"$(MULTILIB_EXCEPTIONS)" \
"$(MULTILIB_EXTRA_OPTS)" \
"$(MULTILIB_EXCLUSIONS)" \
+ "$(MULTILIB_OSDIRNAMES)" \
+ "@enable_multilib@" \
> tmp-mlib.h; \
else \
- $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' > tmp-mlib.h; \
+ $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' no \
+ > tmp-mlib.h; \
fi
$(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h
$(STAMP) s-mlib
diff --git a/contrib/gcc/c-decl.c b/contrib/gcc/c-decl.c
index a6e010bafe0f..ea0b5f60d73f 100644
--- a/contrib/gcc/c-decl.c
+++ b/contrib/gcc/c-decl.c
@@ -3485,15 +3485,9 @@ start_decl (declarator, declspecs, initialized, attributes)
switch (TREE_CODE (decl))
{
case TYPE_DECL:
- /* typedef foo = bar means give foo the same type as bar.
- We haven't parsed bar yet, so `finish_decl' will fix that up.
- Any other case of an initialization in a TYPE_DECL is an error. */
- if (pedantic || list_length (declspecs) > 1)
- {
- error ("typedef `%s' is initialized",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
- initialized = 0;
- }
+ error ("typedef `%s' is initialized",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+ initialized = 0;
break;
case FUNCTION_DECL:
@@ -3642,16 +3636,7 @@ finish_decl (decl, init, asmspec_tree)
init = 0;
if (init)
- {
- if (TREE_CODE (decl) != TYPE_DECL)
- store_init_value (decl, init);
- else
- {
- /* typedef foo = bar; store the type of bar as the type of foo. */
- TREE_TYPE (decl) = TREE_TYPE (init);
- DECL_INITIAL (decl) = init = 0;
- }
- }
+ store_init_value (decl, init);
/* Deduce size of array from initialization, if not already known */
if (TREE_CODE (type) == ARRAY_TYPE
diff --git a/contrib/gcc/c-objc-common.c b/contrib/gcc/c-objc-common.c
index 0ed3869b057b..43ec820599bc 100644
--- a/contrib/gcc/c-objc-common.c
+++ b/contrib/gcc/c-objc-common.c
@@ -149,6 +149,14 @@ c_cannot_inline_tree_fn (fnp)
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
+ /* Don't auto-inline anything that might not be bound within
+ this unit of translation. */
+ if (!DECL_DECLARED_INLINE_P (fn) && flag_pic && TREE_PUBLIC (fn))
+ {
+ DECL_UNINLINABLE (fn) = 1;
+ return 1;
+ }
+
if (! function_attribute_inlinable_p (fn))
{
DECL_UNINLINABLE (fn) = 1;
diff --git a/contrib/gcc/calls.c b/contrib/gcc/calls.c
index c0a73e7740e9..449c933d212a 100644
--- a/contrib/gcc/calls.c
+++ b/contrib/gcc/calls.c
@@ -3666,6 +3666,14 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#endif
;
+ /* If this was a CONST function, it is now PURE since
+ it now reads memory. */
+ if (flags & ECF_CONST)
+ {
+ flags &= ~ECF_CONST;
+ flags |= ECF_PURE;
+ }
+
if (GET_MODE (val) == MEM && ! must_copy)
slot = val;
else if (must_copy)
diff --git a/contrib/gcc/config/arm/arm.h b/contrib/gcc/config/arm/arm.h
index 5e8b5d91cd07..c5431b537d5c 100644
--- a/contrib/gcc/config/arm/arm.h
+++ b/contrib/gcc/config/arm/arm.h
@@ -1093,14 +1093,16 @@ enum reg_class
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
-#define BASE_REG_CLASS (TARGET_THUMB ? BASE_REGS : GENERAL_REGS)
+#define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
-/* For the Thumb the high registers cannot be used as base
- registers when addressing quanitities in QI or HI mode. */
+/* For the Thumb the high registers cannot be used as base registers
+ when addressing quanitities in QI or HI mode; if we don't know the
+ mode, then we must be conservative. After reload we must also be
+ conservative, since we can't support SP+reg addressing, and we
+ can't fix up any bad substitutions. */
#define MODE_BASE_REG_CLASS(MODE) \
- (TARGET_ARM ? BASE_REGS : \
- (((MODE) == QImode || (MODE) == HImode || (MODE) == VOIDmode) \
- ? LO_REGS : BASE_REGS))
+ (TARGET_ARM ? GENERAL_REGS : \
+ (((MODE) == SImode && !reload_completed) ? BASE_REGS : LO_REGS))
/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
registers explicitly used in the rtl to be used as spill registers
diff --git a/contrib/gcc/config/arm/arm.md b/contrib/gcc/config/arm/arm.md
index b90150474f48..5180c75933a2 100644
--- a/contrib/gcc/config/arm/arm.md
+++ b/contrib/gcc/config/arm/arm.md
@@ -1837,7 +1837,8 @@
(match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n"))
- (const_int 0)))]
+ (const_int 0)))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_ARM
&& (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
&& INTVAL (operands[2]) > 0
@@ -8947,7 +8948,8 @@
[(set (match_operand:SI 0 "s_register_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
(const_int 1)
- (match_operand:SI 2 "const_int_operand" "n")))]
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
"*
operands[2] = GEN_INT (1 << INTVAL (operands[2]));
@@ -8963,7 +8965,8 @@
(not:SI
(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
(const_int 1)
- (match_operand:SI 2 "const_int_operand" "n"))))]
+ (match_operand:SI 2 "const_int_operand" "n"))))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
"*
operands[2] = GEN_INT (1 << INTVAL (operands[2]));
diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c
index f07ebad251f4..5e487156b1cb 100644
--- a/contrib/gcc/config/i386/i386.c
+++ b/contrib/gcc/config/i386/i386.c
@@ -284,25 +284,25 @@ struct processor_costs athlon_cost = {
8, /* "large" insn */
9, /* MOVE_RATIO */
4, /* cost for loading QImode using movzbl */
- {4, 5, 4}, /* cost of loading integer registers
+ {3, 4, 3}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
- {2, 3, 2}, /* cost of storing integer registers */
+ {3, 4, 3}, /* cost of storing integer registers */
4, /* cost of reg,reg fld/fst */
- {6, 6, 20}, /* cost of loading fp registers
+ {4, 4, 12}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {4, 4, 16}, /* cost of loading integer registers */
+ {6, 6, 8}, /* cost of loading integer registers */
2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
+ {4, 4}, /* cost of loading MMX registers
in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
+ {4, 4}, /* cost of storing MMX registers
in SImode and DImode */
2, /* cost of moving SSE register */
- {2, 2, 8}, /* cost of loading SSE registers
+ {4, 4, 6}, /* cost of loading SSE registers
in SImode, DImode and TImode */
- {2, 2, 8}, /* cost of storing SSE registers
+ {4, 4, 5}, /* cost of storing SSE registers
in SImode, DImode and TImode */
- 6, /* MMX or SSE register to integer */
+ 5, /* MMX or SSE register to integer */
64, /* size of prefetch block */
6, /* number of parallel prefetches */
};
@@ -1649,7 +1649,11 @@ classify_argument (mode, type, classes, bit_offset)
{
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
- int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+
+ /* Variable sized structures are always passed on the stack. */
+ if (mode == BLKmode && type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ return 0;
if (type && AGGREGATE_TYPE_P (type))
{
@@ -3206,7 +3210,7 @@ q_regs_operand (op, mode)
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
- return QI_REG_P (op);
+ return ANY_QI_REG_P (op);
}
/* Return true if op is a NON_Q_REGS class register. */
@@ -6123,7 +6127,10 @@ print_operand_address (file, addr)
int scale;
if (! ix86_decompose_address (addr, &parts))
- abort ();
+ {
+ output_operand_lossage ("Wrong address expression or operand constraint");
+ return;
+ }
base = parts.base;
index = parts.index;
@@ -8237,7 +8244,7 @@ ix86_expand_int_movcc (operands)
clob = gen_rtx_CLOBBER (VOIDmode, clob);
tmp = gen_rtx_SET (VOIDmode, out, tmp);
- tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
+ tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, copy_rtx (tmp), clob));
emit_insn (tmp);
}
else
@@ -12355,17 +12362,33 @@ ix86_register_move_cost (mode, class1, class2)
enum reg_class class1, class2;
{
/* In case we require secondary memory, compute cost of the store followed
- by load. In case of copying from general_purpose_register we may emit
- multiple stores followed by single load causing memory size mismatch
- stall. Count this as arbitarily high cost of 20. */
+ by load. In order to avoid bad register allocation choices, we need
+ for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */
+
if (ix86_secondary_memory_needed (class1, class2, mode, 0))
{
- int add_cost = 0;
+ int cost = 1;
+
+ cost += MAX (MEMORY_MOVE_COST (mode, class1, 0),
+ MEMORY_MOVE_COST (mode, class1, 1));
+ cost += MAX (MEMORY_MOVE_COST (mode, class2, 0),
+ MEMORY_MOVE_COST (mode, class2, 1));
+
+ /* In case of copying from general_purpose_register we may emit multiple
+ stores followed by single load causing memory size mismatch stall.
+ Count this as arbitarily high cost of 20. */
if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode))
- add_cost = 20;
- return (MEMORY_MOVE_COST (mode, class1, 0)
- + MEMORY_MOVE_COST (mode, class2, 1) + add_cost);
+ cost += 20;
+
+ /* In the case of FP/MMX moves, the registers actually overlap, and we
+ have to switch modes in order to treat them differently. */
+ if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
+ || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
+ cost += 20;
+
+ return cost;
}
+
/* Moves between SSE/MMX and integer unit are expensive. */
if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
|| SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
diff --git a/contrib/gcc/config/i386/i386.h b/contrib/gcc/config/i386/i386.h
index 07502a20d392..58d2c4331eae 100644
--- a/contrib/gcc/config/i386/i386.h
+++ b/contrib/gcc/config/i386/i386.h
@@ -584,9 +584,13 @@ extern int ix86_arch;
%{march=pentium-mmx:-D__i586 -D__i586__ -D__pentium -D__pentium__ \
-D__pentium__mmx__ \
%{!mcpu*:-D__tune_i586__ -D__tune_pentium__ -D__tune_pentium_mmx__}}\
-%{march=pentiumpro|march=i686:-D__i686 -D__i686__ \
+%{march=pentiumpro|march=i686|march=pentium2|march=pentium3:-D__i686 -D__i686__ \
-D__pentiumpro -D__pentiumpro__ \
%{!mcpu*:-D__tune_i686__ -D__tune_pentiumpro__ }}\
+%{march=march=pentium2|march=pentium3: -D__pentium2 -D__pentium2__\
+ %{!mcpu*:-D__tune_pentium2__ }}\
+%{march=pentium3: -D__pentium3 -D__pentium3__\
+ %{!mcpu*:-D__tune_pentium3__ }}\
%{march=k6:-D__k6 -D__k6__ %{!mcpu*:-D__tune_k6__ }}\
%{march=k6-2:-D__k6 -D__k6__ -D__k6_2__ \
%{!mcpu*:-D__tune_k6__ -D__tune_k6_2__ }}\
@@ -601,7 +605,7 @@ extern int ix86_arch;
%{m386|mcpu=i386:-D__tune_i386__ }\
%{m486|mcpu=i486:-D__tune_i486__ }\
%{mpentium|mcpu=pentium|mcpu=i586|mcpu=pentium-mmx:-D__tune_i586__ -D__tune_pentium__ }\
-%{mpentiumpro|mcpu=pentiumpro|mcpu=i686|cpu=pentium2|cpu=pentium3:-D__tune_i686__ \
+%{mpentiumpro|mcpu=pentiumpro|mcpu=i686|mcpu=pentium2|mcpu=pentium3:-D__tune_i686__ \
-D__tune_pentiumpro__ }\
%{mcpu=k6|mcpu=k6-2|mcpu=k6-3:-D__tune_k6__ }\
%{mcpu=athlon|mcpu=athlon-tbird|mcpu=athlon-4|mcpu=athlon-xp|mcpu=athlon-mp:\
@@ -609,17 +613,17 @@ extern int ix86_arch;
%{mcpu=athlon-4|mcpu=athlon-xp|mcpu=athlon-mp:\
-D__tune_athlon_sse__ }\
%{mcpu=pentium4:-D__tune_pentium4__ }\
-%{march=athlon-xp|march=athlon-mp|march=pentium3|march=pentium4:\
+%{march=athlon-xp|march=athlon-mp|march=pentium3|march=pentium4|msse|msse2:\
-D__SSE__ }\
%{march=pentium-mmx|march=k6|march=k6-2|march=k6-3\
|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
-|march=athlon-mp|march=pentium2|march=pentium3|march=pentium4: -D__MMX__ }\
+|march=athlon-mp|march=pentium2|march=pentium3|march=pentium4|mmx|msse|m3dnow: -D__MMX__ }\
%{march=k6-2|march=k6-3\
|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
-|march=athlon-mp: -D__3dNOW__ }\
+|march=athlon-mp|m3dnow: -D__3dNOW__ }\
%{march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
|march=athlon-mp: -D__3dNOW_A__ }\
-%{march=pentium4: -D__SSE2__ }\
+%{march=pentium4|msse2: -D__SSE2__ }\
%{!march*:%{!mcpu*:%{!m386:%{!m486:%{!mpentium*:%(cpp_cpu_default)}}}}}"
#ifndef CPP_CPU_SPEC
@@ -756,8 +760,11 @@ extern int ix86_arch;
#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN \
(ix86_preferred_stack_boundary > STACK_BOUNDARY && !TARGET_64BIT)
-/* Allocation boundary for the code of a function. */
-#define FUNCTION_BOUNDARY 16
+/* Minimum allocation boundary for the code of a function. */
+#define FUNCTION_BOUNDARY 8
+
+/* C++ stores the virtual bit in the lowest bit of function pointers. */
+#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_pfn
/* Alignment of field after `int : 0' in a structure. */
diff --git a/contrib/gcc/config/i386/linux64.h b/contrib/gcc/config/i386/linux64.h
index 61584315d43d..8a0bfbe925ad 100644
--- a/contrib/gcc/config/i386/linux64.h
+++ b/contrib/gcc/config/i386/linux64.h
@@ -50,21 +50,14 @@ Boston, MA 02111-1307, USA. */
#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}}}"
+ "%{!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}}"
#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 ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
#define MULTILIB_DEFAULTS { "m64" }
diff --git a/contrib/gcc/config/i386/t-linux64 b/contrib/gcc/config/i386/t-linux64
index 46a7caadf772..31b6ad463862 100644
--- a/contrib/gcc/config/i386/t-linux64
+++ b/contrib/gcc/config/i386/t-linux64
@@ -6,10 +6,9 @@ SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
MULTILIB_OPTIONS = m64/m32
MULTILIB_DIRNAMES = 64 32
+MULTILIB_OSDIRNAMES = ../lib64 ../lib
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:
diff --git a/contrib/gcc/config/i386/winnt.c b/contrib/gcc/config/i386/winnt.c
index 9d955df2f48e..6928a8c7b3af 100644
--- a/contrib/gcc/config/i386/winnt.c
+++ b/contrib/gcc/config/i386/winnt.c
@@ -76,6 +76,15 @@ ix86_handle_dll_attribute (node, name, args, flags, no_add_attrs)
}
}
+ /* `extern' needn't be specified with dllimport.
+ Specify `extern' now and hope for the best. Sigh. */
+ else if (TREE_CODE (*node) == VAR_DECL
+ && is_attribute_p ("dllimport", name))
+ {
+ DECL_EXTERNAL (*node) = 1;
+ TREE_PUBLIC (*node) = 1;
+ }
+
return NULL_TREE;
}
@@ -300,16 +309,6 @@ i386_pe_mark_dllimport (decl)
return;
}
- /* `extern' needn't be specified with dllimport.
- Specify `extern' now and hope for the best. Sigh. */
- if (TREE_CODE (decl) == VAR_DECL
- /* ??? Is this test for vtables needed? */
- && !DECL_VIRTUAL_P (decl))
- {
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
- }
-
newname = alloca (strlen (oldname) + 11);
sprintf (newname, "@i._imp__%s", oldname);
diff --git a/contrib/gcc/config/rs6000/rs6000.md b/contrib/gcc/config/rs6000/rs6000.md
index f032bfd81b8e..6e86d734f663 100644
--- a/contrib/gcc/config/rs6000/rs6000.md
+++ b/contrib/gcc/config/rs6000/rs6000.md
@@ -9657,7 +9657,7 @@
(define_insn "load_toc_v4_PIC_2"
[(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
(minus:SI (match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")))))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
diff --git a/contrib/gcc/config/sparc/linux64.h b/contrib/gcc/config/sparc/linux64.h
index 1dfd97ff919f..c7d8f491166b 100644
--- a/contrib/gcc/config/sparc/linux64.h
+++ b/contrib/gcc/config/sparc/linux64.h
@@ -1,5 +1,5 @@
/* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
- Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
Contributed by David S. Miller (davem@caip.rutgers.edu)
This file is part of GNU CC.
@@ -56,38 +56,12 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
-#define STARTFILE_SPEC32 \
+#define STARTFILE_SPEC \
"%{!shared: \
- %{pg:/usr/lib/gcrt1.o%s} %{!pg:%{p:/usr/lib/gcrt1.o%s} %{!p:/usr/lib/crt1.o%s}}}\
- /usr/lib/crti.o%s %{static:crtbeginT.o%s}\
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+ crti.o%s %{static:crtbeginT.o%s}\
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-#define STARTFILE_SPEC64 \
- "%{!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 %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#ifdef SPARC_BI_ARCH
-
-#if DEFAULT_ARCH32_P
-#define STARTFILE_SPEC "\
-%{m32:" STARTFILE_SPEC32 "} \
-%{m64:" STARTFILE_SPEC64 "} \
-%{!m32:%{!m64:" STARTFILE_SPEC32 "}}"
-#else
-#define STARTFILE_SPEC "\
-%{m32:" STARTFILE_SPEC32 "} \
-%{m64:" STARTFILE_SPEC64 "} \
-%{!m32:%{!m64:" STARTFILE_SPEC64 "}}"
-#endif
-
-#else
-
-#define STARTFILE_SPEC STARTFILE_SPEC64
-
-#endif
-
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
the GNU/Linux magical crtend.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
@@ -96,36 +70,9 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
-#define ENDFILE_SPEC32 \
- "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib/crtn.o%s"
-
-#define ENDFILE_SPEC64 \
- "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s"
-
-#define ENDFILE_SPEC_COMMON \
- "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
-
-#ifdef SPARC_BI_ARCH
-
-#if DEFAULT_ARCH32_P
-#define ENDFILE_SPEC "\
-%{m32:" ENDFILE_SPEC32 "} \
-%{m64:" ENDFILE_SPEC64 "} \
-%{!m32:%{!m64:" ENDFILE_SPEC32 "}} " \
-ENDFILE_SPEC_COMMON
-#else
-#define ENDFILE_SPEC "\
-%{m32:" ENDFILE_SPEC32 "} \
-%{m64:" ENDFILE_SPEC64 "} \
-%{!m32:%{!m64:" ENDFILE_SPEC64 "}} " \
-ENDFILE_SPEC_COMMON
-#endif
-
-#else
-
-#define ENDFILE_SPEC ENDFILE_SPEC64 " " ENDFILE_SPEC_COMMON
-
-#endif
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s\
+ %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
/* The GNU C++ standard library requires that these macros be defined. */
#undef CPLUSPLUS_CPP_SPEC
diff --git a/contrib/gcc/config/sparc/sol2-bi.h b/contrib/gcc/config/sparc/sol2-bi.h
index 9828d634c915..e19e88810736 100644
--- a/contrib/gcc/config/sparc/sol2-bi.h
+++ b/contrib/gcc/config/sparc/sol2-bi.h
@@ -72,30 +72,6 @@
%{!mcpu*:%(asm_cpu_default)} \
"
-#define STARTFILE_SPEC32 "\
-%{ansi:values-Xc.o%s} \
-%{!ansi: \
- %{traditional:values-Xt.o%s} \
- %{!traditional:values-Xa.o%s}}"
-
-#define STARTFILE_SPEC64 "\
-%{ansi:/usr/lib/sparcv9/values-Xc.o%s} \
-%{!ansi: \
- %{traditional:/usr/lib/sparcv9/values-Xt.o%s} \
- %{!traditional:/usr/lib/sparcv9/values-Xa.o%s}}"
-
-#if DEFAULT_ARCH32_P
-#define STARTFILE_ARCH_SPEC "\
-%{m32:" STARTFILE_SPEC32 "} \
-%{m64:" STARTFILE_SPEC64 "} \
-%{!m32:%{!m64:" STARTFILE_SPEC32 "}}"
-#else
-#define STARTFILE_ARCH_SPEC "\
-%{m32:" STARTFILE_SPEC32 "} \
-%{m64:" STARTFILE_SPEC64 "} \
-%{!m32:%{!m64:" STARTFILE_SPEC64 "}}"
-#endif
-
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared: \
%{!symbolic: \
@@ -103,7 +79,10 @@
%{!p: \
%{pg:gcrt1.o%s gmon.o%s} \
%{!pg:crt1.o%s}}}} \
- crti.o%s " STARTFILE_ARCH_SPEC " \
+ crti.o%s \
+ %{ansi:values-Xc.o%s} \
+ %{!ansi: %{traditional:values-Xt.o%s} \
+ %{!traditional:values-Xa.o%s}} \
crtbegin.o%s"
#undef CPP_CPU_DEFAULT_SPEC
diff --git a/contrib/gcc/config/sparc/sparc.c b/contrib/gcc/config/sparc/sparc.c
index 6ef28141ce40..c23cbef1be52 100644
--- a/contrib/gcc/config/sparc/sparc.c
+++ b/contrib/gcc/config/sparc/sparc.c
@@ -8650,7 +8650,6 @@ set_extends (insn)
return INTVAL (op1) >= 0;
return (GET_CODE (op1) == REG && sparc_check_64 (op1, insn) == 1);
}
- case ASHIFT:
case LSHIFTRT:
return GET_MODE (SET_SRC (pat)) == SImode;
/* Positive integers leave the high bits zero. */
diff --git a/contrib/gcc/config/sparc/sparc.md b/contrib/gcc/config/sparc/sparc.md
index ebb6768ef88b..746dc72c7ea3 100644
--- a/contrib/gcc/config/sparc/sparc.md
+++ b/contrib/gcc/config/sparc/sparc.md
@@ -2517,7 +2517,7 @@
;
}")
-;; Be careful, fmovd does not exist when !arch64.
+;; Be careful, fmovd does not exist when !v9.
;; We match MEM moves directly when we have correct even
;; numbered registers, but fall into splits otherwise.
;; The constraint ordering here is really important to
@@ -2531,9 +2531,9 @@
(define_insn "*movdi_insn_sp32_v9"
[(set (match_operand:DI 0 "nonimmediate_operand"
- "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
+ "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f,?e,?e,?W")
(match_operand:DI 1 "input_operand"
- " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
+ " J,J,U,T,r,o,i,r, f, T, o, f, f, e, W, e"))]
"! TARGET_ARCH64 && TARGET_V9
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
@@ -2549,9 +2549,13 @@
ldd\\t%1, %0
#
#
- #"
- [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
- (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
+ #
+ fmovd\\t%1, %0
+ ldd\\t%1, %0
+ std\\t%1, %0"
+ [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*,fpmove,fpload,fpstore")
+ (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2,*,*,*")
+ (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
(define_insn "*movdi_insn_sp32"
[(set (match_operand:DI 0 "nonimmediate_operand"
@@ -2861,7 +2865,14 @@
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
- "! TARGET_ARCH64 && reload_completed"
+ "reload_completed
+ && (! TARGET_V9
+ || (! TARGET_ARCH64
+ && ((GET_CODE (operands[0]) == REG
+ && REGNO (operands[0]) < 32)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) < 32))))"
[(clobber (const_int 0))]
"
{
diff --git a/contrib/gcc/config/sparc/t-linux64 b/contrib/gcc/config/sparc/t-linux64
index a64862638355..3e3fa4cae7e6 100644
--- a/contrib/gcc/config/sparc/t-linux64
+++ b/contrib/gcc/config/sparc/t-linux64
@@ -1,8 +1,6 @@
-MULTILIB_OPTIONS = m64/m32 mno-app-regs|mcmodel=medany
-MULTILIB_DIRNAMES = 64 32 alt
-MULTILIB_MATCHES = mcmodel?medany=mcmodel?medmid
-MULTILIB_EXCEPTIONS = m32/mno-app-regs* m32/mcmodel=*
-MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany
+MULTILIB_OPTIONS = m64/m32
+MULTILIB_DIRNAMES = 64 32
+MULTILIB_OSDIRNAMES = ../lib64 ../lib
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
@@ -10,10 +8,12 @@ INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
crtfastmath.o
-SHLIB_SLIBDIR_SUFFIXES = 64:64 32:
-
# Override t-slibgcc-elf-ver to export some libgcc symbols with
# the symbol versions that glibc used.
# Avoid the t-linux version file.
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
$(srcdir)/config/sparc/libgcc-sparc-glibc.ver
+
+CRTSTUFF_T_CFLAGS = `if test x$$($(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) \
+ -print-multi-os-directory) \
+ = x../lib64; then echo -mcmodel=medany; fi`
diff --git a/contrib/gcc/config/sparc/t-sol2-64 b/contrib/gcc/config/sparc/t-sol2-64
index 39204d7368fe..3c15f0a712a1 100644
--- a/contrib/gcc/config/sparc/t-sol2-64
+++ b/contrib/gcc/config/sparc/t-sol2-64
@@ -1,11 +1,10 @@
MULTILIB_OPTIONS = m32/m64
MULTILIB_DIRNAMES = sparcv7 sparcv9
MULTILIB_MATCHES =
+MULTILIB_OSDIRNAMES = . sparcv9
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o \
crtfastmath.o
-
-SHLIB_SLIBDIR_SUFFIXES = sparcv9:/sparcv9 sparcv7:
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog
index f75f91f072d4..cc84a035c0a6 100644
--- a/contrib/gcc/cp/ChangeLog
+++ b/contrib/gcc/cp/ChangeLog
@@ -1,3 +1,54 @@
+2002-10-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353
+ * decl.c (start_decl): Unconditionally issue error for
+ 'typedef foo = bar'.
+ (cp_finish_decl): Remove special case for TYPE_DECL with initializer.
+ (grokdeclarator): Remove redundant error for 'typedef foo = bar'.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * decl2.c: Complete reversion of c++/7754.
+
+2002-10-06 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6627
+ * cp/cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition
+ from here, and move it to tree.h.
+ * cp/decl.c (cxx_init_decl_processing): If storing the vbit
+ in function pointers, ensure that force_align_functions_log
+ is atleast one.
+
+2002-10-04 H.J. Lu (hjl@gnu.org)
+
+ * pt.c (tsubst_decl, case VAR_DECL): Back out the last change.
+ (tsubst_expr, case DECL_STMT): Likewise.
+
+2002-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7188.
+ * init.c (expand_member_init): Allow a FIELD_DECL to be passed in
+ directly.
+ * pt.c (tsubst_initializer_list): Use expand_member_init.
+
2002-09-04 Jakub Jelinek <jakub@redhat.com>
* decl.c (start_cleanup_fn): Clear interface_only before
@@ -336,7 +387,7 @@
2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5719
- * decl.c (grok_op_properties): Assignment ops don't have to return
+ * decl.c (grok_op_properties): Assignment ops don't have to return
by value. operator% should.
2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
@@ -420,7 +471,7 @@
(finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
* semantics.c (begin_gobal_stmt_expr): Adjust call to
expand_start_stmt_expr.
-
+
2002-04-15 Mark Mitchell <mark@codesourcery.com>
* decl.c (register_dtor_fn): Pass the address of dso_handle, not
@@ -449,11 +500,11 @@
* typeck.c (type_after_usual_arithmetic_conversions):
If two types have the same variant, return immediately.
- When two floating-point operands are the same precision:
+ When two floating-point operands are the same precision:
convert to float if one of the operands is float;
if neither operand is one of the standard types, return the type
of the first operand.
-
+
2002-04-12 Richard Sandiford <rsandifo@redhat.com>
* decl.c (duplicate_decls): Don't try to unify an implicit typedef
@@ -511,7 +562,7 @@
set before checking it.
PR c++/6179
- * method.c (implicitly_declare_fn): Pass unqualified type to
+ * method.c (implicitly_declare_fn): Pass unqualified type to
synthesize_exception_spec.
2002-04-03 Jason Merrill <jason@redhat.com>
@@ -576,7 +627,7 @@
PR c++/4884
* call.c (build_op_delete_call): Allow for the fact the placement
may be a COMPOUND_EXPR.
-
+
2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5682
@@ -630,7 +681,7 @@
2002-03-18 Ashif Harji <asharji@uwaterloo.ca>
- * lang-specs.h (compiler default_compilers): Add
+ * lang-specs.h (compiler default_compilers): Add
-no-integrated-cpp flag to invoke an external cpp.
2002-03-18 Jason Merrill <jason@redhat.com>
@@ -747,7 +798,7 @@
with pointer to member conversions.
2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
+
* cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
conditional return void.
@@ -781,7 +832,7 @@
* decl.c (finish_function): Only warn about missing return
statement with -Wreturn-type.
-2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
+2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
PR c++/4093
* cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
@@ -835,7 +886,7 @@
2002-02-19 Jason Merrill <jason@redhat.com>
- ABI change: Mangle `void (A::*)() const' as
+ ABI change: Mangle `void (A::*)() const' as
M1AKFvvE, not MK1AFvvE.
* mangle.c (write_function_type): Write cv-quals for member
function type here.
@@ -910,14 +961,14 @@
(coerce_template_template_parms, convert_template_argument,
coerce_template_parms, maybe_get_template_decl_from_type_decl,
lookup_template_class, tsubst_friend_function, tsubst_friend_class,
- instantiate_class_template, tsubst_template_arg_vector,
- tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
+ instantiate_class_template, tsubst_template_arg_vector,
+ tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
tsubst_decl, tsubst_arg_types, tsubst_function_type,
- tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
+ tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
instantiate_template, fn_type_unification,
- resolve_overloaded_unification, verify_class_unification,
- unify, get_bindings_real, do_type_instantiation,
- regenerate_decl_from_template, instantiate_decl,
+ resolve_overloaded_unification, verify_class_unification,
+ unify, get_bindings_real, do_type_instantiation,
+ regenerate_decl_from_template, instantiate_decl,
tsubst_initializer_list, tsubst_enum,
get_mostly_instantiated_function_type,
invalid_nontype_parm_type_p): Likewise.
@@ -978,7 +1029,7 @@
2002-02-01 Jason Merrill <jason@redhat.com>
PR c++/4872
- * decl.c (finish_function): Warn about a non-void function with
+ * decl.c (finish_function): Warn about a non-void function with
no return statement and no abnormal exit.
* cp-tree.h (struct cp_language_function): Add returns_abnormally.
(current_function_returns_abnormally): New macro.
diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h
index 787114f492b4..4bd08799e6fd 100644
--- a/contrib/gcc/cp/cp-tree.h
+++ b/contrib/gcc/cp/cp-tree.h
@@ -2557,32 +2557,6 @@ extern int flag_new_for_scope;
member function. [expr.unary.op]/3 */
#define PTRMEM_OK_P(NODE) TREE_LANG_FLAG_0 (NODE)
-/* A pointer-to-function member type looks like:
-
- struct {
- __P __pfn;
- ptrdiff_t __delta;
- };
-
- If __pfn is NULL, it is a NULL pointer-to-member-function.
-
- (Because the vtable is always the first thing in the object, we
- don't need its offset.) If the function is virtual, then PFN is
- one plus twice the index into the vtable; otherwise, it is just a
- pointer to the function.
-
- Unfortunately, using the lowest bit of PFN doesn't work in
- architectures that don't impose alignment requirements on function
- addresses, or that use the lowest bit to tell one ISA from another,
- for example. For such architectures, we use the lowest bit of
- DELTA instead of the lowest bit of the PFN, and DELTA will be
- multiplied by 2. */
-enum ptrmemfunc_vbit_where_t
-{
- ptrmemfunc_vbit_in_pfn,
- ptrmemfunc_vbit_in_delta
-};
-
/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
before using this macro. */
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c
index 105e7a0d0d57..26484d72ef17 100644
--- a/contrib/gcc/cp/decl.c
+++ b/contrib/gcc/cp/decl.c
@@ -6517,6 +6517,12 @@ cxx_init_decl_processing ()
flag_inline_functions = 0;
}
+ /* Force minimum function alignment if using the least significant
+ bit of function pointers to store the virtual bit. */
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+ && force_align_functions_log < 1)
+ force_align_functions_log = 1;
+
/* Initially, C. */
current_lang_name = lang_name_c;
@@ -7322,14 +7328,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
switch (TREE_CODE (decl))
{
case TYPE_DECL:
- /* typedef foo = bar means give foo the same type as bar.
- We haven't parsed bar yet, so `cp_finish_decl' will fix that up.
- Any other case of an initialization in a TYPE_DECL is an error. */
- if (pedantic || list_length (declspecs) > 1)
- {
- error ("typedef `%D' is initialized", decl);
- initialized = 0;
- }
+ error ("typedef `%D' is initialized", decl);
+ initialized = 0;
break;
case FUNCTION_DECL:
@@ -8241,12 +8241,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
/* Take care of TYPE_DECLs up front. */
if (TREE_CODE (decl) == TYPE_DECL)
{
- if (init && DECL_INITIAL (decl))
- {
- /* typedef foo = bar; store the type of bar as the type of foo. */
- TREE_TYPE (decl) = type = TREE_TYPE (init);
- DECL_INITIAL (decl) = init = NULL_TREE;
- }
if (type != error_mark_node
&& IS_AGGR_TYPE (type) && DECL_NAME (decl))
{
@@ -11345,9 +11339,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE);
- if (initialized)
- error ("typedef declaration includes an initializer");
-
return decl;
}
diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c
index 0eb47994b20a..43349631b4de 100644
--- a/contrib/gcc/cp/decl2.c
+++ b/contrib/gcc/cp/decl2.c
@@ -1975,26 +1975,31 @@ finish_anon_union (anon_union_decl)
return;
}
- main_decl = build_anon_union_vars (anon_union_decl,
- &DECL_ANON_UNION_ELEMS (anon_union_decl),
- static_p, external_p);
-
- if (main_decl == NULL_TREE)
+ if (!processing_template_decl)
{
- warning ("anonymous aggregate with no members");
- return;
- }
+ main_decl
+ = build_anon_union_vars (anon_union_decl,
+ &DECL_ANON_UNION_ELEMS (anon_union_decl),
+ static_p, external_p);
+
+ if (main_decl == NULL_TREE)
+ {
+ warning ("anonymous aggregate with no members");
+ return;
+ }
- if (static_p)
- {
- make_decl_rtl (main_decl, 0);
- COPY_DECL_RTL (main_decl, anon_union_decl);
- expand_anon_union_decl (anon_union_decl,
- NULL_TREE,
- DECL_ANON_UNION_ELEMS (anon_union_decl));
+ if (static_p)
+ {
+ make_decl_rtl (main_decl, 0);
+ COPY_DECL_RTL (main_decl, anon_union_decl);
+ expand_anon_union_decl (anon_union_decl,
+ NULL_TREE,
+ DECL_ANON_UNION_ELEMS (anon_union_decl));
+ return;
+ }
}
- else
- add_decl_stmt (anon_union_decl);
+
+ add_decl_stmt (anon_union_decl);
}
/* Finish processing a builtin type TYPE. It's name is NAME,
diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c
index 369e511edd7f..a46d853efa42 100644
--- a/contrib/gcc/cp/init.c
+++ b/contrib/gcc/cp/init.c
@@ -1094,7 +1094,10 @@ expand_member_init (exp, name, init)
}
else
{
- field = lookup_field (type, name, 1, 0);
+ if (TREE_CODE (name) == IDENTIFIER_NODE)
+ field = lookup_field (type, name, 1, 0);
+ else
+ field = name;
if (! member_init_ok_or_else (field, type, name))
return NULL_TREE;
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c
index 2180e4be2968..8fc9f743e1e0 100644
--- a/contrib/gcc/cp/pt.c
+++ b/contrib/gcc/cp/pt.c
@@ -6079,6 +6079,8 @@ tsubst_decl (t, args, type, complain)
}
r = copy_decl (t);
+ if (TREE_CODE (r) == VAR_DECL)
+ type = complete_type (type);
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
DECL_CONTEXT (r) = ctx;
@@ -6115,6 +6117,8 @@ tsubst_decl (t, args, type, complain)
TREE_CHAIN (r) = NULL_TREE;
if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
cp_error_at ("instantiation of `%D' as type `%T'", r, type);
+ /* Compute the size, alignment, etc. of R. */
+ layout_decl (r, 0);
}
break;
@@ -7374,9 +7378,6 @@ tsubst_expr (t, args, complain, in_decl)
decl = tsubst (decl, args, complain, in_decl);
if (decl != error_mark_node)
{
- if (TREE_CODE (decl) != TYPE_DECL)
- /* Make sure the type is instantiated now. */
- complete_type (TREE_TYPE (decl));
if (init)
DECL_INITIAL (decl) = error_mark_node;
/* By marking the declaration as instantiated, we avoid
@@ -7386,19 +7387,26 @@ tsubst_expr (t, args, complain, in_decl)
do. */
if (TREE_CODE (decl) == VAR_DECL)
DECL_TEMPLATE_INSTANTIATED (decl) = 1;
- maybe_push_decl (decl);
- if (DECL_PRETTY_FUNCTION_P (decl))
+ if (TREE_CODE (decl) == VAR_DECL
+ && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
+ /* Anonymous aggregates are a special case. */
+ finish_anon_union (decl);
+ else
{
- /* For __PRETTY_FUNCTION__ we have to adjust the
- initializer. */
- const char *const name
- = (*decl_printable_name) (current_function_decl, 2);
- init = cp_fname_init (name);
- TREE_TYPE (decl) = TREE_TYPE (init);
+ maybe_push_decl (decl);
+ if (DECL_PRETTY_FUNCTION_P (decl))
+ {
+ /* For __PRETTY_FUNCTION__ we have to adjust the
+ initializer. */
+ const char *const name
+ = (*decl_printable_name) (current_function_decl, 2);
+ init = cp_fname_init (name);
+ TREE_TYPE (decl) = TREE_TYPE (init);
+ }
+ else
+ init = tsubst_expr (init, args, complain, in_decl);
+ cp_finish_decl (decl, init, NULL_TREE, 0);
}
- else
- init = tsubst_expr (init, args, complain, in_decl);
- cp_finish_decl (decl, init, NULL_TREE, 0);
}
}
@@ -10274,8 +10282,10 @@ tsubst_initializer_list (t, argvec)
else
init = convert_from_reference (init);
- *p = build_tree_list (decl, init);
- p = &TREE_CHAIN (*p);
+ *p = expand_member_init (current_class_ref, decl,
+ init ? init : void_type_node);
+ if (*p)
+ p = &TREE_CHAIN (*p);
}
return first;
}
diff --git a/contrib/gcc/cppinit.c b/contrib/gcc/cppinit.c
index adaa30f55c18..c7d50412f6ca 100644
--- a/contrib/gcc/cppinit.c
+++ b/contrib/gcc/cppinit.c
@@ -103,9 +103,13 @@ static void mark_named_operators PARAMS ((cpp_reader *));
static void append_include_chain PARAMS ((cpp_reader *,
char *, int, int));
static struct search_path * remove_dup_dir PARAMS ((cpp_reader *,
+ struct search_path *,
+ struct search_path **));
+static struct search_path * remove_dup_nonsys_dirs PARAMS ((cpp_reader *,
+ struct search_path **,
struct search_path *));
static struct search_path * remove_dup_dirs PARAMS ((cpp_reader *,
- struct search_path *));
+ struct search_path **));
static void merge_include_chains PARAMS ((cpp_reader *));
static bool push_include PARAMS ((cpp_reader *,
struct pending_option *));
@@ -272,55 +276,98 @@ append_include_chain (pfile, dir, path, cxx_aware)
}
/* Handle a duplicated include path. PREV is the link in the chain
- before the duplicate. The duplicate is removed from the chain and
- freed. Returns PREV. */
+ before the duplicate, or NULL if the duplicate is at the head of
+ the chain. The duplicate is removed from the chain and freed.
+ Returns PREV. */
static struct search_path *
-remove_dup_dir (pfile, prev)
+remove_dup_dir (pfile, prev, head_ptr)
cpp_reader *pfile;
struct search_path *prev;
+ struct search_path **head_ptr;
{
- struct search_path *cur = prev->next;
+ struct search_path *cur;
+
+ if (prev != NULL)
+ {
+ cur = prev->next;
+ prev->next = cur->next;
+ }
+ else
+ {
+ cur = *head_ptr;
+ *head_ptr = cur->next;
+ }
if (CPP_OPTION (pfile, verbose))
fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name);
- prev->next = cur->next;
free ((PTR) cur->name);
free (cur);
return prev;
}
+/* Remove duplicate non-system directories for which there is an equivalent
+ system directory later in the chain. The range for removal is between
+ *HEAD_PTR and END. Returns the directory before END, or NULL if none.
+ This algorithm is quadratic in the number of system directories, which is
+ acceptable since there aren't usually that many of them. */
+static struct search_path *
+remove_dup_nonsys_dirs (pfile, head_ptr, end)
+ cpp_reader *pfile;
+ struct search_path **head_ptr;
+ struct search_path *end;
+{
+ int sysdir = 0;
+ struct search_path *prev = NULL, *cur, *other;
+
+ for (cur = *head_ptr; cur; cur = cur->next)
+ {
+ if (cur->sysp)
+ {
+ sysdir = 1;
+ for (other = *head_ptr, prev = NULL;
+ other != end;
+ other = other ? other->next : *head_ptr)
+ {
+ if (!other->sysp
+ && INO_T_EQ (cur->ino, other->ino)
+ && cur->dev == other->dev)
+ {
+ other = remove_dup_dir (pfile, prev, head_ptr);
+ if (CPP_OPTION (pfile, verbose))
+ fprintf (stderr,
+ _(" as it is a non-system directory that duplicates a system directory\n"));
+ }
+ prev = other;
+ }
+ }
+ }
+
+ if (!sysdir)
+ for (cur = *head_ptr; cur != end; cur = cur->next)
+ prev = cur;
+
+ return prev;
+}
+
/* Remove duplicate directories from a chain. Returns the tail of the
chain, or NULL if the chain is empty. This algorithm is quadratic
in the number of -I switches, which is acceptable since there
aren't usually that many of them. */
static struct search_path *
-remove_dup_dirs (pfile, head)
+remove_dup_dirs (pfile, head_ptr)
cpp_reader *pfile;
- struct search_path *head;
+ struct search_path **head_ptr;
{
struct search_path *prev = NULL, *cur, *other;
- for (cur = head; cur; cur = cur->next)
+ for (cur = *head_ptr; cur; cur = cur->next)
{
- for (other = head; other != cur; other = other->next)
+ for (other = *head_ptr; other != cur; other = other->next)
if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev)
{
- if (cur->sysp && !other->sysp)
- {
- cpp_warning (pfile,
- "changing search order for system directory \"%s\"",
- cur->name);
- if (strcmp (cur->name, other->name))
- cpp_warning (pfile,
- " as it is the same as non-system directory \"%s\"",
- other->name);
- else
- cpp_warning (pfile,
- " as it has already been specified as a non-system directory");
- }
- cur = remove_dup_dir (pfile, prev);
+ cur = remove_dup_dir (pfile, prev, head_ptr);
break;
}
prev = cur;
@@ -358,28 +405,33 @@ merge_include_chains (pfile)
else
brack = systm;
- /* This is a bit tricky. First we drop dupes from the quote-include
- list. Then we drop dupes from the bracket-include list.
- Finally, if qtail and brack are the same directory, we cut out
- brack and move brack up to point to qtail.
+ /* This is a bit tricky. First we drop non-system dupes of system
+ directories from the merged bracket-include list. Next we drop
+ dupes from the bracket and quote include lists. Then we drop
+ non-system dupes from the merged quote-include list. Finally,
+ if qtail and brack are the same directory, we cut out brack and
+ move brack up to point to qtail.
We can't just merge the lists and then uniquify them because
then we may lose directories from the <> search path that should
- be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
+ be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
-Ibar -I- -Ifoo -Iquux. */
- remove_dup_dirs (pfile, brack);
- qtail = remove_dup_dirs (pfile, quote);
+ remove_dup_nonsys_dirs (pfile, &brack, systm);
+ remove_dup_dirs (pfile, &brack);
if (quote)
{
+ qtail = remove_dup_dirs (pfile, &quote);
qtail->next = brack;
+ qtail = remove_dup_nonsys_dirs (pfile, &quote, brack);
+
/* If brack == qtail, remove brack as it's simpler. */
- if (brack && INO_T_EQ (qtail->ino, brack->ino)
+ if (qtail && brack && INO_T_EQ (qtail->ino, brack->ino)
&& qtail->dev == brack->dev)
- brack = remove_dup_dir (pfile, qtail);
+ brack = remove_dup_dir (pfile, qtail, &quote);
}
else
quote = brack;
@@ -848,7 +900,7 @@ init_standard_includes (pfile)
&& !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
{
/* Does this dir start with the prefix? */
- if (!memcmp (p->fname, default_prefix, default_len))
+ if (!strncmp (p->fname, default_prefix, default_len))
{
/* Yes; change prefix and add to search list. */
int flen = strlen (p->fname);
@@ -1296,7 +1348,7 @@ parse_option (input)
md = (mn + mx) / 2;
opt_len = cl_options[md].opt_len;
- comp = memcmp (input, cl_options[md].opt_text, opt_len);
+ comp = strncmp (input, cl_options[md].opt_text, opt_len);
if (comp > 0)
mn = md + 1;
@@ -1321,7 +1373,7 @@ parse_option (input)
for (; mn < (unsigned int) N_OPTS; mn++)
{
opt_len = cl_options[mn].opt_len;
- if (memcmp (input, cl_options[mn].opt_text, opt_len))
+ if (strncmp (input, cl_options[mn].opt_text, opt_len))
break;
if (input[opt_len] == '\0')
return mn;
diff --git a/contrib/gcc/cpplib.c b/contrib/gcc/cpplib.c
index 096a7113960f..cff9eeb04286 100644
--- a/contrib/gcc/cpplib.c
+++ b/contrib/gcc/cpplib.c
@@ -1224,6 +1224,9 @@ destringize_and_run (pfile, in)
{
const unsigned char *src, *limit;
char *dest, *result;
+ cpp_context saved_context;
+ cpp_context *saved_cur_context;
+ unsigned int saved_line;
dest = result = alloca (in->len + 1);
for (src = in->text, limit = src + in->len; src < limit;)
@@ -1235,7 +1238,40 @@ destringize_and_run (pfile, in)
}
*dest = '\0';
+ /* FIXME. All this saving is a horrible kludge to handle the case
+ when we're in a macro expansion.
+
+ A better strategy it to not convert _Pragma to #pragma if doing
+ preprocessed output, but to just pass it through as-is, unless it
+ is a CPP pragma in which case is should be processed normally.
+ When compiling the preprocessed output the _Pragma should be
+ handled. This will be become necessary when we move to
+ line-at-a-time lexing since we will be macro-expanding the line
+ before outputting / compiling it. */
+ saved_line = pfile->line;
+ saved_context = pfile->base_context;
+ saved_cur_context = pfile->context;
+ pfile->context = &pfile->base_context;
run_directive (pfile, T_PRAGMA, result, dest - result);
+ pfile->context = saved_cur_context;
+ pfile->base_context = saved_context;
+ pfile->line = saved_line;
+
+ /* See above comment. For the moment, we'd like
+
+ token1 _Pragma ("foo") token2
+
+ to be output as
+
+ token1
+ # 7 "file.c"
+ #pragma foo
+ # 7 "file.c"
+ token2
+
+ Getting the line markers is a little tricky. */
+ if (pfile->cb.line_change)
+ (*pfile->cb.line_change) (pfile, pfile->cur_token, false);
}
/* Handle the _Pragma operator. */
@@ -1245,25 +1281,10 @@ _cpp_do__Pragma (pfile)
{
const cpp_token *string = get__Pragma_string (pfile);
- if (!string)
- cpp_error (pfile, "_Pragma takes a parenthesized string literal");
+ if (string)
+ destringize_and_run (pfile, &string->val.str);
else
- {
- /* Ideally, we'd like
- token1 _Pragma ("foo") token2
- to be output as
- token1
- # 7 "file.c"
- #pragma foo
- # 7 "file.c"
- token2
- Getting these correct line markers is a little tricky. */
-
- unsigned int orig_line = pfile->line;
- destringize_and_run (pfile, &string->val.str);
- pfile->line = orig_line;
- pfile->buffer->saved_flags = BOL;
- }
+ cpp_error (pfile, "_Pragma takes a parenthesized string literal");
}
/* Just ignore #sccs, on systems where we define it at all. */
diff --git a/contrib/gcc/cppmacro.c b/contrib/gcc/cppmacro.c
index c85ac21cce14..70e52fda6e86 100644
--- a/contrib/gcc/cppmacro.c
+++ b/contrib/gcc/cppmacro.c
@@ -348,6 +348,12 @@ stringify_arg (pfile, arg)
}
/* Commit the memory, including NUL, and return the token. */
+ if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < 1)
+ {
+ size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+ _cpp_extend_buff (pfile, &pfile->u_buff, 1);
+ dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
+ }
len = dest - BUFF_FRONT (pfile->u_buff);
BUFF_FRONT (pfile->u_buff) = dest + 1;
return new_string_token (pfile, dest - len, len);
diff --git a/contrib/gcc/doc/cpp.texi b/contrib/gcc/doc/cpp.texi
index 8e829d8c9a61..39e6a2876282 100644
--- a/contrib/gcc/doc/cpp.texi
+++ b/contrib/gcc/doc/cpp.texi
@@ -830,11 +830,22 @@ version of GCC in use.
You can add to this list with the @option{-I@var{dir}} command line
option. All the directories named by @option{-I} are searched, in
-left-to-right order, @emph{before} the default directories. You can
-also prevent GCC from searching any of the default directories with the
-@option{-nostdinc} option. This is useful when you are compiling an
+left-to-right order, @emph{before} the default directories. The only
+exception is when @file{dir} is already searched by default. In
+this case, the option is ignored and the search order for system
+directories remains unchanged.
+
+Duplicate directories are removed from the quote and bracket search
+chains before the two chains are merged to make the final search chain.
+Thus, it is possible for a directory to occur twice in the final search
+chain if it was specified in both the quote and bracket chains.
+
+You can prevent GCC from searching any of the default directories with
+the @option{-nostdinc} option. This is useful when you are compiling an
operating system kernel or some other program that does not use the
standard C library facilities, or the standard C library itself.
+@option{-I} options are not ignored as described above when
+@option{-nostdinc} is in effect.
GCC looks for headers requested with @code{@w{#include "@var{file}"}}
first in the directory containing the current file, then in the same
@@ -843,12 +854,6 @@ For example, if @file{/usr/include/sys/stat.h} contains
@code{@w{#include "types.h"}}, GCC looks for @file{types.h} first in
@file{/usr/include/sys}, then in its usual search path.
-If you name a search directory with @option{-I@var{dir}} that is also a
-system include directory, the @option{-I} wins; the directory will be
-searched according to the @option{-I} ordering, and it will not be
-treated as a system include directory. GCC will warn you when a system
-include directory is hidden in this way.
-
@samp{#line} (@pxref{Line Control}) does not change GCC's idea of the
directory containing the current file.
@@ -1081,8 +1086,8 @@ found in that directory will be considered system headers.
All directories named by @option{-isystem} are searched @emph{after} all
directories named by @option{-I}, no matter what their order was on the
command line. If the same directory is named by both @option{-I} and
-@option{-isystem}, @option{-I} wins; it is as if the @option{-isystem} option
-had never been specified at all. GCC warns you when this happens.
+@option{-isystem}, the @option{-I} option is ignored. GCC provides an
+informative message when this occurs if @option{-v} is used.
@findex #pragma GCC system_header
There is also a directive, @code{@w{#pragma GCC system_header}}, which
@@ -1815,9 +1820,7 @@ conformance to the C Standard. GNU CPP follows the host convention when
processing system header files, but when processing user files
@code{__STDC__} is always 1. This has been reported to cause problems;
for instance, some versions of Solaris provide X Windows headers that
-expect @code{__STDC__} to be either undefined or 1. You may be able to
-work around this sort of problem by using an @option{-I} option to
-cancel treatment of those headers as system headers. @xref{Invocation}.
+expect @code{__STDC__} to be either undefined or 1. @xref{Invocation}.
@item __STDC_VERSION__
This macro expands to the C Standard's version number, a long integer
@@ -3733,9 +3736,9 @@ Here are a few more obsolete features.
@item Attempting to paste two tokens which together do not form a valid
preprocessing token.
-The preprocessor currently warns about this and outputs the two tokens
-adjacently, which is probably the behavior the programmer intends. It
-may not work in future, though.
+The preprocessor currently warns about this, and the resulting
+preprocessed output is undefined. The tokens remain distinct if the
+preprocessor is being used directly by the compiler front end.
Most of the time, when you get this warning, you will find that @samp{##}
is being used superstitiously, to guard against whitespace appearing
diff --git a/contrib/gcc/doc/extend.texi b/contrib/gcc/doc/extend.texi
index 79eea7090a38..281e4ac932e1 100644
--- a/contrib/gcc/doc/extend.texi
+++ b/contrib/gcc/doc/extend.texi
@@ -385,7 +385,6 @@ extensions, accepted by GCC in C89 mode and in C++.
* Labels as Values:: Getting pointers to labels, and computed gotos.
* Nested Functions:: As in Algol and Pascal, lexical scoping of functions.
* Constructing Calls:: Dispatching a call to another function.
-* Naming Types:: Giving a name to the type of some expression.
* Typeof:: @code{typeof}: referring to the type of an expression.
* Lvalues:: Using @samp{?:}, @samp{,} and casts in lvalues.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression.
@@ -495,8 +494,7 @@ the value of an enumeration constant, the width of a bit-field, or
the initial value of a static variable.
If you don't know the type of the operand, you can still do this, but you
-must use @code{typeof} (@pxref{Typeof}) or type naming (@pxref{Naming
-Types}).
+must use @code{typeof} (@pxref{Typeof}).
Statement expressions are not supported fully in G++, and their fate
there is unclear. (It is possible that they will become fully supported
@@ -845,29 +843,6 @@ the containing function. You should specify, for @var{result}, a value
returned by @code{__builtin_apply}.
@end deftypefn
-@node Naming Types
-@section Naming an Expression's Type
-@cindex naming types
-
-You can give a name to the type of an expression using a @code{typedef}
-declaration with an initializer. Here is how to define @var{name} as a
-type name for the type of @var{exp}:
-
-@example
-typedef @var{name} = @var{exp};
-@end example
-
-This is useful in conjunction with the statements-within-expressions
-feature. Here is how the two together can be used to define a safe
-``maximum'' macro that operates on any arithmetic type:
-
-@example
-#define max(a,b) \
- (@{typedef _ta = (a), _tb = (b); \
- _ta _a = (a); _tb _b = (b); \
- _a > _b ? _a : _b; @})
-@end example
-
@cindex underscores in variables in macros
@cindex @samp{_} in variables in macros
@cindex local variables in macros
@@ -919,6 +894,21 @@ A @code{typeof}-construct can be used anywhere a typedef name could be
used. For example, you can use it in a declaration, in a cast, or inside
of @code{sizeof} or @code{typeof}.
+@code{typeof} is often useful in conjunction with the
+statements-within-expressions feature. Here is how the two together can
+be used to define a safe ``maximum'' macro that operates on any
+arithmetic type and evaluates each of its arguments exactly once:
+
+@example
+#define max(a,b) \
+ (@{ typeof (a) _a = (a); \
+ typeof (b) _b = (b); \
+ _a > _b ? _a : _b; @})
+@end example
+
+@noindent
+Some more examples of the use of @code{typeof}:
+
@itemize @bullet
@item
This declares @code{y} with the type of what @code{x} points to.
@@ -968,6 +958,26 @@ Thus, @code{array (pointer (char), 4)} is the type of arrays of 4
pointers to @code{char}.
@end itemize
+@emph{Compatibility Note:} In addition to @code{typeof}, GCC 2 supported
+a more limited extension which permitted one to write
+
+@example
+typedef @var{T} = @var{expr};
+@end example
+
+@noindent
+with the effect of declaring @var{T} to have the type of the expression
+@var{expr}. This extension does not work with GCC 3 (versions between
+3.0 and 3.2 will crash; 3.2.1 and later give an error). Code which
+relies on it should be rewritten to use @code{typeof}:
+
+@example
+typedef typeof(@var{expr}) @var{T};
+@end example
+
+@noindent
+This will work with all versions of GCC@.
+
@node Lvalues
@section Generalized Lvalues
@cindex compound expressions as lvalues
@@ -6170,12 +6180,12 @@ the minimum value of variables @var{i} and @var{j}.
However, side effects in @code{X} or @code{Y} may cause unintended
behavior. For example, @code{MIN (i++, j++)} will fail, incrementing
-the smaller counter twice. A GNU C extension allows you to write safe
-macros that avoid this kind of problem (@pxref{Naming Types,,Naming an
-Expression's Type}). However, writing @code{MIN} and @code{MAX} as
-macros also forces you to use function-call notation for a
-fundamental arithmetic operation. Using GNU C++ extensions, you can
-write @w{@samp{int min = i <? j;}} instead.
+the smaller counter twice. The GNU C @code{typeof} extension allows you
+to write safe macros that avoid this kind of problem (@pxref{Typeof}).
+However, writing @code{MIN} and @code{MAX} as macros also forces you to
+use function-call notation for a fundamental arithmetic operation.
+Using GNU C++ extensions, you can write @w{@samp{int min = i <? j;}}
+instead.
Since @code{<?} and @code{>?} are built into the compiler, they properly
handle expressions with side-effects; @w{@samp{int min = i++ <? j++;}}
diff --git a/contrib/gcc/doc/invoke.texi b/contrib/gcc/doc/invoke.texi
index d60d6fcfa59a..a56e3ed577f8 100644
--- a/contrib/gcc/doc/invoke.texi
+++ b/contrib/gcc/doc/invoke.texi
@@ -222,7 +222,7 @@ in the following sections.
-Werror-implicit-function-declaration @gol
-Wimport -Winline @gol
-Wlarger-than-@var{len} -Wlong-long @gol
--Wmain -Wmissing-braces -Wmissing-declarations @gol
+-Wmain -Wmissing-braces @gol
-Wmissing-format-attribute -Wmissing-noreturn @gol
-Wmultichar -Wno-format-extra-args -Wno-format-y2k @gol
-Wno-import -Wpacked -Wpadded @gol
@@ -236,8 +236,8 @@ in the following sections.
@item C-only Warning Options
@gccoptlist{
--Wbad-function-cast -Wmissing-prototypes -Wnested-externs @gol
--Wstrict-prototypes -Wtraditional}
+-Wbad-function-cast -Wmissing-declarations -Wmissing-prototypes @gol
+-Wnested-externs -Wstrict-prototypes -Wtraditional}
@item Debugging Options
@xref{Debugging Options,,Options for Debugging Your Program or GCC}.
@@ -4246,15 +4246,13 @@ one @option{-I} option, the directories are scanned in left-to-right
order; the standard system directories come after.
If a standard system include directory, or a directory specified with
-@option{-isystem}, is also specified with @option{-I}, it will be
-searched only in the position requested by @option{-I}. Also, it will
-not be considered a system include directory. If that directory really
-does contain system headers, there is a good chance that they will
-break. For instance, if GCC's installation procedure edited the headers
-in @file{/usr/include} to fix bugs, @samp{-I/usr/include} will cause the
-original, buggy headers to be found instead of the corrected ones. GCC
-will issue a warning when a system include directory is hidden in this
-way.
+@option{-isystem}, is also specified with @option{-I}, the @option{-I}
+option will be ignored. The directory will still be searched but as a
+system directory at its normal position in the system include chain.
+This is to ensure that GCC's procedure to fix buggy system headers and
+the ordering for the include_next directive are not inadvertantly changed.
+If you really need to change the search order for system directories,
+use the @option{-nostdinc} and/or @option{-isystem} options.
@item -I-
@opindex I-
diff --git a/contrib/gcc/doloop.c b/contrib/gcc/doloop.c
index 6c0185cafd55..06d8d5734853 100644
--- a/contrib/gcc/doloop.c
+++ b/contrib/gcc/doloop.c
@@ -552,6 +552,7 @@ doloop_modify_runtime (loop, iterations_max,
{
const struct loop_info *loop_info = LOOP_INFO (loop);
HOST_WIDE_INT abs_inc;
+ HOST_WIDE_INT abs_loop_inc;
int neg_inc;
rtx diff;
rtx sequence;
@@ -591,13 +592,22 @@ doloop_modify_runtime (loop, iterations_max,
n = abs (final - initial) / abs_inc;
n += (abs (final - initial) % abs_inc) != 0;
- If the loop has been unrolled, then the loop body has been
- preconditioned to iterate a multiple of unroll_number times. If
- abs_inc is != 1, the full calculation is
+ But when abs_inc is a power of two, the summation won't overflow
+ except in cases where the loop never terminates. So we don't
+ need to use this more costly calculation.
- t1 = abs_inc * unroll_number;
- n = abs (final - initial) / t1;
- n += (abs (final - initial) % t1) > t1 - abs_inc;
+ If the loop has been unrolled, the full calculation is
+
+ t1 = abs_inc * unroll_number; increment per loop
+ n = abs (final - initial) / t1; full loops
+ n += (abs (final - initial) % t1) != 0; partial loop
+
+ However, in certain cases the unrolled loop will be preconditioned
+ by emitting copies of the loop body with conditional branches,
+ so that the unrolled loop is always a full loop and thus needs
+ no exit tests. In this case we don't want to add the partial
+ loop count. As above, when t1 is a power of two we don't need to
+ worry about overflow.
The division and modulo operations can be avoided by requiring
that the increment is a power of 2 (precondition_loop_p enforces
@@ -658,58 +668,32 @@ doloop_modify_runtime (loop, iterations_max,
fprintf (loop_dump_stream,
"Doloop: Basic induction var skips initial incr.\n");
- diff = expand_simple_binop (mode, PLUS, diff, increment, diff,
- unsigned_p, OPTAB_LIB_WIDEN);
+ diff = expand_simple_binop (mode, PLUS, diff, GEN_INT (abs_inc),
+ diff, unsigned_p, OPTAB_LIB_WIDEN);
}
}
- if (abs_inc * loop_info->unroll_number != 1)
+ abs_loop_inc = abs_inc * loop_info->unroll_number;
+ if (abs_loop_inc != 1)
{
int shift_count;
- rtx extra;
- rtx label;
- unsigned HOST_WIDE_INT limit;
- shift_count = exact_log2 (abs_inc * loop_info->unroll_number);
+ shift_count = exact_log2 (abs_loop_inc);
if (shift_count < 0)
abort ();
- /* abs (final - initial) / (abs_inc * unroll_number) */
- iterations = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
- diff, GEN_INT (shift_count),
- NULL_RTX, 1,
- OPTAB_LIB_WIDEN);
-
- if (abs_inc != 1)
- {
- /* abs (final - initial) % (abs_inc * unroll_number) */
- rtx count = GEN_INT (abs_inc * loop_info->unroll_number - 1);
- extra = expand_simple_binop (GET_MODE (iterations), AND,
- diff, count, NULL_RTX, 1,
- OPTAB_LIB_WIDEN);
-
- /* If (abs (final - initial) % (abs_inc * unroll_number)
- <= abs_inc * (unroll - 1)),
- jump past following increment instruction. */
- label = gen_label_rtx ();
- limit = abs_inc * (loop_info->unroll_number - 1);
- emit_cmp_and_jump_insns (extra, GEN_INT (limit),
- limit == 0 ? EQ : LEU, NULL_RTX,
- GET_MODE (extra), 0, label);
- JUMP_LABEL (get_last_insn ()) = label;
- LABEL_NUSES (label)++;
-
- /* Increment the iteration count by one. */
- iterations = expand_simple_binop (GET_MODE (iterations), PLUS,
- iterations, GEN_INT (1),
- iterations, 1,
- OPTAB_LIB_WIDEN);
+ if (!loop_info->preconditioned)
+ diff = expand_simple_binop (GET_MODE (diff), PLUS,
+ diff, GEN_INT (abs_loop_inc - 1),
+ diff, 1, OPTAB_LIB_WIDEN);
- emit_label (label);
- }
+ /* (abs (final - initial) + abs_inc * unroll_number - 1)
+ / (abs_inc * unroll_number) */
+ diff = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
+ diff, GEN_INT (shift_count),
+ diff, 1, OPTAB_LIB_WIDEN);
}
- else
- iterations = diff;
+ iterations = diff;
/* If there is a NOTE_INSN_LOOP_VTOP, we have a `for' or `while'
style loop, with a loop exit test at the start. Thus, we can
@@ -722,17 +706,20 @@ doloop_modify_runtime (loop, iterations_max,
iteration count to one if necessary. */
if (! loop->vtop)
{
- rtx label;
-
if (loop_dump_stream)
fprintf (loop_dump_stream, "Doloop: Do-while loop.\n");
- /* A `do-while' loop must iterate at least once. If the
- iteration count is bogus, we set the iteration count to 1.
+ /* A `do-while' loop must iterate at least once. For code like
+ i = initial; do { ... } while (++i < final);
+ we will calculate a bogus iteration count if initial > final.
+ So detect this and set the iteration count to 1.
Note that if the loop has been unrolled, then the loop body
- is guaranteed to execute at least once. */
- if (loop_info->unroll_number == 1)
+ is guaranteed to execute at least once. Also, when the
+ comparison is NE, our calculated count will be OK. */
+ if (loop_info->unroll_number == 1 && comparison_code != NE)
{
+ rtx label;
+
/* Emit insns to test if the loop will immediately
terminate and to set the iteration count to 1 if true. */
label = gen_label_rtx();
diff --git a/contrib/gcc/expr.c b/contrib/gcc/expr.c
index 2a5c6f9b890b..99f7fcf84b0c 100644
--- a/contrib/gcc/expr.c
+++ b/contrib/gcc/expr.c
@@ -5434,16 +5434,13 @@ rtx
force_operand (value, target)
rtx value, target;
{
- optab binoptab = 0;
- /* Use a temporary to force order of execution of calls to
- `force_operand'. */
- rtx tmp;
- rtx op2;
+ rtx op1, op2;
/* Use subtarget as the target for operand 0 of a binary operation. */
rtx subtarget = get_subtarget (target);
+ enum rtx_code code = GET_CODE (value);
/* Check for a PIC address load. */
- if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
+ if ((code == PLUS || code == MINUS)
&& XEXP (value, 0) == pic_offset_table_rtx
&& (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
|| GET_CODE (XEXP (value, 1)) == LABEL_REF
@@ -5455,60 +5452,88 @@ force_operand (value, target)
return subtarget;
}
- if (GET_CODE (value) == PLUS)
- binoptab = add_optab;
- else if (GET_CODE (value) == MINUS)
- binoptab = sub_optab;
- else if (GET_CODE (value) == MULT)
+ if (code == ZERO_EXTEND || code == SIGN_EXTEND)
{
- op2 = XEXP (value, 1);
- if (!CONSTANT_P (op2)
- && !(GET_CODE (op2) == REG && op2 != subtarget))
- subtarget = 0;
- tmp = force_operand (XEXP (value, 0), subtarget);
- return expand_mult (GET_MODE (value), tmp,
- force_operand (op2, NULL_RTX),
- target, 1);
+ if (!target)
+ target = gen_reg_rtx (GET_MODE (value));
+ convert_move (target, force_operand (XEXP (value, 0), NULL),
+ code == ZERO_EXTEND);
+ return target;
}
- if (binoptab)
+ if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c')
{
op2 = XEXP (value, 1);
- if (!CONSTANT_P (op2)
- && !(GET_CODE (op2) == REG && op2 != subtarget))
+ if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget))
subtarget = 0;
- if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT)
+ if (code == MINUS && GET_CODE (op2) == CONST_INT)
{
- binoptab = add_optab;
+ code = PLUS;
op2 = negate_rtx (GET_MODE (value), op2);
}
/* Check for an addition with OP2 a constant integer and our first
- operand a PLUS of a virtual register and something else. In that
- case, we want to emit the sum of the virtual register and the
- constant first and then add the other value. This allows virtual
- register instantiation to simply modify the constant rather than
- creating another one around this addition. */
- if (binoptab == add_optab && GET_CODE (op2) == CONST_INT
+ operand a PLUS of a virtual register and something else. In that
+ case, we want to emit the sum of the virtual register and the
+ constant first and then add the other value. This allows virtual
+ register instantiation to simply modify the constant rather than
+ creating another one around this addition. */
+ if (code == PLUS && GET_CODE (op2) == CONST_INT
&& GET_CODE (XEXP (value, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
&& REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
&& REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
{
- rtx temp = expand_binop (GET_MODE (value), binoptab,
- XEXP (XEXP (value, 0), 0), op2,
- subtarget, 0, OPTAB_LIB_WIDEN);
- return expand_binop (GET_MODE (value), binoptab, temp,
- force_operand (XEXP (XEXP (value, 0), 1), 0),
- target, 0, OPTAB_LIB_WIDEN);
+ rtx temp = expand_simple_binop (GET_MODE (value), code,
+ XEXP (XEXP (value, 0), 0), op2,
+ subtarget, 0, OPTAB_LIB_WIDEN);
+ return expand_simple_binop (GET_MODE (value), code, temp,
+ force_operand (XEXP (XEXP (value,
+ 0), 1), 0),
+ target, 0, OPTAB_LIB_WIDEN);
+ }
+
+ op1 = force_operand (XEXP (value, 0), subtarget);
+ op2 = force_operand (op2, NULL_RTX);
+ switch (code)
+ {
+ case MULT:
+ return expand_mult (GET_MODE (value), op1, op2, target, 1);
+ case DIV:
+ if (!INTEGRAL_MODE_P (GET_MODE (value)))
+ return expand_simple_binop (GET_MODE (value), code, op1, op2,
+ target, 1, OPTAB_LIB_WIDEN);
+ else
+ return expand_divmod (0,
+ FLOAT_MODE_P (GET_MODE (value))
+ ? RDIV_EXPR : TRUNC_DIV_EXPR,
+ GET_MODE (value), op1, op2, target, 0);
+ break;
+ case MOD:
+ return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
+ target, 0);
+ break;
+ case UDIV:
+ return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
+ target, 1);
+ break;
+ case UMOD:
+ return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
+ target, 1);
+ break;
+ case ASHIFTRT:
+ return expand_simple_binop (GET_MODE (value), code, op1, op2,
+ target, 0, OPTAB_LIB_WIDEN);
+ break;
+ default:
+ return expand_simple_binop (GET_MODE (value), code, op1, op2,
+ target, 1, OPTAB_LIB_WIDEN);
}
-
- tmp = force_operand (XEXP (value, 0), subtarget);
- return expand_binop (GET_MODE (value), binoptab, tmp,
- force_operand (op2, NULL_RTX),
- target, 0, OPTAB_LIB_WIDEN);
- /* We give UNSIGNEDP = 0 to expand_binop
- because the only operations we are expanding here are signed ones. */
+ }
+ if (GET_RTX_CLASS (code) == '1')
+ {
+ op1 = force_operand (XEXP (value, 0), NULL_RTX);
+ return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
}
#ifdef INSN_SCHEDULING
@@ -7563,16 +7588,23 @@ expand_expr (exp, target, tmode, modifier)
}
}
+ if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
+ subtarget = 0;
+
/* No sense saving up arithmetic to be done
if it's all in the wrong mode to form part of an address.
And force_operand won't know whether to sign-extend or
zero-extend. */
if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
|| mode != ptr_mode)
- goto binop;
-
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
+ {
+ op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
+ op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ temp = simplify_binary_operation (PLUS, mode, op0, op1);
+ if (temp)
+ return temp;
+ goto binop2;
+ }
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
diff --git a/contrib/gcc/f/version.c b/contrib/gcc/f/version.c
index b9dc05c6ca43..a420cc91c2bc 100644
--- a/contrib/gcc/f/version.c
+++ b/contrib/gcc/f/version.c
@@ -1,4 +1,4 @@
#include "ansidecl.h"
#include "f/version.h"
-const char *const ffe_version_string = "3.2.1 20020916 (prerelease)";
+const char *const ffe_version_string = "3.2.1 20021009 (prerelease)";
diff --git a/contrib/gcc/flags.h b/contrib/gcc/flags.h
index 40d42f2d0d51..85e07924b5d7 100644
--- a/contrib/gcc/flags.h
+++ b/contrib/gcc/flags.h
@@ -604,6 +604,10 @@ extern int align_labels_max_skip;
extern int align_functions;
extern int align_functions_log;
+/* Like align_functions_log above, but used by front-ends to force the
+ minimum function alignment. Zero means no alignment is forced. */
+extern int force_align_functions_log;
+
/* Nonzero if we dump in VCG format, not plain text. */
extern int dump_for_graph;
diff --git a/contrib/gcc/gcc.c b/contrib/gcc/gcc.c
index 96045167492e..cf86f9bc2f22 100644
--- a/contrib/gcc/gcc.c
+++ b/contrib/gcc/gcc.c
@@ -172,6 +172,11 @@ static const char *print_prog_name = NULL;
static int print_multi_directory;
+/* Flag saying to print the relative path we'd use to
+ find OS libraries given the current compiler flags. */
+
+static int print_multi_os_directory;
+
/* Flag saying to print the list of subdirectories and
compiler flags used to select them in a standard form. */
@@ -285,9 +290,10 @@ static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const cha
static char *build_search_list PARAMS ((struct path_prefix *, const char *, int));
static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *));
static int access_check PARAMS ((const char *, int));
-static char *find_a_file PARAMS ((struct path_prefix *, const char *, int));
+static char *find_a_file PARAMS ((struct path_prefix *, const char *,
+ int, int));
static void add_prefix PARAMS ((struct path_prefix *, const char *,
- const char *, int, int, int *));
+ const char *, int, int, int *, int));
static void translate_options PARAMS ((int *, const char *const **));
static char *skip_whitespace PARAMS ((char *));
static void delete_if_ordinary PARAMS ((const char *));
@@ -963,6 +969,7 @@ static const struct option_map option_map[] =
{"--print-missing-file-dependencies", "-MG", 0},
{"--print-multi-lib", "-print-multi-lib", 0},
{"--print-multi-directory", "-print-multi-directory", 0},
+ {"--print-multi-os-directory", "-print-multi-os-directory", 0},
{"--print-prog-name", "-print-prog-name=", "aj"},
{"--profile", "-p", 0},
{"--profile-blocks", "-a", 0},
@@ -1248,7 +1255,9 @@ struct prefix_list
int require_machine_suffix; /* Don't use without machine_suffix. */
/* 2 means try both machine_suffix and just_machine_suffix. */
int *used_flag_ptr; /* 1 if a file was found with this prefix. */
- int priority; /* Sort key - priority within list */
+ int priority; /* Sort key - priority within list. */
+ int os_multilib; /* 1 if OS multilib scheme should be used,
+ 0 for GCC multilib scheme. */
};
struct path_prefix
@@ -1337,6 +1346,11 @@ static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
set_multilib_dir based on the compilation options. */
static const char *multilib_dir;
+
+/* Subdirectory to use for locating libraries in OS conventions. Set by
+ set_multilib_dir based on the compilation options. */
+
+static const char *multilib_os_dir;
/* Structure to keep track of the specs that have been defined so far.
These are accessed using %(specname) or %[specname] in a compiler
@@ -1390,6 +1404,7 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("multilib_extra", &multilib_extra),
INIT_STATIC_SPEC ("multilib_matches", &multilib_matches),
INIT_STATIC_SPEC ("multilib_exclusions", &multilib_exclusions),
+ INIT_STATIC_SPEC ("multilib_options", &multilib_options),
INIT_STATIC_SPEC ("linker", &linker_name_spec),
INIT_STATIC_SPEC ("link_libgcc", &link_libgcc_spec),
INIT_STATIC_SPEC ("md_exec_prefix", &md_exec_prefix),
@@ -1832,7 +1847,7 @@ read_specs (filename, main_p)
(long) (p1 - buffer + 1));
p[-2] = '\0';
- new_filename = find_a_file (&startfile_prefixes, p1, R_OK);
+ new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
read_specs (new_filename ? new_filename : p1, FALSE);
continue;
}
@@ -1851,7 +1866,7 @@ read_specs (filename, main_p)
(long) (p1 - buffer + 1));
p[-2] = '\0';
- new_filename = find_a_file (&startfile_prefixes, p1, R_OK);
+ new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
if (new_filename)
read_specs (new_filename, FALSE);
else if (verbose_flag)
@@ -2480,16 +2495,17 @@ access_check (name, mode)
Return 0 if not found, otherwise return its name, allocated with malloc. */
static char *
-find_a_file (pprefix, name, mode)
+find_a_file (pprefix, name, mode, multilib)
struct path_prefix *pprefix;
const char *name;
- int mode;
+ int mode, multilib;
{
char *temp;
const char *const file_suffix =
((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
struct prefix_list *pl;
int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
+ const char *multilib_name, *multilib_os_name;
#ifdef DEFAULT_ASSEMBLER
if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
@@ -2504,6 +2520,22 @@ find_a_file (pprefix, name, mode)
if (machine_suffix)
len += strlen (machine_suffix);
+ multilib_name = name;
+ multilib_os_name = name;
+ if (multilib && multilib_os_dir)
+ {
+ int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0;
+ int len2 = strlen (multilib_os_dir) + 1;
+
+ len += len1 > len2 ? len1 : len2;
+ if (multilib_dir)
+ multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name,
+ NULL));
+ if (strcmp (multilib_os_dir, ".") != 0)
+ multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name,
+ NULL));
+ }
+
temp = xmalloc (len);
/* Determine the filename to execute (special case for absolute paths). */
@@ -2519,6 +2551,9 @@ find_a_file (pprefix, name, mode)
else
for (pl = pprefix->plist; pl; pl = pl->next)
{
+ const char *this_name
+ = pl->os_multilib ? multilib_os_name : multilib_name;
+
if (machine_suffix)
{
/* Some systems have a suffix for executable files.
@@ -2527,7 +2562,7 @@ find_a_file (pprefix, name, mode)
{
strcpy (temp, pl->prefix);
strcat (temp, machine_suffix);
- strcat (temp, name);
+ strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
{
@@ -2537,10 +2572,10 @@ find_a_file (pprefix, name, mode)
}
}
- /* Now try just the name. */
+ /* Now try just the multilib_name. */
strcpy (temp, pl->prefix);
strcat (temp, machine_suffix);
- strcat (temp, name);
+ strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
{
if (pl->used_flag_ptr != 0)
@@ -2559,7 +2594,7 @@ find_a_file (pprefix, name, mode)
{
strcpy (temp, pl->prefix);
strcat (temp, just_machine_suffix);
- strcat (temp, name);
+ strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
{
@@ -2571,7 +2606,7 @@ find_a_file (pprefix, name, mode)
strcpy (temp, pl->prefix);
strcat (temp, just_machine_suffix);
- strcat (temp, name);
+ strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
{
if (pl->used_flag_ptr != 0)
@@ -2589,7 +2624,7 @@ find_a_file (pprefix, name, mode)
if (file_suffix[0] != 0)
{
strcpy (temp, pl->prefix);
- strcat (temp, name);
+ strcat (temp, this_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
{
@@ -2600,7 +2635,7 @@ find_a_file (pprefix, name, mode)
}
strcpy (temp, pl->prefix);
- strcat (temp, name);
+ strcat (temp, this_name);
if (access_check (temp, mode) == 0)
{
if (pl->used_flag_ptr != 0)
@@ -2638,13 +2673,15 @@ enum path_prefix_priority
2 means try both machine_suffix and just_machine_suffix. */
static void
-add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn)
+add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
+ warn, os_multilib)
struct path_prefix *pprefix;
const char *prefix;
const char *component;
/* enum prefix_priority */ int priority;
int require_machine_suffix;
int *warn;
+ int os_multilib;
{
struct prefix_list *pl, **prev;
int len;
@@ -2666,6 +2703,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn)
pl->require_machine_suffix = require_machine_suffix;
pl->used_flag_ptr = warn;
pl->priority = priority;
+ pl->os_multilib = os_multilib;
if (warn)
*warn = 0;
@@ -2709,7 +2747,7 @@ execute ()
commands[0].prog = argbuf[0]; /* first command. */
commands[0].argv = &argbuf[0];
- string = find_a_file (&exec_prefixes, commands[0].prog, X_OK);
+ string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0);
if (string)
commands[0].argv[0] = string;
@@ -2723,7 +2761,8 @@ execute ()
argbuf[i] = 0; /* termination of command args. */
commands[n_commands].prog = argbuf[i + 1];
commands[n_commands].argv = &argbuf[i + 1];
- string = find_a_file (&exec_prefixes, commands[n_commands].prog, X_OK);
+ string = find_a_file (&exec_prefixes, commands[n_commands].prog,
+ X_OK, 0);
if (string)
commands[n_commands].argv[0] = string;
n_commands++;
@@ -3041,6 +3080,7 @@ display_help ()
fputs (_("\
-print-multi-lib Display the mapping between command line options and\n\
multiple library search directories\n"), stdout);
+ fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout);
fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout);
fputs (_(" -Wl,<options> Pass comma-separated <options> on to the linker\n"), stdout);
@@ -3202,9 +3242,9 @@ process_command (argc, argv)
set_std_prefix (gcc_exec_prefix, len);
add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
}
/* COMPILER_PATH and LIBRARY_PATH have values
@@ -3232,10 +3272,10 @@ process_command (argc, argv)
else
nstore[endp - startp] = 0;
add_prefix (&exec_prefixes, nstore, 0,
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
add_prefix (&include_prefixes,
concat (nstore, "include", NULL),
- 0, PREFIX_PRIORITY_LAST, 0, NULL);
+ 0, PREFIX_PRIORITY_LAST, 0, NULL, 0);
if (*endp == 0)
break;
endp = startp = endp + 1;
@@ -3267,7 +3307,7 @@ process_command (argc, argv)
else
nstore[endp - startp] = 0;
add_prefix (&startfile_prefixes, nstore, NULL,
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
if (*endp == 0)
break;
endp = startp = endp + 1;
@@ -3300,7 +3340,7 @@ process_command (argc, argv)
else
nstore[endp - startp] = 0;
add_prefix (&startfile_prefixes, nstore, NULL,
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
if (*endp == 0)
break;
endp = startp = endp + 1;
@@ -3401,6 +3441,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
print_multi_lib = 1;
else if (! strcmp (argv[i], "-print-multi-directory"))
print_multi_directory = 1;
+ else if (! strcmp (argv[i], "-print-multi-os-directory"))
+ print_multi_os_directory = 1;
else if (! strncmp (argv[i], "-Wa,", 4))
{
int prev, j;
@@ -3570,7 +3612,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
{
if (len == 7)
add_prefix (&include_prefixes, "include", NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL);
+ PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
else
{
char * string = xmalloc (len + 1);
@@ -3578,16 +3620,16 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
strncpy (string, value, len - 7);
strcpy (string + len - 7, "include");
add_prefix (&include_prefixes, string, NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL);
+ PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
}
}
add_prefix (&exec_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, &warn_B);
+ PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
add_prefix (&startfile_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, &warn_B);
+ PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
add_prefix (&include_prefixes, concat (value, "include", NULL),
- NULL, PREFIX_PRIORITY_B_OPT, 0, NULL);
+ NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
n_switches++;
}
break;
@@ -3760,17 +3802,17 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
as well as trying the machine and the version. */
#ifndef OS2
add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr);
+ PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr);
+ PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr);
+ PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
#endif
add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr);
+ PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr);
+ PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
dir_separator_str, NULL);
@@ -3793,11 +3835,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
add_prefix (&exec_prefixes,
concat (gcc_exec_tooldir_prefix, "bin",
dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL);
+ NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0);
add_prefix (&startfile_prefixes,
concat (gcc_exec_tooldir_prefix, "lib",
dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL);
+ NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
}
tooldir_prefix = concat (standard_exec_prefix, spec_machine,
@@ -3807,10 +3849,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
add_prefix (&exec_prefixes,
concat (tooldir_prefix, "bin", dir_separator_str, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0);
add_prefix (&startfile_prefixes,
concat (tooldir_prefix, "lib", dir_separator_str, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
/* More prefixes are enabled in main, after we read the specs file
and determine whether this is cross-compilation or not. */
@@ -3860,6 +3902,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
;
else if (! strcmp (argv[i], "-print-multi-directory"))
;
+ else if (! strcmp (argv[i], "-print-multi-os-directory"))
+ ;
else if (! strcmp (argv[i], "-ftarget-help"))
;
else if (! strcmp (argv[i], "-fhelp"))
@@ -4363,9 +4407,14 @@ do_spec_1 (spec, inswitch, soft_matched_part)
continue;
#endif
/* Try subdirectory if there is one. */
- if (multilib_dir != NULL)
+ if (multilib_dir != NULL
+ || (pl->os_multilib && multilib_os_dir != NULL))
{
- if (machine_suffix)
+ const char *multi_dir;
+
+ multi_dir = pl->os_multilib ? multilib_os_dir
+ : multilib_dir;
+ if (machine_suffix && multilib_dir)
{
if (strlen (pl->prefix) + strlen (machine_suffix)
>= bufsize)
@@ -4388,14 +4437,14 @@ do_spec_1 (spec, inswitch, soft_matched_part)
}
if (!pl->require_machine_suffix)
{
- if (is_directory (pl->prefix, multilib_dir, 1))
+ if (is_directory (pl->prefix, multi_dir, 1))
{
do_spec_1 ("-L", 0, NULL);
#ifdef SPACE_AFTER_L_OPTION
do_spec_1 (" ", 0, NULL);
#endif
do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (multilib_dir, 1, NULL);
+ do_spec_1 (multi_dir, 1, NULL);
/* Make this a separate argument. */
do_spec_1 (" ", 0, NULL);
}
@@ -5616,11 +5665,9 @@ find_file (name)
char *newname;
/* Try multilib_dir if it is defined. */
- if (multilib_dir != NULL)
+ if (multilib_os_dir != NULL)
{
- const char *const try = ACONCAT ((multilib_dir, dir_separator_str, name, NULL));
-
- newname = find_a_file (&startfile_prefixes, try, R_OK);
+ newname = find_a_file (&startfile_prefixes, name, R_OK, 1);
/* If we don't find it in the multi library dir, then fall
through and look for it in the normal places. */
@@ -5628,7 +5675,7 @@ find_file (name)
return newname;
}
- newname = find_a_file (&startfile_prefixes, name, R_OK);
+ newname = find_a_file (&startfile_prefixes, name, R_OK, 0);
return newname ? newname : name;
}
@@ -5863,7 +5910,7 @@ main (argc, argv)
spec_version, dir_separator_str, NULL);
just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
- specs_file = find_a_file (&startfile_prefixes, "specs", R_OK);
+ specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0);
/* Read the specs file unless it is a default one. */
if (specs_file != 0 && strcmp (specs_file, "specs"))
read_specs (specs_file, TRUE);
@@ -5888,18 +5935,18 @@ main (argc, argv)
if (*md_exec_prefix)
{
add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
add_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
}
if (*md_startfile_prefix)
add_prefix (&startfile_prefixes, md_startfile_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
if (*md_startfile_prefix_1)
add_prefix (&startfile_prefixes, md_startfile_prefix_1, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
/* If standard_startfile_prefix is relative, base it on
standard_exec_prefix. This lets us move the installed tree
@@ -5907,28 +5954,28 @@ main (argc, argv)
standard_startfile_prefix on that as well. */
if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix))
add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL);
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
else
{
if (gcc_exec_prefix)
add_prefix (&startfile_prefixes,
concat (gcc_exec_prefix, machine_suffix,
standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL);
+ NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
add_prefix (&startfile_prefixes,
concat (standard_exec_prefix,
machine_suffix,
standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL);
+ NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
}
add_prefix (&startfile_prefixes, standard_startfile_prefix_1,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
add_prefix (&startfile_prefixes, standard_startfile_prefix_2,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
#if 0 /* Can cause surprises, and one can use -B./ instead. */
add_prefix (&startfile_prefixes, "./", NULL,
- PREFIX_PRIORITY_LAST, 1, NULL);
+ PREFIX_PRIORITY_LAST, 1, NULL, 0);
#endif
}
else
@@ -5938,14 +5985,15 @@ main (argc, argv)
add_prefix (&startfile_prefixes,
concat (gcc_exec_prefix, machine_suffix,
standard_startfile_prefix, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
}
/* Process any user specified specs in the order given on the command
line. */
for (uptr = user_specs_head; uptr; uptr = uptr->next)
{
- char *filename = find_a_file (&startfile_prefixes, uptr->filename, R_OK);
+ char *filename = find_a_file (&startfile_prefixes, uptr->filename,
+ R_OK, 0);
read_specs (filename ? filename : uptr->filename, FALSE);
}
@@ -5987,7 +6035,7 @@ main (argc, argv)
if (print_prog_name)
{
- char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK);
+ char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
printf ("%s\n", (newname ? newname : print_prog_name));
return (0);
}
@@ -6007,6 +6055,15 @@ main (argc, argv)
return (0);
}
+ if (print_multi_os_directory)
+ {
+ if (multilib_os_dir == NULL)
+ printf (".\n");
+ else
+ printf ("%s\n", multilib_os_dir);
+ return (0);
+ }
+
if (target_help_flag)
{
/* Print if any target specific options. */
@@ -6166,7 +6223,7 @@ main (argc, argv)
/* We'll use ld if we can't find collect2. */
if (! strcmp (linker_name_spec, "collect2"))
{
- char *s = find_a_file (&exec_prefixes, "collect2", X_OK);
+ char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0);
if (s == NULL)
linker_name_spec = "ld";
}
@@ -6460,6 +6517,15 @@ next_member:
goto next_member;
}
+struct mdswitchstr
+{
+ const char *str;
+ int len;
+};
+
+static struct mdswitchstr *mdswitches;
+static int n_mdswitches;
+
/* Check whether a particular argument was used. The first time we
canonicalize the switches to keep only the ones we care about. */
@@ -6525,8 +6591,9 @@ used_arg (p, len)
xmalloc from calling fatal, and prevents us from re-executing this
block of code. */
mswitches
- = (struct mswitchstr *) xmalloc ((sizeof (struct mswitchstr))
- * (n_switches ? n_switches : 1));
+ = (struct mswitchstr *)
+ xmalloc (sizeof (struct mswitchstr)
+ * (n_mdswitches + (n_switches ? n_switches : 1)));
for (i = 0; i < n_switches; i++)
{
int xlen = strlen (switches[i].part1);
@@ -6542,6 +6609,57 @@ used_arg (p, len)
break;
}
}
+
+ /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
+ on the command line nor any options mutually incompatible with
+ them. */
+ for (i = 0; i < n_mdswitches; i++)
+ {
+ const char *r;
+
+ for (q = multilib_options; *q != '\0'; q++)
+ {
+ while (*q == ' ')
+ q++;
+
+ r = q;
+ while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
+ || strchr (" /", q[mdswitches[i].len]) == NULL)
+ {
+ while (*q != ' ' && *q != '/' && *q != '\0')
+ q++;
+ if (*q != '/')
+ break;
+ q++;
+ }
+
+ if (*q != ' ' && *q != '\0')
+ {
+ while (*r != ' ' && *r != '\0')
+ {
+ q = r;
+ while (*q != ' ' && *q != '/' && *q != '\0')
+ q++;
+
+ if (used_arg (r, q - r))
+ break;
+
+ if (*q != '/')
+ {
+ mswitches[n_mswitches].str = mdswitches[i].str;
+ mswitches[n_mswitches].len = mdswitches[i].len;
+ mswitches[n_mswitches].replace = (char *) 0;
+ mswitches[n_mswitches].rep_len = 0;
+ n_mswitches++;
+ break;
+ }
+
+ r = q + 1;
+ }
+ break;
+ }
+ }
+ }
}
for (i = 0; i < n_mswitches; i++)
@@ -6556,25 +6674,11 @@ default_arg (p, len)
const char *p;
int len;
{
- const char *start, *end;
-
- for (start = multilib_defaults; *start != '\0'; start = end + 1)
- {
- while (*start == ' ' || *start == '\t')
- start++;
-
- if (*start == '\0')
- break;
-
- for (end = start + 1; *end != ' ' && *end != '\t' && *end != '\0'; end++)
- ;
-
- if ((end - start) == len && strncmp (p, start, len) == 0)
- return 1;
+ int i;
- if (*end == '\0')
- break;
- }
+ for (i = 0; i < n_mdswitches; i++)
+ if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
+ return 1;
return 0;
}
@@ -6596,8 +6700,51 @@ set_multilib_dir ()
const char *p;
unsigned int this_path_len;
const char *this_path, *this_arg;
+ const char *start, *end;
int not_arg;
- int ok;
+ int ok, ndfltok, first;
+
+ n_mdswitches = 0;
+ start = multilib_defaults;
+ while (*start == ' ' || *start == '\t')
+ start++;
+ while (*start != '\0')
+ {
+ n_mdswitches++;
+ while (*start != ' ' && *start != '\t' && *start != '\0')
+ start++;
+ while (*start == ' ' || *start == '\t')
+ start++;
+ }
+
+ if (n_mdswitches)
+ {
+ int i = 0;
+
+ mdswitches
+ = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr)
+ * n_mdswitches);
+ for (start = multilib_defaults; *start != '\0'; start = end + 1)
+ {
+ while (*start == ' ' || *start == '\t')
+ start++;
+
+ if (*start == '\0')
+ break;
+
+ for (end = start + 1;
+ *end != ' ' && *end != '\t' && *end != '\0'; end++)
+ ;
+
+ obstack_grow (&multilib_obstack, start, end - start);
+ obstack_1grow (&multilib_obstack, 0);
+ mdswitches[i].str = obstack_finish (&multilib_obstack);
+ mdswitches[i++].len = end - start;
+
+ if (*end == '\0')
+ break;
+ }
+ }
p = multilib_exclusions;
while (*p != '\0')
@@ -6652,6 +6799,7 @@ set_multilib_dir ()
++p;
}
+ first = 1;
p = multilib_select;
while (*p != '\0')
{
@@ -6674,6 +6822,7 @@ set_multilib_dir ()
/* Check the arguments. */
ok = 1;
+ ndfltok = 1;
++p;
while (*p != ';')
{
@@ -6709,32 +6858,65 @@ set_multilib_dir ()
there is a more specific library which uses this
argument. If this argument is a default, we need not
consider that more specific library. */
- if (! default_arg (this_arg, p - this_arg))
- {
- ok = used_arg (this_arg, p - this_arg);
- if (not_arg)
- ok = ! ok;
- }
+ ok = used_arg (this_arg, p - this_arg);
+ if (not_arg)
+ ok = ! ok;
+
+ if (! ok)
+ ndfltok = 0;
+
+ if (default_arg (this_arg, p - this_arg))
+ ok = 1;
if (*p == ' ')
++p;
}
- if (ok)
+ if (ok && first)
{
if (this_path_len != 1
|| this_path[0] != '.')
{
char *new_multilib_dir = xmalloc (this_path_len + 1);
+ char *q;
+
strncpy (new_multilib_dir, this_path, this_path_len);
new_multilib_dir[this_path_len] = '\0';
+ q = strchr (new_multilib_dir, ':');
+ if (q != NULL)
+ *q = '\0';
multilib_dir = new_multilib_dir;
}
- break;
+ first = 0;
+ }
+
+ if (ndfltok)
+ {
+ const char *q = this_path, *end = this_path + this_path_len;
+
+ while (q < end && *q != ':')
+ q++;
+ if (q < end)
+ {
+ char *new_multilib_os_dir = xmalloc (end - q);
+ memcpy (new_multilib_os_dir, q + 1, end - q - 1);
+ new_multilib_os_dir[end - q - 1] = '\0';
+ multilib_os_dir = new_multilib_os_dir;
+ break;
+ }
}
++p;
}
+
+ if (multilib_dir == NULL && multilib_os_dir != NULL
+ && strcmp (multilib_os_dir, ".") == 0)
+ {
+ free ((char *) multilib_os_dir);
+ multilib_os_dir = NULL;
+ }
+ else if (multilib_dir != NULL && multilib_os_dir == NULL)
+ multilib_os_dir = multilib_dir;
}
/* Print out the multiple library subdirectory selection
@@ -6774,6 +6956,12 @@ print_multilib_info ()
++p;
}
+ /* When --disable-multilib was used but target defines
+ MULTILIB_OSDIRNAMES, entries starting with .: are there just
+ to find multilib_os_dir, so skip them from output. */
+ if (this_path[0] == '.' && this_path[1] == ':')
+ skip = 1;
+
/* Check for matches with the multilib_exclusions. We don't bother
with the '!' in either list. If any of the exclusion rules match
all of its options with the select rule, we skip it. */
@@ -6915,7 +7103,7 @@ print_multilib_info ()
{
const char *p1;
- for (p1 = last_path; p1 < p; p1++)
+ for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
putchar (*p1);
putchar (';');
}
diff --git a/contrib/gcc/genmultilib b/contrib/gcc/genmultilib
index 3cbfaa1ebab2..ca3b71bdfa3d 100644
--- a/contrib/gcc/genmultilib
+++ b/contrib/gcc/genmultilib
@@ -63,6 +63,14 @@
# for the rule to exclude a set. Options can be preceded with a '!' to
# match a logical NOT.
+# The optional sevenths argument is a list of OS subdirectory names.
+# The format is the same as of the second argument.
+# The difference is that second argument describes multilib directories
+# in GCC conventions, while this one the OS multilib convention.
+
+# The last option should be "yes" if multilibs are enabled. If it is not
+# "yes", all GCC multilib dir names will be ".".
+
# The output looks like
# #define MULTILIB_MATCHES "\
# SUBDIRECTORY OPTIONS;\
@@ -79,17 +87,18 @@
# Here is an example (this is from the actual sparc64 case):
# genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
# 'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
-# 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
+# '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
+# '../lib64 ../lib32 alt' yes
# This produces:
# ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
-# "64 m64 !m32 !mno-app-regs !mcmodel=medany;",
-# "32 !m64 m32 !mno-app-regs !mcmodel=medany;",
+# "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
+# "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;",
# "alt !m64 !m32 mno-app-regs mcmodel=medany;",
# "alt !m64 !m32 mno-app-regs !mcmodel=medany;",
# "alt !m64 !m32 !mno-app-regs mcmodel=medany;",
-# "64/alt m64 !m32 mno-app-regs mcmodel=medany;",
-# "64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
-# "64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
+# "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;",
+# "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
+# "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
#
# The effect is that `gcc -mno-app-regs' (for example) will append "alt"
# to the directory name when searching for libraries or startup files and
@@ -106,6 +115,8 @@ matches=$3
exceptions=$4
extra=$5
exclusions=$6
+osdirnames=$7
+enable_multilib=$8
echo "static const char *const multilib_raw[] = {"
@@ -202,6 +213,29 @@ if [ -n "${dirnames}" ]; then
done
fi
+# Construct a sed pattern which will convert option names to OS directory
+# names.
+toosdirnames=
+if [ -n "${osdirnames}" ]; then
+ set x ${osdirnames}
+ shift
+ for set in ${options}; do
+ for opts in `echo ${set} | sed -e 's|/| |'g`; do
+ patt="/"
+ for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
+ if [ "$1" != "${opt}" ]; then
+ toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
+ patt="${patt}${1}/"
+ if [ "${patt}" != "/${1}/" ]; then
+ toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g"
+ fi
+ fi
+ done
+ shift
+ done
+ done
+fi
+
# We need another recursive shell script to correctly handle positive
# matches. If we are invoked as
# genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
@@ -257,6 +291,25 @@ for combo in ${combinations}; do
# Remove the leading and trailing slashes.
dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
+ # Use the OS directory names rather than the option names.
+ if [ -n "${toosdirnames}" ]; then
+ osdirout=`echo ${combo} | sed ${toosdirnames}`
+ # Remove the leading and trailing slashes.
+ osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
+ if [ "x${enable_multilib}" != xyes ]; then
+ dirout=".:${osdirout}"
+ else
+ dirout="${dirout}:${osdirout}"
+ fi
+ else
+ if [ "x${enable_multilib}" != xyes ]; then
+ # genmultilib with --disable-multilib should be
+ # called with '' '' '' '' '' '' '' no
+ # if MULTILIB_OSDIRNAMES is empty.
+ exit 1
+ fi
+ fi
+
# Look through the options. We must output each option that is
# present, and negate each option that is not present.
optout=
@@ -313,6 +366,11 @@ done
echo "NULL"
echo "};"
+# Output the options now
+moptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'`
+echo ""
+echo "static const char *multilib_options = \"${moptions}\";"
+
rm -f tmpmultilib2
exit 0
diff --git a/contrib/gcc/jump.c b/contrib/gcc/jump.c
index cad10ff51ca2..1a26b5924b93 100644
--- a/contrib/gcc/jump.c
+++ b/contrib/gcc/jump.c
@@ -2428,3 +2428,15 @@ true_regnum (x)
}
return -1;
}
+
+/* Return regno of the register REG and handle subregs too. */
+unsigned int
+reg_or_subregno (reg)
+ rtx reg;
+{
+ if (REG_P (reg))
+ return REGNO (reg);
+ if (GET_CODE (reg) == SUBREG)
+ return REGNO (SUBREG_REG (reg));
+ abort ();
+}
diff --git a/contrib/gcc/libgcc2.c b/contrib/gcc/libgcc2.c
index 59d48d8d5243..dd5eee7dbb52 100644
--- a/contrib/gcc/libgcc2.c
+++ b/contrib/gcc/libgcc2.c
@@ -1,7 +1,7 @@
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@@ -36,8 +36,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tconfig.h"
#include "tsystem.h"
-#include "machmode.h"
-
/* Don't use `fancy_abort' here even if config.h says to use it. */
#ifdef abort
#undef abort
@@ -1117,7 +1115,10 @@ __floatdisf (DWtype u)
&& u < ((DWtype) 1 << DF_SIZE)))
{
if ((UDWtype) u & (REP_BIT - 1))
- u |= REP_BIT;
+ {
+ u &= ~ (REP_BIT - 1);
+ u |= REP_BIT;
+ }
}
}
f = (Wtype) (u >> WORD_SIZE);
diff --git a/contrib/gcc/loop.c b/contrib/gcc/loop.c
index 4450845ea7c7..732a84d64b72 100644
--- a/contrib/gcc/loop.c
+++ b/contrib/gcc/loop.c
@@ -640,6 +640,7 @@ scan_loop (loop, flags)
int threshold;
/* Nonzero if we are scanning instructions in a sub-loop. */
int loop_depth = 0;
+ int in_libcall;
loop->top = 0;
@@ -756,290 +757,311 @@ scan_loop (loop, flags)
When MAYBE_NEVER is 0, all insns will be executed at least once
so that is not a problem. */
- for (p = next_insn_in_loop (loop, loop->scan_start);
+ for (in_libcall = 0, p = next_insn_in_loop (loop, loop->scan_start);
p != NULL_RTX;
p = next_insn_in_loop (loop, p))
{
- if (GET_CODE (p) == INSN
- && (set = single_set (p))
- && GET_CODE (SET_DEST (set)) == REG
-#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
- && SET_DEST (set) != pic_offset_table_rtx
-#endif
- && ! regs->array[REGNO (SET_DEST (set))].may_not_optimize)
+ if (in_libcall && INSN_P (p) && find_reg_note (p, REG_RETVAL, NULL_RTX))
+ in_libcall--;
+ if (GET_CODE (p) == INSN)
{
- int tem1 = 0;
- int tem2 = 0;
- int move_insn = 0;
- rtx src = SET_SRC (set);
- rtx dependencies = 0;
-
- /* Figure out what to use as a source of this insn. If a REG_EQUIV
- note is given or if a REG_EQUAL note with a constant operand is
- specified, use it as the source and mark that we should move
- this insn by calling emit_move_insn rather that duplicating the
- insn.
-
- Otherwise, only use the REG_EQUAL contents if a REG_RETVAL note
- is present. */
- temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
+ temp = find_reg_note (p, REG_LIBCALL, NULL_RTX);
if (temp)
- src = XEXP (temp, 0), move_insn = 1;
- else
+ in_libcall++;
+ if (! in_libcall
+ && (set = single_set (p))
+ && GET_CODE (SET_DEST (set)) == REG
+#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
+ && SET_DEST (set) != pic_offset_table_rtx
+#endif
+ && ! regs->array[REGNO (SET_DEST (set))].may_not_optimize)
{
- temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
- if (temp && CONSTANT_P (XEXP (temp, 0)))
+ int tem1 = 0;
+ int tem2 = 0;
+ int move_insn = 0;
+ rtx src = SET_SRC (set);
+ rtx dependencies = 0;
+
+ /* Figure out what to use as a source of this insn. If a
+ REG_EQUIV note is given or if a REG_EQUAL note with a
+ constant operand is specified, use it as the source and
+ mark that we should move this insn by calling
+ emit_move_insn rather that duplicating the insn.
+
+ Otherwise, only use the REG_EQUAL contents if a REG_RETVAL
+ note is present. */
+ temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
+ if (temp)
src = XEXP (temp, 0), move_insn = 1;
- if (temp && find_reg_note (p, REG_RETVAL, NULL_RTX))
- {
- src = XEXP (temp, 0);
- /* A libcall block can use regs that don't appear in
- the equivalent expression. To move the libcall,
- we must move those regs too. */
- dependencies = libcall_other_reg (p, src);
- }
- }
-
- /* For parallels, add any possible uses to the depencies, as we can't move
- the insn without resolving them first. */
- if (GET_CODE (PATTERN (p)) == PARALLEL)
- {
- for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
+ else
{
- rtx x = XVECEXP (PATTERN (p), 0, i);
- if (GET_CODE (x) == USE)
- dependencies = gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0), dependencies);
+ temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
+ if (temp && CONSTANT_P (XEXP (temp, 0)))
+ src = XEXP (temp, 0), move_insn = 1;
+ if (temp && find_reg_note (p, REG_RETVAL, NULL_RTX))
+ {
+ src = XEXP (temp, 0);
+ /* A libcall block can use regs that don't appear in
+ the equivalent expression. To move the libcall,
+ we must move those regs too. */
+ dependencies = libcall_other_reg (p, src);
+ }
}
- }
- /* Don't try to optimize a register that was made
- by loop-optimization for an inner loop.
- We don't know its life-span, so we can't compute the benefit. */
- if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
- ;
- else if (/* The register is used in basic blocks other
- than the one where it is set (meaning that
- something after this point in the loop might
- depend on its value before the set). */
- ! reg_in_basic_block_p (p, SET_DEST (set))
- /* And the set is not guaranteed to be executed once
- the loop starts, or the value before the set is
- needed before the set occurs...
-
- ??? Note we have quadratic behaviour here, mitigated
- by the fact that the previous test will often fail for
- large loops. Rather than re-scanning the entire loop
- each time for register usage, we should build tables
- of the register usage and use them here instead. */
- && (maybe_never
- || loop_reg_used_before_p (loop, set, p)))
- /* It is unsafe to move the set.
-
- This code used to consider it OK to move a set of a variable
- which was not created by the user and not used in an exit test.
- That behavior is incorrect and was removed. */
- ;
- else if ((tem = loop_invariant_p (loop, src))
- && (dependencies == 0
- || (tem2 = loop_invariant_p (loop, dependencies)) != 0)
- && (regs->array[REGNO (SET_DEST (set))].set_in_loop == 1
- || (tem1
- = consec_sets_invariant_p
- (loop, SET_DEST (set),
- regs->array[REGNO (SET_DEST (set))].set_in_loop,
- p)))
- /* If the insn can cause a trap (such as divide by zero),
- can't move it unless it's guaranteed to be executed
- once loop is entered. Even a function call might
- prevent the trap insn from being reached
- (since it might exit!) */
- && ! ((maybe_never || call_passed)
- && may_trap_p (src)))
- {
- struct movable *m;
- int regno = REGNO (SET_DEST (set));
-
- /* A potential lossage is where we have a case where two insns
- can be combined as long as they are both in the loop, but
- we move one of them outside the loop. For large loops,
- this can lose. The most common case of this is the address
- of a function being called.
-
- Therefore, if this register is marked as being used exactly
- once if we are in a loop with calls (a "large loop"), see if
- we can replace the usage of this register with the source
- of this SET. If we can, delete this insn.
-
- Don't do this if P has a REG_RETVAL note or if we have
- SMALL_REGISTER_CLASSES and SET_SRC is a hard register. */
-
- if (loop_info->has_call
- && regs->array[regno].single_usage != 0
- && regs->array[regno].single_usage != const0_rtx
- && REGNO_FIRST_UID (regno) == INSN_UID (p)
- && (REGNO_LAST_UID (regno)
- == INSN_UID (regs->array[regno].single_usage))
- && regs->array[regno].set_in_loop == 1
- && GET_CODE (SET_SRC (set)) != ASM_OPERANDS
- && ! side_effects_p (SET_SRC (set))
- && ! find_reg_note (p, REG_RETVAL, NULL_RTX)
- && (! SMALL_REGISTER_CLASSES
- || (! (GET_CODE (SET_SRC (set)) == REG
- && REGNO (SET_SRC (set)) < FIRST_PSEUDO_REGISTER)))
- /* This test is not redundant; SET_SRC (set) might be
- a call-clobbered register and the life of REGNO
- might span a call. */
- && ! modified_between_p (SET_SRC (set), p,
- regs->array[regno].single_usage)
- && no_labels_between_p (p, regs->array[regno].single_usage)
- && validate_replace_rtx (SET_DEST (set), SET_SRC (set),
- regs->array[regno].single_usage))
+ /* For parallels, add any possible uses to the depencies, as
+ we can't move the insn without resolving them first. */
+ if (GET_CODE (PATTERN (p)) == PARALLEL)
{
- /* Replace any usage in a REG_EQUAL note. Must copy the
- new source, so that we don't get rtx sharing between the
- SET_SOURCE and REG_NOTES of insn p. */
- REG_NOTES (regs->array[regno].single_usage)
- = replace_rtx (REG_NOTES (regs->array[regno].single_usage),
- SET_DEST (set), copy_rtx (SET_SRC (set)));
-
- delete_insn (p);
- for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); i++)
- regs->array[regno+i].set_in_loop = 0;
- continue;
+ for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
+ {
+ rtx x = XVECEXP (PATTERN (p), 0, i);
+ if (GET_CODE (x) == USE)
+ dependencies
+ = gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0),
+ dependencies);
+ }
}
- m = (struct movable *) xmalloc (sizeof (struct movable));
- m->next = 0;
- m->insn = p;
- m->set_src = src;
- m->dependencies = dependencies;
- m->set_dest = SET_DEST (set);
- m->force = 0;
- m->consec = regs->array[REGNO (SET_DEST (set))].set_in_loop - 1;
- m->done = 0;
- m->forces = 0;
- m->partial = 0;
- m->move_insn = move_insn;
- m->move_insn_first = 0;
- m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
- m->savemode = VOIDmode;
- m->regno = regno;
- /* Set M->cond if either loop_invariant_p
- or consec_sets_invariant_p returned 2
- (only conditionally invariant). */
- m->cond = ((tem | tem1 | tem2) > 1);
- m->global = LOOP_REG_GLOBAL_P (loop, regno);
- m->match = 0;
- m->lifetime = LOOP_REG_LIFETIME (loop, regno);
- m->savings = regs->array[regno].n_times_set;
- if (find_reg_note (p, REG_RETVAL, NULL_RTX))
- m->savings += libcall_benefit (p);
- for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); i++)
- regs->array[regno+i].set_in_loop = move_insn ? -2 : -1;
- /* Add M to the end of the chain MOVABLES. */
- loop_movables_add (movables, m);
-
- if (m->consec > 0)
+ /* Don't try to optimize a register that was made
+ by loop-optimization for an inner loop.
+ We don't know its life-span, so we can't compute
+ the benefit. */
+ if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
+ ;
+ else if (/* The register is used in basic blocks other
+ than the one where it is set (meaning that
+ something after this point in the loop might
+ depend on its value before the set). */
+ ! reg_in_basic_block_p (p, SET_DEST (set))
+ /* And the set is not guaranteed to be executed once
+ the loop starts, or the value before the set is
+ needed before the set occurs...
+
+ ??? Note we have quadratic behaviour here, mitigated
+ by the fact that the previous test will often fail for
+ large loops. Rather than re-scanning the entire loop
+ each time for register usage, we should build tables
+ of the register usage and use them here instead. */
+ && (maybe_never
+ || loop_reg_used_before_p (loop, set, p)))
+ /* It is unsafe to move the set.
+
+ This code used to consider it OK to move a set of a variable
+ which was not created by the user and not used in an exit
+ test.
+ That behavior is incorrect and was removed. */
+ ;
+ else if ((tem = loop_invariant_p (loop, src))
+ && (dependencies == 0
+ || (tem2
+ = loop_invariant_p (loop, dependencies)) != 0)
+ && (regs->array[REGNO (SET_DEST (set))].set_in_loop == 1
+ || (tem1
+ = consec_sets_invariant_p
+ (loop, SET_DEST (set),
+ regs->array[REGNO (SET_DEST (set))].set_in_loop,
+ p)))
+ /* If the insn can cause a trap (such as divide by zero),
+ can't move it unless it's guaranteed to be executed
+ once loop is entered. Even a function call might
+ prevent the trap insn from being reached
+ (since it might exit!) */
+ && ! ((maybe_never || call_passed)
+ && may_trap_p (src)))
{
- /* It is possible for the first instruction to have a
- REG_EQUAL note but a non-invariant SET_SRC, so we must
- remember the status of the first instruction in case
- the last instruction doesn't have a REG_EQUAL note. */
- m->move_insn_first = m->move_insn;
-
- /* Skip this insn, not checking REG_LIBCALL notes. */
- p = next_nonnote_insn (p);
- /* Skip the consecutive insns, if there are any. */
- p = skip_consec_insns (p, m->consec);
- /* Back up to the last insn of the consecutive group. */
- p = prev_nonnote_insn (p);
-
- /* We must now reset m->move_insn, m->is_equiv, and possibly
- m->set_src to correspond to the effects of all the
- insns. */
- temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
- if (temp)
- m->set_src = XEXP (temp, 0), m->move_insn = 1;
- else
+ struct movable *m;
+ int regno = REGNO (SET_DEST (set));
+
+ /* A potential lossage is where we have a case where two insns
+ can be combined as long as they are both in the loop, but
+ we move one of them outside the loop. For large loops,
+ this can lose. The most common case of this is the address
+ of a function being called.
+
+ Therefore, if this register is marked as being used
+ exactly once if we are in a loop with calls
+ (a "large loop"), see if we can replace the usage of
+ this register with the source of this SET. If we can,
+ delete this insn.
+
+ Don't do this if P has a REG_RETVAL note or if we have
+ SMALL_REGISTER_CLASSES and SET_SRC is a hard register. */
+
+ if (loop_info->has_call
+ && regs->array[regno].single_usage != 0
+ && regs->array[regno].single_usage != const0_rtx
+ && REGNO_FIRST_UID (regno) == INSN_UID (p)
+ && (REGNO_LAST_UID (regno)
+ == INSN_UID (regs->array[regno].single_usage))
+ && regs->array[regno].set_in_loop == 1
+ && GET_CODE (SET_SRC (set)) != ASM_OPERANDS
+ && ! side_effects_p (SET_SRC (set))
+ && ! find_reg_note (p, REG_RETVAL, NULL_RTX)
+ && (! SMALL_REGISTER_CLASSES
+ || (! (GET_CODE (SET_SRC (set)) == REG
+ && (REGNO (SET_SRC (set))
+ < FIRST_PSEUDO_REGISTER))))
+ /* This test is not redundant; SET_SRC (set) might be
+ a call-clobbered register and the life of REGNO
+ might span a call. */
+ && ! modified_between_p (SET_SRC (set), p,
+ regs->array[regno].single_usage)
+ && no_labels_between_p (p,
+ regs->array[regno].single_usage)
+ && validate_replace_rtx (SET_DEST (set), SET_SRC (set),
+ regs->array[regno].single_usage))
{
- temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
- if (temp && CONSTANT_P (XEXP (temp, 0)))
- m->set_src = XEXP (temp, 0), m->move_insn = 1;
- else
- m->move_insn = 0;
+ /* Replace any usage in a REG_EQUAL note. Must copy
+ the new source, so that we don't get rtx sharing
+ between the SET_SOURCE and REG_NOTES of insn p. */
+ REG_NOTES (regs->array[regno].single_usage)
+ = (replace_rtx
+ (REG_NOTES (regs->array[regno].single_usage),
+ SET_DEST (set), copy_rtx (SET_SRC (set))));
+ delete_insn (p);
+ for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));
+ i++)
+ regs->array[regno+i].set_in_loop = 0;
+ continue;
}
- m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
- }
- }
- /* If this register is always set within a STRICT_LOW_PART
- or set to zero, then its high bytes are constant.
- So clear them outside the loop and within the loop
- just load the low bytes.
- We must check that the machine has an instruction to do so.
- Also, if the value loaded into the register
- depends on the same register, this cannot be done. */
- else if (SET_SRC (set) == const0_rtx
- && GET_CODE (NEXT_INSN (p)) == INSN
- && (set1 = single_set (NEXT_INSN (p)))
- && GET_CODE (set1) == SET
- && (GET_CODE (SET_DEST (set1)) == STRICT_LOW_PART)
- && (GET_CODE (XEXP (SET_DEST (set1), 0)) == SUBREG)
- && (SUBREG_REG (XEXP (SET_DEST (set1), 0))
- == SET_DEST (set))
- && !reg_mentioned_p (SET_DEST (set), SET_SRC (set1)))
- {
- int regno = REGNO (SET_DEST (set));
- if (regs->array[regno].set_in_loop == 2)
- {
- struct movable *m;
+
m = (struct movable *) xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
+ m->set_src = src;
+ m->dependencies = dependencies;
m->set_dest = SET_DEST (set);
- m->dependencies = 0;
m->force = 0;
- m->consec = 0;
+ m->consec
+ = regs->array[REGNO (SET_DEST (set))].set_in_loop - 1;
m->done = 0;
m->forces = 0;
- m->move_insn = 0;
+ m->partial = 0;
+ m->move_insn = move_insn;
m->move_insn_first = 0;
- m->partial = 1;
- /* If the insn may not be executed on some cycles,
- we can't clear the whole reg; clear just high part.
- Not even if the reg is used only within this loop.
- Consider this:
- while (1)
- while (s != t) {
- if (foo ()) x = *s;
- use (x);
- }
- Clearing x before the inner loop could clobber a value
- being saved from the last time around the outer loop.
- However, if the reg is not used outside this loop
- and all uses of the register are in the same
- basic block as the store, there is no problem.
-
- If this insn was made by loop, we don't know its
- INSN_LUID and hence must make a conservative
- assumption. */
- m->global = (INSN_UID (p) >= max_uid_for_loop
- || LOOP_REG_GLOBAL_P (loop, regno)
- || (labels_in_range_p
- (p, REGNO_FIRST_LUID (regno))));
- if (maybe_never && m->global)
- m->savemode = GET_MODE (SET_SRC (set1));
- else
- m->savemode = VOIDmode;
+ m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
+ m->savemode = VOIDmode;
m->regno = regno;
- m->cond = 0;
+ /* Set M->cond if either loop_invariant_p
+ or consec_sets_invariant_p returned 2
+ (only conditionally invariant). */
+ m->cond = ((tem | tem1 | tem2) > 1);
+ m->global = LOOP_REG_GLOBAL_P (loop, regno);
m->match = 0;
m->lifetime = LOOP_REG_LIFETIME (loop, regno);
- m->savings = 1;
+ m->savings = regs->array[regno].n_times_set;
+ if (find_reg_note (p, REG_RETVAL, NULL_RTX))
+ m->savings += libcall_benefit (p);
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); i++)
- regs->array[regno+i].set_in_loop = -1;
+ regs->array[regno+i].set_in_loop = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
+
+ if (m->consec > 0)
+ {
+ /* It is possible for the first instruction to have a
+ REG_EQUAL note but a non-invariant SET_SRC, so we must
+ remember the status of the first instruction in case
+ the last instruction doesn't have a REG_EQUAL note. */
+ m->move_insn_first = m->move_insn;
+
+ /* Skip this insn, not checking REG_LIBCALL notes. */
+ p = next_nonnote_insn (p);
+ /* Skip the consecutive insns, if there are any. */
+ p = skip_consec_insns (p, m->consec);
+ /* Back up to the last insn of the consecutive group. */
+ p = prev_nonnote_insn (p);
+
+ /* We must now reset m->move_insn, m->is_equiv, and
+ possibly m->set_src to correspond to the effects of
+ all the insns. */
+ temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
+ if (temp)
+ m->set_src = XEXP (temp, 0), m->move_insn = 1;
+ else
+ {
+ temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
+ if (temp && CONSTANT_P (XEXP (temp, 0)))
+ m->set_src = XEXP (temp, 0), m->move_insn = 1;
+ else
+ m->move_insn = 0;
+
+ }
+ m->is_equiv
+ = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
+ }
+ }
+ /* If this register is always set within a STRICT_LOW_PART
+ or set to zero, then its high bytes are constant.
+ So clear them outside the loop and within the loop
+ just load the low bytes.
+ We must check that the machine has an instruction to do so.
+ Also, if the value loaded into the register
+ depends on the same register, this cannot be done. */
+ else if (SET_SRC (set) == const0_rtx
+ && GET_CODE (NEXT_INSN (p)) == INSN
+ && (set1 = single_set (NEXT_INSN (p)))
+ && GET_CODE (set1) == SET
+ && (GET_CODE (SET_DEST (set1)) == STRICT_LOW_PART)
+ && (GET_CODE (XEXP (SET_DEST (set1), 0)) == SUBREG)
+ && (SUBREG_REG (XEXP (SET_DEST (set1), 0))
+ == SET_DEST (set))
+ && !reg_mentioned_p (SET_DEST (set), SET_SRC (set1)))
+ {
+ int regno = REGNO (SET_DEST (set));
+ if (regs->array[regno].set_in_loop == 2)
+ {
+ struct movable *m;
+ m = (struct movable *) xmalloc (sizeof (struct movable));
+ m->next = 0;
+ m->insn = p;
+ m->set_dest = SET_DEST (set);
+ m->dependencies = 0;
+ m->force = 0;
+ m->consec = 0;
+ m->done = 0;
+ m->forces = 0;
+ m->move_insn = 0;
+ m->move_insn_first = 0;
+ m->partial = 1;
+ /* If the insn may not be executed on some cycles,
+ we can't clear the whole reg; clear just high part.
+ Not even if the reg is used only within this loop.
+ Consider this:
+ while (1)
+ while (s != t) {
+ if (foo ()) x = *s;
+ use (x);
+ }
+ Clearing x before the inner loop could clobber a value
+ being saved from the last time around the outer loop.
+ However, if the reg is not used outside this loop
+ and all uses of the register are in the same
+ basic block as the store, there is no problem.
+
+ If this insn was made by loop, we don't know its
+ INSN_LUID and hence must make a conservative
+ assumption. */
+ m->global = (INSN_UID (p) >= max_uid_for_loop
+ || LOOP_REG_GLOBAL_P (loop, regno)
+ || (labels_in_range_p
+ (p, REGNO_FIRST_LUID (regno))));
+ if (maybe_never && m->global)
+ m->savemode = GET_MODE (SET_SRC (set1));
+ else
+ m->savemode = VOIDmode;
+ m->regno = regno;
+ m->cond = 0;
+ m->match = 0;
+ m->lifetime = LOOP_REG_LIFETIME (loop, regno);
+ m->savings = 1;
+ for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));
+ i++)
+ regs->array[regno+i].set_in_loop = -1;
+ /* Add M to the end of the chain MOVABLES. */
+ loop_movables_add (movables, m);
+ }
}
}
}
@@ -1911,10 +1933,10 @@ move_movables (loop, movables, threshold, insn_count)
for (count = m->consec; count >= 0; count--)
{
/* If this is the first insn of a library call sequence,
- skip to the end. */
+ something is very wrong. */
if (GET_CODE (p) != NOTE
&& (temp = find_reg_note (p, REG_LIBCALL, NULL_RTX)))
- p = XEXP (temp, 0);
+ abort ();
/* If this is the last insn of a libcall sequence, then
delete every insn in the sequence except the last.
@@ -4090,11 +4112,17 @@ emit_prefetch_instructions (loop)
{
rtx reg = gen_reg_rtx (Pmode);
rtx loop_start = loop->start;
+ rtx init_val = info[i].class->initial_value;
rtx add_val = simplify_gen_binary (PLUS, Pmode,
info[i].giv->add_val,
GEN_INT (y * PREFETCH_BLOCK));
- loop_iv_add_mult_emit_before (loop, info[i].class->initial_value,
+ /* Functions called by LOOP_IV_ADD_EMIT_BEFORE expect a
+ non-constant INIT_VAL to have the same mode as REG, which
+ in this case we know to be Pmode. */
+ if (GET_MODE (init_val) != Pmode && !CONSTANT_P (init_val))
+ init_val = convert_to_mode (Pmode, init_val, 0);
+ loop_iv_add_mult_emit_before (loop, init_val,
info[i].giv->mult_val,
add_val, reg, 0, loop_start);
emit_insn_before (gen_prefetch (reg, GEN_INT (info[i].write),
diff --git a/contrib/gcc/loop.h b/contrib/gcc/loop.h
index 8e3a9351f36c..6d18b01f5bd5 100644
--- a/contrib/gcc/loop.h
+++ b/contrib/gcc/loop.h
@@ -314,6 +314,9 @@ struct loop_info
int has_multiple_exit_targets;
/* Nonzero if there is an indirect jump in the current function. */
int has_indirect_jump;
+ /* Whether loop unrolling has emitted copies of the loop body so
+ that the main loop needs no exit tests. */
+ int preconditioned;
/* Register or constant initial loop value. */
rtx initial_value;
/* Register or constant value used for comparison test. */
diff --git a/contrib/gcc/mklibgcc.in b/contrib/gcc/mklibgcc.in
index c5db6f0a0393..30f660c4be1a 100644
--- a/contrib/gcc/mklibgcc.in
+++ b/contrib/gcc/mklibgcc.in
@@ -32,7 +32,7 @@
# SHLIB_MAPFILES
# SHLIB_NM_FLAGS
# SHLIB_INSTALL
-# SHLIB_SLIBDIR_SUFFIXES
+# MULTILIB_OSDIRNAMES
# Make needs VPATH to be literal.
echo 'srcdir = @srcdir@'
@@ -317,22 +317,18 @@ for ml in $MULTILIBS; do
fi
shlib_so_name="$shlib_base_name"
shlib_dir=
- if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then
+ if [ -n "$MULTILIB_OSDIRNAMES" ]; then
if [ "$dir" != . ]; then
+ gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
+ os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory`
shlib_dir="$dir"/
- for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
- base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
- if [ "$dir" = "$base_ml_dir" ]; then
- shlib_so_name=libgcc_s
- break
- else
- canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"`
- if [ -n "$canon_dir" ]; then
- shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g`
- break
- fi
- fi
- done
+ gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'`
+ os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
+ if [ -z "$os_multilib_base" ]; then
+ shlib_so_name=libgcc_s
+ else
+ shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
+ fi
fi
fi
echo ""
@@ -438,6 +434,7 @@ echo ""
echo "install: $all"
for ml in $MULTILIBS; do
dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
+ flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
if [ $dir != . ]; then
ldir='$(libsubdir)'/$dir
echo " if [ -d $ldir ]; then true; else mkdir $ldir; chmod a+rx $ldir; fi;"
@@ -460,39 +457,22 @@ for ml in $MULTILIBS; do
shlib_so_name="$shlib_base_name"
shlib_dir=
shlib_slibdir_qual=
- if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then
- shlib_slibdir_qual=none
+ if [ -n "$MULTILIB_OSDIRNAMES" ]; then
+ gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
+ os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory`
if [ "$dir" != . ]; then
shlib_dir="$dir"/
- for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
- base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
- if [ "$dir" = "$base_ml_dir" ]; then
- shlib_so_name=libgcc_s
- shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
- break
- else
- canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"`
- if [ -n "$canon_dir" ]; then
- shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g`
- shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
- break
- fi
- fi
- done
fi
- if [ "$shlib_slibdir_qual" = none ]; then
- for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
- base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
- shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
- for ml2 in $MULTILIBS; do
- dir2=`echo ${ml2} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
- if [ "$base_ml_dir" = "$dir2" ]; then
- shlib_slibdir_qual=
- break
- fi
- done
- if [ -n "$shlib_slibdir_qual" ]; then break; fi
- done
+ gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'`
+ os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
+ if [ -z "$os_multilib_base" ]; then
+ shlib_so_name=libgcc_s
+ if [ "$os_multilib_dir" != "." ]; then
+ shlib_slibdir_qual="/$os_multilib_dir"
+ fi
+ else
+ shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
+ shlib_slibdir_qual="/$os_multilib_base"
fi
fi
echo " $SHLIB_INSTALL" \
diff --git a/contrib/gcc/reload.c b/contrib/gcc/reload.c
index 5880dfb6fa3f..80678d0d7b9a 100644
--- a/contrib/gcc/reload.c
+++ b/contrib/gcc/reload.c
@@ -1283,12 +1283,17 @@ push_reload (in, out, inloc, outloc, class,
So add an additional reload. */
#ifdef SECONDARY_MEMORY_NEEDED
- /* If a memory location is needed for the copy, make one. */
- if (in != 0 && GET_CODE (in) == REG
- && REGNO (in) < FIRST_PSEUDO_REGISTER
- && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
- class, inmode))
- get_secondary_mem (in, inmode, opnum, type);
+ {
+ int regnum;
+
+ /* If a memory location is needed for the copy, make one. */
+ if (in != 0
+ && ((regnum = true_regnum (in)) >= 0)
+ && regnum < FIRST_PSEUDO_REGISTER
+ && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (regnum),
+ class, inmode))
+ get_secondary_mem (in, inmode, opnum, type);
+ }
#endif
i = n_reloads;
@@ -1314,11 +1319,16 @@ push_reload (in, out, inloc, outloc, class,
n_reloads++;
#ifdef SECONDARY_MEMORY_NEEDED
- if (out != 0 && GET_CODE (out) == REG
- && REGNO (out) < FIRST_PSEUDO_REGISTER
- && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
- outmode))
- get_secondary_mem (out, outmode, opnum, type);
+ {
+ int regnum;
+
+ if (out != 0
+ && ((regnum = true_regnum (out)) >= 0)
+ && regnum < FIRST_PSEUDO_REGISTER
+ && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (regnum),
+ outmode))
+ get_secondary_mem (out, outmode, opnum, type);
+ }
#endif
}
else
diff --git a/contrib/gcc/reload1.c b/contrib/gcc/reload1.c
index 0ce10c4c3af7..9782f3ab0c7f 100644
--- a/contrib/gcc/reload1.c
+++ b/contrib/gcc/reload1.c
@@ -7354,6 +7354,9 @@ gen_reload (out, in, opnum, type)
{
rtx last = get_last_insn ();
rtx tem;
+#ifdef SECONDARY_MEMORY_NEEDED
+ int in_regnum, out_regnum;
+#endif
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
@@ -7516,20 +7519,22 @@ gen_reload (out, in, opnum, type)
#ifdef SECONDARY_MEMORY_NEEDED
/* If we need a memory location to do the move, do it that way. */
- else if (GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER
- && GET_CODE (out) == REG && REGNO (out) < FIRST_PSEUDO_REGISTER
- && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
- REGNO_REG_CLASS (REGNO (out)),
+ else if ((in_regnum = true_regnum (in)) >= 0
+ && in_regnum < FIRST_PSEUDO_REGISTER
+ && (out_regnum = true_regnum (out)) >= 0
+ && out_regnum < FIRST_PSEUDO_REGISTER
+ && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (in_regnum),
+ REGNO_REG_CLASS (out_regnum),
GET_MODE (out)))
{
/* Get the memory to use and rewrite both registers to its mode. */
rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
if (GET_MODE (loc) != GET_MODE (out))
- out = gen_rtx_REG (GET_MODE (loc), REGNO (out));
+ out = gen_rtx_REG (GET_MODE (loc), out_regnum);
if (GET_MODE (loc) != GET_MODE (in))
- in = gen_rtx_REG (GET_MODE (loc), REGNO (in));
+ in = gen_rtx_REG (GET_MODE (loc), in_regnum);
gen_reload (loc, in, opnum, type);
gen_reload (out, loc, opnum, type);
@@ -7581,6 +7586,11 @@ delete_output_reload (insn, j, last_reload_reg)
rtx i1;
rtx substed;
+ /* It is possible that this reload has been only used to set another reload
+ we eliminated earlier and thus deleted this instruction too. */
+ if (INSN_DELETED_P (output_reload_insn))
+ return;
+
/* Get the raw pseudo-register referred to. */
while (GET_CODE (reg) == SUBREG)
diff --git a/contrib/gcc/rtl.h b/contrib/gcc/rtl.h
index 12f994bc63e3..63b9f5812a44 100644
--- a/contrib/gcc/rtl.h
+++ b/contrib/gcc/rtl.h
@@ -1811,6 +1811,7 @@ extern int invert_jump_1 PARAMS ((rtx, rtx));
extern int invert_jump PARAMS ((rtx, rtx, int));
extern int rtx_renumbered_equal_p PARAMS ((rtx, rtx));
extern int true_regnum PARAMS ((rtx));
+extern unsigned int reg_or_subregno PARAMS ((rtx));
extern int redirect_jump_1 PARAMS ((rtx, rtx));
extern int redirect_jump PARAMS ((rtx, rtx, int));
extern void rebuild_jump_labels PARAMS ((rtx));
diff --git a/contrib/gcc/sched-deps.c b/contrib/gcc/sched-deps.c
index f2f64d39669b..4e14ee26eaaa 100644
--- a/contrib/gcc/sched-deps.c
+++ b/contrib/gcc/sched-deps.c
@@ -923,7 +923,15 @@ sched_analyze_insn (deps, x, insn, loop_notes)
code = GET_CODE (x);
}
if (code == SET || code == CLOBBER)
- sched_analyze_1 (deps, x, insn);
+ {
+ sched_analyze_1 (deps, x, insn);
+
+ /* Bare clobber insns are used for letting life analysis, reg-stack
+ and others know that a value is dead. Depend on the last call
+ instruction so that reg-stack won't get confused. */
+ if (code == CLOBBER)
+ add_dependence_list (insn, deps->last_function_call, REG_DEP_OUTPUT);
+ }
else if (code == PARALLEL)
{
int i;
diff --git a/contrib/gcc/sibcall.c b/contrib/gcc/sibcall.c
index 6e753fa2fa99..fca451f5a8d8 100644
--- a/contrib/gcc/sibcall.c
+++ b/contrib/gcc/sibcall.c
@@ -574,8 +574,8 @@ optimize_sibling_and_tail_recursive_calls ()
rtx insn, insns;
basic_block alternate_exit = EXIT_BLOCK_PTR;
bool no_sibcalls_this_function = false;
- int successful_sibling_call = 0;
- int replaced_call_placeholder = 0;
+ bool successful_replacement = false;
+ bool replaced_call_placeholder = false;
edge e;
insns = get_insns ();
@@ -715,10 +715,11 @@ optimize_sibling_and_tail_recursive_calls ()
/* Select a set of insns to implement the call and emit them.
Tail recursion is the most efficient, so select it over
a tail/sibling call. */
- if (sibcall)
- successful_sibling_call = 1;
- replaced_call_placeholder = 1;
+ if (sibcall || tailrecursion)
+ successful_replacement = true;
+ replaced_call_placeholder = true;
+
replace_call_placeholder (insn,
tailrecursion != 0
? sibcall_use_tail_recursion
@@ -728,7 +729,7 @@ optimize_sibling_and_tail_recursive_calls ()
}
}
- if (successful_sibling_call)
+ if (successful_replacement)
{
rtx insn;
tree arg;
diff --git a/contrib/gcc/toplev.c b/contrib/gcc/toplev.c
index efc7c973ac41..d2732ce0e2de 100644
--- a/contrib/gcc/toplev.c
+++ b/contrib/gcc/toplev.c
@@ -879,6 +879,10 @@ int align_labels_max_skip;
int align_functions;
int align_functions_log;
+/* Like align_functions_log above, but used by front-ends to force the
+ minimum function alignment. Zero means no alignment is forced. */
+int force_align_functions_log;
+
/* Table of supported debugging formats. */
static const struct
{
@@ -3016,13 +3020,13 @@ rest_of_compilation (decl)
block. The loop infrastructure does the real job for us. */
flow_loops_find (&loops, LOOP_TREE);
+ if (rtl_dump_file)
+ flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
+
/* Estimate using heuristics if no profiling info is available. */
if (flag_guess_branch_prob)
estimate_probability (&loops);
- if (rtl_dump_file)
- flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
-
flow_loops_free (&loops);
}
life_analysis (insns, rtl_dump_file, PROP_FINAL);
diff --git a/contrib/gcc/tree.h b/contrib/gcc/tree.h
index 9346f7da60f7..084c3065cbd3 100644
--- a/contrib/gcc/tree.h
+++ b/contrib/gcc/tree.h
@@ -2052,6 +2052,33 @@ extern tree integer_types[itk_none];
#define long_long_unsigned_type_node integer_types[itk_unsigned_long_long]
+/* A pointer-to-function member type looks like:
+
+ struct {
+ __P __pfn;
+ ptrdiff_t __delta;
+ };
+
+ If __pfn is NULL, it is a NULL pointer-to-member-function.
+
+ (Because the vtable is always the first thing in the object, we
+ don't need its offset.) If the function is virtual, then PFN is
+ one plus twice the index into the vtable; otherwise, it is just a
+ pointer to the function.
+
+ Unfortunately, using the lowest bit of PFN doesn't work in
+ architectures that don't impose alignment requirements on function
+ addresses, or that use the lowest bit to tell one ISA from another,
+ for example. For such architectures, we use the lowest bit of
+ DELTA instead of the lowest bit of the PFN, and DELTA will be
+ multiplied by 2. */
+
+enum ptrmemfunc_vbit_where_t
+{
+ ptrmemfunc_vbit_in_pfn,
+ ptrmemfunc_vbit_in_delta
+};
+
#define NULL_TREE (tree) NULL
/* Approximate positive square root of a host double. This is for
diff --git a/contrib/gcc/unroll.c b/contrib/gcc/unroll.c
index 032d675a3b65..83327c7ba4cf 100644
--- a/contrib/gcc/unroll.c
+++ b/contrib/gcc/unroll.c
@@ -1188,6 +1188,9 @@ unroll_loop (loop, insn_count, strength_reduce_p)
/* Keep track of the unroll factor for the loop. */
loop_info->unroll_number = unroll_number;
+ /* And whether the loop has been preconditioned. */
+ loop_info->preconditioned = loop_preconditioned;
+
/* For each biv and giv, determine whether it can be safely split into
a different variable for each unrolled copy of the loop body.
We precalculate and save this info here, since computing it is
@@ -2868,7 +2871,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
value = tem;
}
- splittable_regs[REGNO (v->new_reg)] = value;
+ splittable_regs[reg_or_subregno (v->new_reg)] = value;
}
else
{
@@ -3047,21 +3050,21 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
itself does not have to be splittable. */
if (v->same && v->same->giv_type == DEST_REG)
- addr_combined_regs[REGNO (v->same->new_reg)] = v->same;
+ addr_combined_regs[reg_or_subregno (v->same->new_reg)] = v->same;
if (GET_CODE (v->new_reg) == REG)
{
/* This giv maybe hasn't been combined with any others.
Make sure that it's giv is marked as splittable here. */
- splittable_regs[REGNO (v->new_reg)] = value;
+ splittable_regs[reg_or_subregno (v->new_reg)] = value;
/* Make it appear to depend upon itself, so that the
giv will be properly split in the main loop above. */
if (! v->same)
{
v->same = v;
- addr_combined_regs[REGNO (v->new_reg)] = v;
+ addr_combined_regs[reg_or_subregno (v->new_reg)] = v;
}
}
@@ -3098,7 +3101,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
if (! v->ignore)
count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count;
- splittable_regs_updates[REGNO (v->new_reg)] = count;
+ splittable_regs_updates[reg_or_subregno (v->new_reg)] = count;
}
result++;
diff --git a/contrib/gcc/varasm.c b/contrib/gcc/varasm.c
index 4c27011bc8c7..9e683a54edeb 100644
--- a/contrib/gcc/varasm.c
+++ b/contrib/gcc/varasm.c
@@ -1194,6 +1194,8 @@ assemble_start_function (decl, fnname)
/* Tell assembler to move to target machine's alignment for functions. */
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
+ if (align < force_align_functions_log)
+ align = force_align_functions_log;
if (align > 0)
{
ASM_OUTPUT_ALIGN (asm_out_file, align);
diff --git a/contrib/gcc/version.c b/contrib/gcc/version.c
index 696fa5aeeb04..0ca60deab149 100644
--- a/contrib/gcc/version.c
+++ b/contrib/gcc/version.c
@@ -1,4 +1,4 @@
#include "ansidecl.h"
#include "version.h"
-const char *const version_string = "3.2.1 20020916 (prerelease)";
+const char *const version_string = "3.2.1 20021009 (prerelease)";