[llvm-commits] CVS: gcc-3.4/gcc/Makefile.in alias.c builtins.c c-common.c c-common.h c-decl.c c-lang.c c-lex.c c-pragma.c c-pretty-print.c c-semantics.c c-typeck.c calls.c cgraphunit.c dwarf2out.c emit-rtl.c expr.c fold-const.c function.c gcc.c integrate.c langhooks-def.h langhooks.c langhooks.h llvm-expand.c llvm-out.c llvm-out.h loop.c opts.c stmt.c toplev.c tree-optimize.c tree.c tree.def tree.h varasm.c version.c configure.frag

John Criswell criswell at cs.uiuc.edu
Thu Feb 5 10:10:11 PST 2004


Changes in directory gcc-3.4/gcc:

Makefile.in updated: 1.2 -> 1.3
alias.c updated: 1.2 -> 1.3
builtins.c updated: 1.2 -> 1.3
c-common.c updated: 1.2 -> 1.3
c-common.h updated: 1.2 -> 1.3
c-decl.c updated: 1.2 -> 1.3
c-lang.c updated: 1.2 -> 1.3
c-lex.c updated: 1.2 -> 1.3
c-pragma.c updated: 1.3 -> 1.4
c-pretty-print.c updated: 1.1.1.2 -> 1.2
c-semantics.c updated: 1.2 -> 1.3
c-typeck.c updated: 1.2 -> 1.3
calls.c updated: 1.2 -> 1.3
cgraphunit.c updated: 1.1.1.3 -> 1.2
dwarf2out.c updated: 1.2 -> 1.3
emit-rtl.c updated: 1.2 -> 1.3
expr.c updated: 1.2 -> 1.3
fold-const.c updated: 1.2 -> 1.3
function.c updated: 1.2 -> 1.3
gcc.c updated: 1.2 -> 1.3
integrate.c updated: 1.2 -> 1.3
langhooks-def.h updated: 1.2 -> 1.3
langhooks.c updated: 1.2 -> 1.3
langhooks.h updated: 1.2 -> 1.3
llvm-expand.c updated: 1.7 -> 1.8
llvm-out.c updated: 1.1 -> 1.2
llvm-out.h updated: 1.2 -> 1.3
loop.c updated: 1.2 -> 1.3
opts.c updated: 1.2 -> 1.3
stmt.c updated: 1.2 -> 1.3
toplev.c updated: 1.3 -> 1.4
tree-optimize.c updated: 1.1.1.1 -> 1.2
tree.c updated: 1.2 -> 1.3
tree.def updated: 1.2 -> 1.3
tree.h updated: 1.2 -> 1.3
varasm.c updated: 1.2 -> 1.3
version.c updated: 1.2 -> 1.3
configure.frag (r1.1.1.1) removed

---
Log message:

Commit of merge from September 24, 2003 of mainline GCC.  This merge now
works reasonably on Linux/x86 and probably works on Solaris/Sparc.



---
Diffs of the changes:  (+2028 -1933)

Index: gcc-3.4/gcc/Makefile.in
diff -u gcc-3.4/gcc/Makefile.in:1.2 gcc-3.4/gcc/Makefile.in:1.3
--- gcc-3.4/gcc/Makefile.in:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/Makefile.in	Thu Feb  5 10:05:44 2004
@@ -186,7 +186,6 @@
 FLEXFLAGS =
 AR = ar
 AR_FLAGS = rc
-DLLTOOL = dlltool
 RANLIB = @RANLIB@
 
 # -------------------------------------------
@@ -223,6 +222,7 @@
 
 # Make sure the $(MAKE) variable is defined.
 @SET_MAKE@
+REMAKEFLAGS=LANGUAGES="$(LANGUAGES)" BOOT_CFLAGS="$(BOOT_CFLAGS)"
 
 # --------
 # UNSORTED
@@ -336,8 +336,8 @@
 # each of $(system_prefix)/usr/include, $(system_prefix)/usr/lib, etc.
 TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT@
 
-xmake_file=@dep_host_xmake_file@
-tmake_file=@dep_tmake_file@
+xmake_file=@xmake_file@
+tmake_file=@tmake_file@
 out_file=$(srcdir)/config/@out_file@
 out_object_file=@out_object_file@
 md_file=$(srcdir)/config/@md_file@
@@ -661,12 +661,16 @@
 DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H)
 C_PRETTY_PRINT_H = $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H)
 
-# sed inserts variable overrides after the following line.
-####target overrides
- at target_overrides@
+# target overrides
+ifneq ($(tmake_file),)
+include $(tmake_file)
+endif
+
+# host overrides
+ifneq ($(xmake_file),)
+include $(xmake_file)
+endif
 
-####host overrides
- at host_overrides@
 #
 # Now figure out from those variables how to compile and link.
 
@@ -735,6 +739,7 @@
 # Support for additional languages (other than C).
 # C can be supported this way too (leave for later).
 
+LANG_MAKEFRAGS = @all_lang_makefrags@
 LANG_MAKEFILES = @all_lang_makefiles@
 LANG_STAGESTUFF = @all_stagestuff@
 
@@ -848,13 +853,13 @@
  reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o	   \
  sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o	   \
  sibcall.o simplify-rtx.o sreal.o ssa.o ssa-ccp.o ssa-dce.o stmt.o	   \
- stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
+ stor-layout.o stringpool.o targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
  unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o		   \
  alloc-pool.o et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) $(LLVM_OBJS)
 
 OBJS-md = $(out_object_file)
 OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) hashtable.o tree-inline.o	   \
-  cgraph.o cgraphunit.o
+  tree-optimize.o cgraph.o cgraphunit.o
 
 OBJS = $(OBJS-common) $(out_object_file) $(OBJS-archive)
 
@@ -926,27 +931,24 @@
 # targets).  The name of each hooked is "lang.${target_name}" (eg: lang.info).
 # Configure computes and adds these here.
 
-####language hooks
+# language hooks, generated by configure
 @language_hooks@
 
-# sed inserts language fragments after the following line.
-####language fragments
- at language_fragments@
+# per-language makefile fragments
+ifneq ($(LANG_MAKEFRAGS),)
+include $(LANG_MAKEFRAGS)
+endif
 
-# End of language makefile fragments.
 #
 
 # -----------------------------
 # Rebuilding this configuration
 # -----------------------------
 
-Makefile: $(srcdir)/Makefile.in config.status $(srcdir)/version.c \
-   $(xmake_file) $(tmake_file) $(LANG_MAKEFILES)
-	$(SHELL) $(srcdir)/configure.frag $(srcdir) "$(SUBDIRS)" \
-		"$(xmake_file)" "$(tmake_file)"
-	cp config.status config.run
-	LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.run
-	rm -f config.run
+Makefile: config.status $(srcdir)/Makefile.in $(srcdir)/version.c
+	LANGUAGES="$(CONFIG_LANGUAGES)" \
+	CONFIG_HEADERS= \
+	CONFIG_FILES=$@ $(SHELL) config.status
 
 config.h: cs-config.h ; @true
 bconfig.h: cs-bconfig.h ; @true
@@ -1015,7 +1017,9 @@
 @MAINT@	echo timestamp > $(srcdir)/cstamp-h.in
 auto-host.h: cstamp-h ; @true
 cstamp-h: config.in config.status
-	CONFIG_HEADERS=auto-host.h:config.in LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
+	CONFIG_HEADERS=auto-host.h:config.in \
+	CONFIG_FILES= \
+	LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
 
 # Really, really stupid make features, such as SUN's KEEP_STATE, may force
 # a target to build even if it is up-to-date.  So we must verify that
@@ -1295,7 +1299,7 @@
 c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(C_TREE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) $(EXPR_H) $(C_TREE_H) \
     flags.h toplev.h tree-inline.h $(DIAGNOSTIC_H) $(VARRAY_H) \
-    langhooks.h $(GGC_H) gt-c-objc-common.h $(TARGET_H) cgraph.h
+    langhooks.h $(GGC_H) $(TARGET_H) cgraph.h
 c-aux-info.o : c-aux-info.c  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(C_TREE_H) flags.h toplev.h
 c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -1408,8 +1412,6 @@
 
 gencheck.o : gencheck.c gencheck.h tree.def $(BCONFIG_H) $(SYSTEM_H) \
 	coretypes.h $(GTM_H) $(lang_tree_files)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
-	  $(srcdir)/gencheck.c $(OUTPUT_OPTION)
 
 gencheck.h : s-gencheck ; @true
 s-gencheck : Makefile
@@ -1468,17 +1470,20 @@
 
 langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) toplev.h \
    tree-inline.h $(RTL_H) insn-config.h $(INTEGRATE_H) langhooks.h \
-   $(LANGHOOKS_DEF_H) flags.h $(GGC_H) gt-langhooks.h
+   $(LANGHOOKS_DEF_H) flags.h $(GGC_H) gt-langhooks.h diagnostic.h
 tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h function.h \
    toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
    real.h gt-tree.h
 tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(C_TREE_H) flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
    $(EXPR_H) $(SPLAY_TREE_H) tree-dump.h
-tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
-   $(RTL_H) $(EXPR_H) flags.h $(PARAMS_H) input.h insn-config.h $(INTEGRATE_H) \
-   $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h langhooks.h \
-   $(C_COMMON_H) tree-inline.h cgraph.h
+tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   $(TREE_H) $(RTL_H) $(EXPR_H) flags.h $(PARAMS_H) input.h insn-config.h \
+   $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
+   langhooks.h $(C_COMMON_H) tree-inline.h cgraph.h intl.h
+tree-optimize.o : tree-optimize.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   $(TREE_H) toplev.h langhooks.h cgraph.h $(TIMEVAR_H) function.h $(GGC_H)
+
 print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(GGC_H) langhooks.h real.h
 stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -1492,6 +1497,10 @@
 opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \
 	coretypes.h $(TREE_H) $(TM_H) $(LANGHOOKS_H) $(GGC_H) $(RTL_H) \
 	output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h
+targhooks.o : targhooks.c targhooks.h $(CONFIG_H) $(SYSTEM_H) \
+	coretypes.h $(TREE_H) $(TM_H) $(RTL_H) $(TM_P_H) function.h \
+	output.h toplev.h
+
 toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
    function.h flags.h xcoffout.h input.h $(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) \
    debug.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h \
@@ -1530,16 +1539,16 @@
 function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    flags.h function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
    insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
-   $(TM_P_H) langhooks.h gt-function.h
+   $(TM_P_H) langhooks.h gt-function.h $(TARGET_H)
 stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
    function.h insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
    $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
-   langhooks.h $(PREDICT_H) gt-stmt.h $(OPTABS_H)
-except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
-   flags.h except.h function.h $(EXPR_H) libfuncs.h $(INTEGRATE_H) langhooks.h \
-   insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
+   langhooks.h $(PREDICT_H) gt-stmt.h $(OPTABS_H) $(TARGET_H)
+except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+   $(TREE_H) flags.h except.h function.h $(EXPR_H) libfuncs.h $(INTEGRATE_H) \
+   langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
    dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H) \
-   gt-except.h
+   gt-except.h cgraph.h
 expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
    function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) libfuncs.h $(INSN_ATTR_H) insn-config.h \
    $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
@@ -1700,7 +1709,7 @@
 et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.h alloc-pool.h
 combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
    function.h insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
-   $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H)
+   $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H)
 regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    hard-reg-set.h flags.h $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h \
    real.h toplev.h function.h output.h $(GGC_H) $(TM_P_H) $(EXPR_H) $(TIMEVAR_H)
@@ -1884,8 +1893,6 @@
 
 dummy-conditions.o : dummy-conditions.c $(BCONFIG_H) $(SYSTEM_H) \
   coretypes.h $(GTM_H) gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
-	    $(srcdir)/dummy-conditions.c $(OUTPUT_OPTION)
 
 insn-flags.h: s-flags ; @true
 s-flags : $(md_file) genflags$(build_exeext) $(srcdir)/move-if-change
@@ -2044,7 +2051,7 @@
 gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h \
 gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
 gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
-gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
+gt-c-pragma.h gtype-c.h gt-input.h gt-cfglayout.h \
 gt-stringpool.h gt-langhooks.h : s-gtype ; @true
 
 gtyp-gen.h: Makefile
@@ -2089,43 +2096,43 @@
 # about the target machine.  They do depend on config.h itself,
 # since that describes the host machine.
 
+# The names of programs that run on the "build" machine.
+genprognames=genconfig genflags gencodes genemit genopinit genrecog \
+	     genextract genpeep genattr genoutput
+
+# The names of the executable files for those programs.
+genprogs=$(genprognames:%=%$(build_exeext))
+
+# Object files used in those programs.
+genobjs=$(genprognames:%=%.o) read-rtl.o gensupport.o genattrtab.o \
+        genautomata.o gengenrtl.o genpreds.o gengtype.o \
+	genconstants.o gen-protos.o scan.o fix-header.o scan-decls.o \
+	gencheck.o dummy-conditions.o genconditions.o
+
+$(genprogs): %$(build_exeext): %.o  $(BUILD_RTL) $(BUILD_SUPPORT) \
+			       $(BUILD_PRINT) $(BUILD_ERRORS) \
+	                       $(BUILD_LIBDEPS)
+	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+		$< $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
+		$(BUILD_ERRORS) $(BUILD_LIBS)
+
+$(genobjs): %.o : %.c
+	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+
 read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) \
   $(OBSTACK_H) $(HASHTAB_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/read-rtl.c $(OUTPUT_OPTION)
 
 gensupport.o: gensupport.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) \
   $(OBSTACK_H) errors.h $(HASHTAB_H) gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/gensupport.c $(OUTPUT_OPTION)
-
-genconfig$(build_exeext) : genconfig.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	  genconfig.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genconfig.o : genconfig.c $(RTL_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genconfig.c $(OUTPUT_OPTION)
-
-genflags$(build_exeext) : genflags.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genflags.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genflags.o : genflags.c $(RTL_H) $(OBSTACK_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genflags.c $(OUTPUT_OPTION)
-
-gencodes$(build_exeext) : gencodes.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 gencodes.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 gencodes.o : gencodes.c $(RTL_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/gencodes.c $(OUTPUT_OPTION)
 
 genconstants$(build_exeext) : genconstants.o $(BUILD_RTL) $(BUILD_EARLY_SUPPORT) \
   $(BUILD_ERRORS) $(BUILD_LIBDEPS)
@@ -2135,67 +2142,24 @@
 
 genconstants.o : genconstants.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
   errors.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genconstants.c $(OUTPUT_OPTION)
-
-genemit$(build_exeext) : genemit.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genemit.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genemit.o : genemit.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
   errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genemit.c $(OUTPUT_OPTION)
-
-genopinit$(build_exeext) : genopinit.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genopinit.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genopinit.o : genopinit.c $(RTL_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genopinit.c $(OUTPUT_OPTION)
-
-genrecog$(build_exeext) : genrecog.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-    $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genrecog.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genrecog.o : genrecog.c $(RTL_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genrecog.c $(OUTPUT_OPTION)
-
-genextract$(build_exeext) : genextract.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genextract.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genextract.o : genextract.c $(RTL_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) insn-config.h errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genextract.c $(OUTPUT_OPTION)
-
-genpeep$(build_exeext) : genpeep.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genpeep.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genpeep.o : genpeep.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
   errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genpeep.c $(OUTPUT_OPTION)
-
-genattr$(build_exeext) : genattr.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genattr.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genattr.o : genattr.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h \
   gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genattr.c $(OUTPUT_OPTION)
 
 genattrtab$(build_exeext) : genattrtab.o genautomata.o \
   $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_VARRAY) \
@@ -2207,21 +2171,12 @@
 
 genattrtab.o : genattrtab.c $(RTL_H) $(OBSTACK_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(GGC_H) gensupport.h genattrtab.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c $(OUTPUT_OPTION)
 
 genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h varray.h genattrtab.h $(HASHTAB_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genautomata.c $(OUTPUT_OPTION)
-
-genoutput$(build_exeext) : genoutput.o $(BUILD_RTL) $(BUILD_SUPPORT) \
-  $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
-	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
-	 genoutput.o $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
-	    $(BUILD_ERRORS) $(BUILD_LIBS)
 
 genoutput.o : genoutput.c $(RTL_H) $(BCONFIG_H) \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genoutput.c $(OUTPUT_OPTION)
 
 gengenrtl$(build_exeext) : gengenrtl.o $(BUILD_LIBDEPS)
 	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
@@ -2229,14 +2184,12 @@
 
 gengenrtl.o : gengenrtl.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
   $(GTM_H) real.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/gengenrtl.c $(OUTPUT_OPTION)
 
 genpreds$(build_exeext) : genpreds.o $(BUILD_LIBDEPS)
 	$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
 	 genpreds.o $(BUILD_LIBS)
 
 genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/genpreds.c $(OUTPUT_OPTION)
 
 gengtype$(build_exeext) : gengtype.o gengtype-lex.o gengtype-yacc.o \
   $(BUILD_LIBDEPS)
@@ -2245,8 +2198,6 @@
 
 gengtype.o : gengtype.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
   real.h $(RTL_BASE_H) gtyp-gen.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
-	  $(srcdir)/gengtype.c $(OUTPUT_OPTION)
 
 gengtype-lex.o : $(parsedir)/gengtype-lex.c gengtype.h $(parsedir)/gengtype-yacc.c \
   $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H)
@@ -2286,8 +2237,6 @@
 
 genconditions.o : genconditions.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
   $(GTM_H) errors.h
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
-		$(srcdir)/genconditions.c $(OUTPUT_OPTION)
 
 #
 # Compile the libraries to be used by gen*.
@@ -2587,10 +2536,8 @@
 	  $(GEN_PROTOS_OBJS) $(BUILD_LIBS)
 
 gen-protos.o: gen-protos.c scan.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c $(OUTPUT_OPTION)
 
 scan.o: scan.c scan.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/scan.c $(OUTPUT_OPTION)
 
 xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos$(build_exeext) Makefile
 	sed -e s/TARGET_GETGROUPS_T/$(TARGET_GETGROUPS_T)/ \
@@ -2611,10 +2558,8 @@
 
 fix-header.o: fix-header.c $(OBSTACK_H) scan.h \
 	xsys-protos.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(CPPLIB_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c $(OUTPUT_OPTION)
 
 scan-decls.o: scan-decls.c scan.h $(CPPLIB_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
-	$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/scan-decls.c $(OUTPUT_OPTION)
 
 # stmp-fixproto depends on this, not on fix-header directly.
 # The idea is to make sure fix-header gets built,
@@ -2688,99 +2633,55 @@
 
 TEXI_CPPINT_FILES = $(docdir)/cppinternals.texi
 
-$(docobjdir)/cpp.info: $(TEXI_CPP_FILES) stmp-docobjdir
-	$(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) -I $(docdir)/include \
-	  -o $@ $(docdir)/cpp.texi
+$(docobjdir)/cpp.info cpp.dvi: $(TEXI_CPP_FILES)
+$(docobjdir)/gcc.info gcc.dvi: $(TEXI_GCC_FILES)
+$(docobjdir)/gccint.info gccint.dvi: $(TEXI_GCCINT_FILES)
+$(docobjdir)/gccinstall.info gccinstall.dvi: $(TEXI_GCCINSTALL_FILES)
+$(docobjdir)/cppinternals.info cppinternals.dvi: $(TEXI_CPPINT_FILES)
 
-$(docobjdir)/gcc.info: $(TEXI_GCC_FILES) stmp-docobjdir
+$(docobjdir)/%.info: $(docdir)/%.texi stmp-docobjdir
 	$(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) -I $(docdir)/include \
-	  -o $@ $(docdir)/gcc.texi
-
-$(docobjdir)/gccint.info: $(TEXI_GCCINT_FILES) stmp-docobjdir
-	$(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) -I $(docdir)/include \
-	  -o $@ $(docdir)/gccint.texi
-
-$(docobjdir)/gccinstall.info: $(TEXI_GCCINSTALL_FILES) stmp-docobjdir
-	$(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) -I $(docdir)/include \
-	  -o $@ $(docdir)/install.texi
-
-$(docobjdir)/cppinternals.info: $(TEXI_CPPINT_FILES) stmp-docobjdir
-	$(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) -I $(docdir)/include \
-	  -o $@ $(docdir)/cppinternals.texi
+	  -o $@ $<
 
 dvi: gcc.dvi gccint.dvi gccinstall.dvi cpp.dvi lang.dvi cppinternals.dvi
 
-# This works with GNU Make's default rule.
-cpp.dvi: $(TEXI_CPP_FILES)
-	$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cpp.texi
-
-gcc.dvi: $(TEXI_GCC_FILES)
-	$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gcc.texi
-
-gccint.dvi: $(TEXI_GCCINT_FILES)
-	$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gccint.texi
+%.dvi: $(docdir)/%.texi
+	$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $<
 
-gccinstall.dvi: $(TEXI_GCCINSTALL_FILES)
+gccinstall.dvi:
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
 	$(TEXI2DVI) -I $$s/doc -I $$s/doc/include -o $@ $$s/doc/install.texi
 
-cppinternals.dvi: $(TEXI_CPPINT_FILES)
-	$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cppinternals.texi
-
 generated-manpages: $(docobjdir)/gcov.1 $(docobjdir)/cpp.1 $(docobjdir)/gcc.1 \
-	 $(docobjdir)/gfdl.7 $(docobjdir)/gpl.7 $(docobjdir)/fsf-funding.7 \
-	 lang.generated-manpages
-
-$(docobjdir)/gcov.1: $(docdir)/gcov.texi stmp-docobjdir
-	$(STAMP) $(docobjdir)/gcov.1
-	-$(TEXI2POD) $(docdir)/gcov.texi > gcov.pod
-	-($(POD2MAN) --section=1 gcov.pod > $(docobjdir)/gcov.1.T$$$$ && \
-		mv -f $(docobjdir)/gcov.1.T$$$$ $(docobjdir)/gcov.1) || \
-		(rm -f $(docobjdir)/gcov.1.T$$$$ && exit 1)
-	-rm -f gcov.pod
+	$(docobjdir)/gfdl.7 $(docobjdir)/gpl.7 $(docobjdir)/fsf-funding.7 \
+	lang.generated-manpages
 
+$(docobjdir)/gcov.1: $(docdir)/gcov.texi
 $(docobjdir)/cpp.1: $(docdir)/cpp.texi $(docdir)/cppenv.texi \
-  $(docdir)/cppopts.texi stmp-docobjdir
-	$(STAMP) $(docobjdir)/cpp.1
-	-$(TEXI2POD) $(docdir)/cpp.texi > cpp.pod
-	-($(POD2MAN) --section=1 cpp.pod > $(docobjdir)/cpp.1.T$$$$ && \
-		mv -f $(docobjdir)/cpp.1.T$$$$ $(docobjdir)/cpp.1) || \
-		(rm -f $(docobjdir)/cpp.1.T$$$$ && exit 1)
-	-rm -f cpp.pod
-
+  $(docdir)/cppopts.texi
 $(docobjdir)/gcc.1: $(docdir)/invoke.texi $(docdir)/cppenv.texi \
-  $(docdir)/cppopts.texi stmp-docobjdir
-	$(STAMP) $(docobjdir)/gcc.1
-	-$(TEXI2POD) $(docdir)/invoke.texi > gcc.pod
-	-($(POD2MAN) --section=1 gcc.pod > $(docobjdir)/gcc.1.T$$$$ && \
-		mv -f $(docobjdir)/gcc.1.T$$$$ $(docobjdir)/gcc.1) || \
-		(rm -f $(docobjdir)/gcc.1.T$$$$ && exit 1)
-	-rm -f gcc.pod
-
-$(docobjdir)/gfdl.7: $(docdir)/include/fdl.texi stmp-docobjdir
-	$(STAMP) $(docobjdir)/gfdl.7
-	-$(TEXI2POD) $(docdir)/include/fdl.texi > gfdl.pod
-	-($(POD2MAN) --section=7 gfdl.pod > $(docobjdir)/gfdl.7.T$$$$ && \
-		mv -f $(docobjdir)/gfdl.7.T$$$$ $(docobjdir)/gfdl.7) || \
-		(rm -f $(docobjdir)/gfdl.7.T$$$$ && exit 1)
-	-rm -f gfdl.pod
-
-$(docobjdir)/gpl.7: $(docdir)/include/gpl.texi stmp-docobjdir
-	$(STAMP) $(docobjdir)/gpl.7
-	-$(TEXI2POD) $(docdir)/include/gpl.texi > gpl.pod
-	-($(POD2MAN) --section=7 gpl.pod > $(docobjdir)/gpl.7.T$$$$ && \
-		mv -f $(docobjdir)/gpl.7.T$$$$ $(docobjdir)/gpl.7) || \
-		(rm -f $(docobjdir)/gpl.7.T$$$$ && exit 1)
-	-rm -f gpl.pod
-
-$(docobjdir)/fsf-funding.7: $(docdir)/include/funding.texi stmp-docobjdir
-	$(STAMP) $(docobjdir)/fsf-funding.7
-	-$(TEXI2POD) $(docdir)/include/funding.texi > fsf-funding.pod
-	-($(POD2MAN) --section=7 fsf-funding.pod \
-		> $(docobjdir)/fsf-funding.7.T$$$$ && \
-	    mv -f $(docobjdir)/fsf-funding.7.T$$$$ $(docobjdir)/fsf-funding.7) || \
-	    (rm -f $(docobjdir)/fsf-funding.7.T$$$$ && exit 1)
-	-rm -f fsf-funding.pod
+  $(docdir)/cppopts.texi
+$(docobjdir)/gfdl.7: $(docdir)/include/fdl.texi
+$(docobjdir)/gpl.7: $(docdir)/include/gpl.texi
+$(docobjdir)/fsf-funding.7: $(docdir)/include/funding.texi
+
+$(docobjdir)/%.1: $(docdir)/%.texi stmp-docobjdir
+	$(STAMP) $@
+	-$(TEXI2POD) $< > $(basename $(notdir $@)).pod
+	-($(POD2MAN) --section=1 \
+			$(basename $(notdir $@)).pod > $(@).T$$$$ && \
+		mv -f $(@).T$$$$ $@) || \
+		(rm -f $(@).T$$$$ && exit 1)
+	-rm -f $(basename $(notdir $@)).pod
+
+$(docobjdir)/%.7: $(docdir)/%.texi stmp-docobjdir
+	$(STAMP) $@
+	-$(TEXI2POD) $< > $(basename $(notdir $@)).pod
+	-($(POD2MAN) --section=7 \
+			$(basename $(notdir $@)).pod > $(@).T$$$$ && \
+		mv -f $(@).T$$$$ $@) || \
+		(rm -f $(@).T$$$$ && exit 1)
+	-rm -f $(basename $(notdir $@)).pod
 
 #
 # Deletion of files made during compilation.
@@ -3319,7 +3220,7 @@
 	-rm -f $@
 	sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)|' < site.exp > $@
 
-check-g++: $(TESTSUITEDIR)/site.exp
+check-g++ check-gcc check-g77 check-objc: check-% : $(TESTSUITEDIR)/site.exp
 	-(rootme=`${PWD_COMMAND}`; export rootme; \
 	srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
 	cd $(TESTSUITEDIR); \
@@ -3327,37 +3228,7 @@
 	if [ -f $${rootme}/../expect/expect ] ; then  \
 	   TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
 	    export TCL_LIBRARY ; fi ; \
-	$(RUNTEST) --tool g++ $(RUNTESTFLAGS))
-
-check-gcc: $(TESTSUITEDIR)/site.exp
-	-(rootme=`${PWD_COMMAND}`; export rootme; \
-	srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-	cd $(TESTSUITEDIR); \
-	EXPECT=${EXPECT} ; export EXPECT ; \
-	if [ -f $${rootme}/../expect/expect ] ; then  \
-	   TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-	   export TCL_LIBRARY ; fi ; \
-	$(RUNTEST) --tool gcc $(RUNTESTFLAGS))
-
-check-g77: $(TESTSUITEDIR)/site.exp
-	-(rootme=`${PWD_COMMAND}`; export rootme; \
-	srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-	cd $(TESTSUITEDIR); \
-	EXPECT=${EXPECT} ; export EXPECT ; \
-	if [ -f $${rootme}/../expect/expect ] ; then  \
-	   TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-	   export TCL_LIBRARY ; fi ; \
-	$(RUNTEST) --tool g77 $(RUNTESTFLAGS))
-
-check-objc: $(TESTSUITEDIR)/site.exp
-	-(rootme=`${PWD_COMMAND}`; export rootme; \
-	srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-	cd $(TESTSUITEDIR); \
-	EXPECT=${EXPECT} ; export EXPECT ; \
-	if [ -f $${rootme}/../expect/expect ] ; then  \
-	   TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-	    export TCL_LIBRARY ; fi ; \
-	$(RUNTEST) --tool objc $(RUNTESTFLAGS))
+	$(RUNTEST) --tool $* $(RUNTESTFLAGS))
 
 check-consistency: testsuite/site.exp
 	-rootme=`${PWD_COMMAND}`; export rootme; \
@@ -3607,22 +3478,22 @@
 	echo $${stage}_build > stage_last
 
 restage1: unstage1
-	$(MAKE) stage1_build
+	$(MAKE) $(REMAKEFLAGS) stage1_build
 
 restage2: unstage2
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stage2_build
+	$(MAKE) $(REMAKEFLAGS) stage2_build
 
 restage3: unstage3
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stage3_build
+	$(MAKE) $(REMAKEFLAGS) stage3_build
 
 restage4: unstage4
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stage4_build
+	$(MAKE) $(REMAKEFLAGS) stage4_build
 
 restageprofile: unstageprofile
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stageprofile_build
+	$(MAKE) $(REMAKEFLAGS) stageprofile_build
 
 restagefeedback: unstagefeedback
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stagefeedback_build
+	$(MAKE) $(REMAKEFLAGS) stagefeedback_build
 
 # Bubble up a bugfix through all the stages.  Primarily useful for fixing
 # bugs that cause the compiler to crash while building stage 2.
@@ -3630,31 +3501,31 @@
 	if test -f stage_last; then \
 	  LAST=`sed -e 's/_build//' < stage_last`; \
 	  if test "$$LAST" != "stage1"; then \
-	    $(MAKE) $$LAST; \
+	    $(MAKE) $(REMAKEFLAGS) $$LAST; \
 	    $(STAMP) $${LAST}_copy; \
 	  fi; \
 	fi
 	if test -f stage1_copy; then $(MAKE) unstage1; fi
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stage1_copy
+	$(MAKE) $(REMAKEFLAGS) stage1_copy
 	if test -f stage2_copy; then $(MAKE) unstage2; fi
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stage2_copy
+	$(MAKE) $(REMAKEFLAGS) stage2_copy
 	if test -f stage3_copy; then $(MAKE) unstage3; fi
-	$(MAKE) LANGUAGES="$(LANGUAGES)" stage3_build
+	$(MAKE) $(REMAKEFLAGS) stage3_build
 	if test -f stage4_copy; then \
-	  $(MAKE) stage3_copy; $(MAKE) unstage4; \
-	  $(MAKE) LANGUAGES="$(LANGUAGES)" stage4_build || exit 1; \
+	  $(MAKE) $(REMAKEFLAGS) stage3_copy; $(MAKE) unstage4; \
+	  $(MAKE) $(REMAKEFLAGS) stage4_build || exit 1; \
 	fi
 
 quickstrap:
 	if test -f stage_last ; then \
-	  LAST=`cat stage_last`; rm $$LAST; $(MAKE) BOOT_CFLAGS="$(BOOT_CFLAGS)" LANGUAGES="$(LANGUAGES)" $$LAST; \
+	  LAST=`cat stage_last`; rm $$LAST; $(MAKE) $(REMAKEFLAGS) $$LAST; \
 	else \
-	  $(MAKE) stage1_build; \
+	  $(MAKE) $(REMAKEFLAGS) stage1_build; \
 	fi
 
 cleanstrap:
 	-$(MAKE) clean
-	$(MAKE) LANGUAGES="$(LANGUAGES)" BOOT_CFLAGS="$(BOOT_CFLAGS)" bootstrap
+	$(MAKE) $(REMAKEFLAGS) bootstrap
 
 unstrap:
 	-rm -rf stage[234]*
@@ -3665,64 +3536,64 @@
 # not from scratch.
 restrap:
 	$(MAKE) unstrap
-	$(MAKE) LANGUAGES="$(LANGUAGES)" BOOT_CFLAGS="$(BOOT_CFLAGS)" bootstrap
+	$(MAKE) $(REMAKEFLAGS) bootstrap
 
-# Compare the object files in the current directory with those in the
-# stage2 directory.
-# ./ avoids bug in some versions of tail.
-slowcompare slowcompare3 slowcompare4 slowcompare-lean slowcompare3-lean slowcompare4-lean: force
+# These targets compare the object files in the current directory with
+# those in a stage directory.  We need to skip the first N bytes of
+# each object file.  The "slow" mechanism assumes nothing special
+# about cmp and uses the tail command to skip.  ./ avoids a bug in
+# some versions of tail.  The "gnu" targets use gnu cmp (diffutils
+# v2.4 or later), to avoid running tail and the overhead of twice
+# copying each object file.  Likewise, the "fast" targets use the skip
+# parameter of cmp available on some systems to accomplish the same
+# thing.  An exit status of 1 is precisely the result we're looking
+# for (other values mean other problems).
+slowcompare slowcompare3 slowcompare4 slowcompare-lean slowcompare3-lean slowcompare4-lean \
+fastcompare fastcompare3 fastcompare4 fastcompare-lean fastcompare3-lean fastcompare4-lean \
+ gnucompare  gnucompare3  gnucompare4  gnucompare-lean  gnucompare3-lean  gnucompare4-lean: force
 	-rm -f .bad_compare
-	case "$@" in slowcompare | slowcompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^slowcompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
+	case "$@" in *compare | *compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^[a-z]*compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
 	for file in *$(objext); do \
-	  tail +16c ./$$file > tmp-foo1; \
-	  tail +16c stage$$stage/$$file > tmp-foo2 \
-	    && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
-	done
-	case "$@" in slowcompare | slowcompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^slowcompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-	for dir in tmp-foo $(SUBDIRS); do \
-	  if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
-	    for file in $$dir/*$(objext); do \
+	  case "$@" in \
+	    slowcompare* ) \
 	      tail +16c ./$$file > tmp-foo1; \
 	      tail +16c stage$$stage/$$file > tmp-foo2 \
 	        && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
-	    done; \
-	  else true; fi; \
-	done
-	-rm -f tmp-foo*
-	case "$@" in slowcompare | slowcompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^slowcompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-	if [ -f .bad_compare ]; then \
-	  echo "Bootstrap comparison failure!"; \
-	  cat .bad_compare; \
-	  exit 1; \
-	else \
-	  case "$@" in \
-	    *-lean ) rm -rf stage$$stage ;; \
-	    *) ;; \
-	  esac; true; \
-	fi
-
-# Compare the object files in the current directory with those in the
-# stage2 directory.  Use gnu cmp (diffutils v2.4 or later) to avoid
-# running tail and the overhead of twice copying each object file.
-# An exit status of 1 is precisely the result we're looking for (other
-# values mean other problems).
-gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4-lean: force
-	-rm -f .bad_compare
-	case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-	for file in *$(objext); do \
-	  cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
-	  test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+	      ;; \
+	    fastcompare* ) \
+	      cmp $$file stage$$stage/$$file 16 16 > /dev/null 2>&1; \
+	      test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+	      ;; \
+	    gnucompare* ) \
+	      cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
+	      test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+	      ;; \
+	  esac ; \
 	done
-	case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
+	case "$@" in *compare | *compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^[a-z]*compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
 	for dir in tmp-foo $(SUBDIRS); do \
 	  if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
 	    for file in $$dir/*$(objext); do \
-	      cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
-	      test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+	      case "$@" in \
+		slowcompare* ) \
+		  tail +16c ./$$file > tmp-foo1; \
+		  tail +16c stage$$stage/$$file > tmp-foo2 \
+		    && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
+		  ;; \
+		fastcompare* ) \
+		  cmp $$file stage$$stage/$$file 16 16 > /dev/null 2>&1; \
+		  test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+		  ;; \
+		gnucompare* ) \
+		  cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
+		  test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+		  ;; \
+	      esac ; \
 	    done; \
 	  else true; fi; \
 	done
-	case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
+	-rm -f tmp-foo*
+	case "$@" in *compare | *compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^[a-z]*compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
 	if [ -f .bad_compare ]; then \
 	  echo "Bootstrap comparison failure!"; \
 	  cat .bad_compare; \
@@ -3730,6 +3601,7 @@
 	else \
 	  case "$@" in \
 	    *-lean ) rm -rf stage$$stage ;; \
+	    *) ;; \
 	  esac; true; \
 	fi
 


Index: gcc-3.4/gcc/alias.c
diff -u gcc-3.4/gcc/alias.c:1.2 gcc-3.4/gcc/alias.c:1.3
--- gcc-3.4/gcc/alias.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/alias.c	Thu Feb  5 10:05:44 2004
@@ -111,7 +111,7 @@
 static tree decl_for_component_ref (tree);
 static rtx adjust_offset_for_component_ref (tree, rtx);
 static int nonoverlapping_memrefs_p (rtx, rtx);
-static int write_dependence_p (rtx, rtx, int);
+static int write_dependence_p (rtx, rtx, int, int);
 
 static int nonlocal_mentioned_p_1 (rtx *, void *);
 static int nonlocal_mentioned_p (rtx);
@@ -891,10 +891,8 @@
       {
 	rtx temp = find_base_value (XEXP (src, 0));
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-	if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
+	if (temp != 0 && CONSTANT_P (temp))
 	  temp = convert_memory_address (Pmode, temp);
-#endif
 
 	return temp;
       }
@@ -1310,10 +1308,8 @@
       {
 	rtx temp = find_base_term (XEXP (x, 0));
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-	if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
+	if (temp != 0 && CONSTANT_P (temp))
 	  temp = convert_memory_address (Pmode, temp);
-#endif
 
 	return temp;
       }
@@ -2205,10 +2201,11 @@
 }
 
 /* Returns nonzero if a write to X might alias a previous read from
-   (or, if WRITEP is nonzero, a write to) MEM.  */
+   (or, if WRITEP is nonzero, a write to) MEM.  If CONSTP is nonzero,
+   honor the RTX_UNCHANGING_P flags on X and MEM.  */
 
 static int
-write_dependence_p (rtx mem, rtx x, int writep)
+write_dependence_p (rtx mem, rtx x, int writep, int constp)
 {
   rtx x_addr, mem_addr;
   rtx fixed_scalar;
@@ -2227,15 +2224,18 @@
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
 
-  /* Unchanging memory can't conflict with non-unchanging memory.  */
-  if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
-    return 0;
+  if (constp)
+    {
+      /* Unchanging memory can't conflict with non-unchanging memory.  */
+      if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
+	return 0;
 
-  /* If MEM is an unchanging read, then it can't possibly conflict with
-     the store to X, because there is at most one store to MEM, and it must
-     have occurred somewhere before MEM.  */
-  if (! writep && RTX_UNCHANGING_P (mem))
-    return 0;
+      /* If MEM is an unchanging read, then it can't possibly conflict with
+	 the store to X, because there is at most one store to MEM, and it
+	 must have occurred somewhere before MEM.  */
+      if (! writep && RTX_UNCHANGING_P (mem))
+	return 0;
+    }
 
   if (nonoverlapping_memrefs_p (x, mem))
     return 0;
@@ -2276,7 +2276,7 @@
 int
 anti_dependence (rtx mem, rtx x)
 {
-  return write_dependence_p (mem, x, /*writep=*/0);
+  return write_dependence_p (mem, x, /*writep=*/0, /*constp*/1);
 }
 
 /* Output dependence: X is written after store in MEM takes place.  */
@@ -2284,7 +2284,16 @@
 int
 output_dependence (rtx mem, rtx x)
 {
-  return write_dependence_p (mem, x, /*writep=*/1);
+  return write_dependence_p (mem, x, /*writep=*/1, /*constp*/1);
+}
+
+/* Unchanging anti dependence: Like anti_dependence but ignores
+   the UNCHANGING_RTX_P property on const variable references.  */
+
+int
+unchanging_anti_dependence (rtx mem, rtx x)
+{
+  return write_dependence_p (mem, x, /*writep=*/0, /*constp*/0);
 }
 
 /* A subroutine of nonlocal_mentioned_p, returns 1 if *LOC mentions


Index: gcc-3.4/gcc/builtins.c
diff -u gcc-3.4/gcc/builtins.c:1.2 gcc-3.4/gcc/builtins.c:1.3
--- gcc-3.4/gcc/builtins.c:1.2	Fri Jan  9 10:54:24 2004
+++ gcc-3.4/gcc/builtins.c	Thu Feb  5 10:05:44 2004
@@ -79,11 +79,6 @@
    required to implement the function call in all cases.  */
 tree implicit_built_in_decls[(int) END_BUILTINS];
 
-/* Trigonometric and mathematical constants used in builtin folding.  */
-static bool builtin_dconsts_init = 0;
-static REAL_VALUE_TYPE dconstpi;
-static REAL_VALUE_TYPE dconste;
-
 static int get_pointer_alignment (tree, unsigned int);
 static tree c_strlen (tree, int);
 static const char *c_getstr (tree);
@@ -157,27 +152,12 @@
 static bool readonly_data_expr (tree);
 static rtx expand_builtin_fabs (tree, rtx, rtx);
 static rtx expand_builtin_cabs (tree, rtx);
-static void init_builtin_dconsts (void);
 static tree fold_builtin_cabs (tree, tree, tree);
 static tree fold_builtin_trunc (tree);
 static tree fold_builtin_floor (tree);
 static tree fold_builtin_ceil (tree);
 static tree fold_builtin_bitop (tree);
 
-/* Initialize mathematical constants for constant folding builtins.
-   These constants need to be given to at least 160 bits precision.  */
-
-static void
-init_builtin_dconsts (void)
-{
-  real_from_string (&dconstpi,
-    "3.1415926535897932384626433832795028841971693993751058209749445923078");
-  real_from_string (&dconste,
-    "2.7182818284590452353602874713526624977572470936999595749669676277241");
-
-  builtin_dconsts_init = true;
-}
-
 /* Return the alignment in bits of EXP, a pointer valued expression.
    But don't return more than MAX_ALIGN no matter what.
    The alignment returned is, by default, the alignment of the thing that
@@ -497,10 +477,7 @@
   if (setjmp_alias_set == -1)
     setjmp_alias_set = new_alias_set ();
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (buf_addr) != Pmode)
-    buf_addr = convert_memory_address (Pmode, buf_addr);
-#endif
+  buf_addr = convert_memory_address (Pmode, buf_addr);
 
   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
 
@@ -639,10 +616,11 @@
 
   expand_builtin_setjmp_setup (buf_addr, next_lab);
 
-  /* Set TARGET to zero and branch to the continue label.  */
+  /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
+     ensure that pending stack adjustments are flushed.  */
   emit_move_insn (target, const0_rtx);
-  emit_jump_insn (gen_jump (cont_lab));
-  emit_barrier ();
+  emit_jump (cont_lab);
+
   emit_label (next_lab);
 
   expand_builtin_setjmp_receiver (next_lab);
@@ -680,10 +658,7 @@
   if (setjmp_alias_set == -1)
     setjmp_alias_set = new_alias_set ();
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (buf_addr) != Pmode)
-    buf_addr = convert_memory_address (Pmode, buf_addr);
-#endif
+  buf_addr = convert_memory_address (Pmode, buf_addr);
 
   buf_addr = force_reg (Pmode, buf_addr);
 
@@ -826,10 +801,7 @@
 	      insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
 	  || (GET_MODE (op0) != Pmode))
 	{
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (op0) != Pmode)
-	    op0 = convert_memory_address (Pmode, op0);
-#endif
+	  op0 = convert_memory_address (Pmode, op0);
 	  op0 = force_reg (Pmode, op0);
 	}
       emit_insn (gen_prefetch (op0, op1, op2));
@@ -852,10 +824,7 @@
   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
   rtx mem;
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (addr) != Pmode)
-    addr = convert_memory_address (Pmode, addr);
-#endif
+  addr = convert_memory_address (Pmode, addr);
 
   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
 
@@ -940,7 +909,7 @@
 
       /* The second value is the structure value address unless this is
 	 passed as an "invisible" first argument.  */
-      if (struct_value_rtx)
+      if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
 	size += GET_MODE_SIZE (Pmode);
 
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -1115,6 +1084,7 @@
   rtx registers;
   int size, align, regno;
   enum machine_mode mode;
+  rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
 
   /* Create a block where the arg-pointer, structure value address,
      and argument registers can be saved.  */
@@ -1122,7 +1092,7 @@
 
   /* Walk past the arg-pointer and structure value address.  */
   size = GET_MODE_SIZE (Pmode);
-  if (struct_value_rtx)
+  if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
     size += GET_MODE_SIZE (Pmode);
 
   /* Save each register used in calling a function to the block.  */
@@ -1148,10 +1118,10 @@
 
   /* Save the structure value address unless this is passed as an
      "invisible" first argument.  */
-  if (struct_value_incoming_rtx)
+  if (struct_incoming_value)
     {
       emit_move_insn (adjust_address (registers, Pmode, size),
-		      copy_to_reg (struct_value_incoming_rtx));
+		      copy_to_reg (struct_incoming_value));
       size += GET_MODE_SIZE (Pmode);
     }
 
@@ -1209,11 +1179,9 @@
   rtx incoming_args, result, reg, dest, src, call_insn;
   rtx old_stack_level = 0;
   rtx call_fusage = 0;
+  rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (arguments) != Pmode)
-    arguments = convert_memory_address (Pmode, arguments);
-#endif
+  arguments = convert_memory_address (Pmode, arguments);
 
   /* Create a block where the return registers can be saved.  */
   result = assign_stack_local (BLKmode, apply_result_size (), -1);
@@ -1262,7 +1230,7 @@
 
   /* Walk past the arg-pointer and structure value address.  */
   size = GET_MODE_SIZE (Pmode);
-  if (struct_value_rtx)
+  if (struct_value)
     size += GET_MODE_SIZE (Pmode);
 
   /* Restore each of the registers previously saved.  Make USE insns
@@ -1282,13 +1250,13 @@
   /* Restore the structure value address unless this is passed as an
      "invisible" first argument.  */
   size = GET_MODE_SIZE (Pmode);
-  if (struct_value_rtx)
+  if (struct_value)
     {
       rtx value = gen_reg_rtx (Pmode);
       emit_move_insn (value, adjust_address (arguments, Pmode, size));
-      emit_move_insn (struct_value_rtx, value);
-      if (GET_CODE (struct_value_rtx) == REG)
-	use_reg (&call_fusage, struct_value_rtx);
+      emit_move_insn (struct_value, value);
+      if (GET_CODE (struct_value) == REG)
+	use_reg (&call_fusage, struct_value);
       size += GET_MODE_SIZE (Pmode);
     }
 
@@ -1351,7 +1319,8 @@
   OK_DEFER_POP;
 
   /* Return the address of the result block.  */
-  return copy_addr_to_reg (XEXP (result, 0));
+  result = copy_addr_to_reg (XEXP (result, 0));
+  return convert_memory_address (ptr_mode, result);
 }
 
 /* Perform an untyped return.  */
@@ -1364,10 +1333,7 @@
   rtx reg;
   rtx call_fusage = 0;
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (result) != Pmode)
-    result = convert_memory_address (Pmode, result);
-#endif
+  result = convert_memory_address (Pmode, result);
 
   apply_result_size ();
   result = gen_rtx_MEM (BLKmode, result);
@@ -1462,7 +1428,11 @@
 
   /* We have taken care of the easy cases during constant folding.  This
      case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
-     get a chance to see if it can deduce whether ARGLIST is constant.  */
+     get a chance to see if it can deduce whether ARGLIST is constant.
+     If CSE isn't going to run, of course, don't bother waiting.  */
+
+  if (cse_not_expected)
+    return const0_rtx;
 
   current_function_calls_constant_p = 1;
 
@@ -1490,18 +1460,79 @@
 
   switch (fn)
     {
+      CASE_MATHFN (BUILT_IN_ACOS)
+      CASE_MATHFN (BUILT_IN_ACOSH)
+      CASE_MATHFN (BUILT_IN_ASIN)
+      CASE_MATHFN (BUILT_IN_ASINH)
       CASE_MATHFN (BUILT_IN_ATAN)
+      CASE_MATHFN (BUILT_IN_ATAN2)
+      CASE_MATHFN (BUILT_IN_ATANH)
+      CASE_MATHFN (BUILT_IN_CBRT)
       CASE_MATHFN (BUILT_IN_CEIL)
+      CASE_MATHFN (BUILT_IN_COPYSIGN)
       CASE_MATHFN (BUILT_IN_COS)
+      CASE_MATHFN (BUILT_IN_COSH)
+      CASE_MATHFN (BUILT_IN_DREM)
+      CASE_MATHFN (BUILT_IN_ERF)
+      CASE_MATHFN (BUILT_IN_ERFC)
       CASE_MATHFN (BUILT_IN_EXP)
+      CASE_MATHFN (BUILT_IN_EXP10)
+      CASE_MATHFN (BUILT_IN_EXP2)
+      CASE_MATHFN (BUILT_IN_EXPM1)
+      CASE_MATHFN (BUILT_IN_FABS)
+      CASE_MATHFN (BUILT_IN_FDIM)
       CASE_MATHFN (BUILT_IN_FLOOR)
+      CASE_MATHFN (BUILT_IN_FMA)
+      CASE_MATHFN (BUILT_IN_FMAX)
+      CASE_MATHFN (BUILT_IN_FMIN)
+      CASE_MATHFN (BUILT_IN_FMOD)
+      CASE_MATHFN (BUILT_IN_FREXP)
+      CASE_MATHFN (BUILT_IN_GAMMA)
+      CASE_MATHFN (BUILT_IN_HUGE_VAL)
+      CASE_MATHFN (BUILT_IN_HYPOT)
+      CASE_MATHFN (BUILT_IN_ILOGB)
+      CASE_MATHFN (BUILT_IN_INF)
+      CASE_MATHFN (BUILT_IN_J0)
+      CASE_MATHFN (BUILT_IN_J1)
+      CASE_MATHFN (BUILT_IN_JN)
+      CASE_MATHFN (BUILT_IN_LDEXP)
+      CASE_MATHFN (BUILT_IN_LGAMMA)
+      CASE_MATHFN (BUILT_IN_LLRINT)
+      CASE_MATHFN (BUILT_IN_LLROUND)
       CASE_MATHFN (BUILT_IN_LOG)
+      CASE_MATHFN (BUILT_IN_LOG10)
+      CASE_MATHFN (BUILT_IN_LOG1P)
+      CASE_MATHFN (BUILT_IN_LOG2)
+      CASE_MATHFN (BUILT_IN_LOGB)
+      CASE_MATHFN (BUILT_IN_LRINT)
+      CASE_MATHFN (BUILT_IN_LROUND)
+      CASE_MATHFN (BUILT_IN_MODF)
+      CASE_MATHFN (BUILT_IN_NAN)
+      CASE_MATHFN (BUILT_IN_NANS)
       CASE_MATHFN (BUILT_IN_NEARBYINT)
+      CASE_MATHFN (BUILT_IN_NEXTAFTER)
+      CASE_MATHFN (BUILT_IN_NEXTTOWARD)
+      CASE_MATHFN (BUILT_IN_POW)
+      CASE_MATHFN (BUILT_IN_POW10)
+      CASE_MATHFN (BUILT_IN_REMAINDER)
+      CASE_MATHFN (BUILT_IN_REMQUO)
+      CASE_MATHFN (BUILT_IN_RINT)
       CASE_MATHFN (BUILT_IN_ROUND)
+      CASE_MATHFN (BUILT_IN_SCALB)
+      CASE_MATHFN (BUILT_IN_SCALBLN)
+      CASE_MATHFN (BUILT_IN_SCALBN)
+      CASE_MATHFN (BUILT_IN_SIGNIFICAND)
       CASE_MATHFN (BUILT_IN_SIN)
+      CASE_MATHFN (BUILT_IN_SINCOS)
+      CASE_MATHFN (BUILT_IN_SINH)
       CASE_MATHFN (BUILT_IN_SQRT)
       CASE_MATHFN (BUILT_IN_TAN)
+      CASE_MATHFN (BUILT_IN_TANH)
+      CASE_MATHFN (BUILT_IN_TGAMMA)
       CASE_MATHFN (BUILT_IN_TRUNC)
+      CASE_MATHFN (BUILT_IN_Y0)
+      CASE_MATHFN (BUILT_IN_Y1)
+      CASE_MATHFN (BUILT_IN_YN)
 
       default:
 	return 0;
@@ -2473,10 +2504,7 @@
 				      builtin_memcpy_read_str,
 				      (void *) src_str, dest_align, 0);
 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_mem) != ptr_mode)
-	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
 	  return dest_mem;
 	}
 
@@ -2490,10 +2518,7 @@
       if (dest_addr == 0)
 	{
 	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_addr) != ptr_mode)
-	    dest_addr = convert_memory_address (ptr_mode, dest_addr);
-#endif
+	  dest_addr = convert_memory_address (ptr_mode, dest_addr);
 	}
       return dest_addr;
     }
@@ -2572,10 +2597,7 @@
 				      builtin_memcpy_read_str,
 				      (void *) src_str, dest_align, endp);
 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_mem) != ptr_mode)
-	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
 	  return dest_mem;
 	}
 
@@ -2590,10 +2612,7 @@
 	  dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
 				     MIN (dest_align, src_align), endp);
 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_mem) != ptr_mode)
-	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
 	  return dest_mem;
 	}
 
@@ -2829,10 +2848,7 @@
 			   builtin_strncpy_read_str,
 			   (void *) p, dest_align, 0);
 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_mem) != ptr_mode)
-	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
 	  return dest_mem;
 	}
 
@@ -2950,10 +2966,7 @@
 			   builtin_memset_gen_str,
 			   val_rtx, dest_align, 0);
 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_mem) != ptr_mode)
-	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
 	  return dest_mem;
 	}
 
@@ -2974,10 +2987,7 @@
 			   builtin_memset_read_str,
 			   &c, dest_align, 0);
 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_mem) != ptr_mode)
-	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
 	  return dest_mem;
 	}
 
@@ -2990,10 +3000,7 @@
       if (dest_addr == 0)
 	{
 	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (dest_addr) != ptr_mode)
-	    dest_addr = convert_memory_address (ptr_mode, dest_addr);
-#endif
+	  dest_addr = convert_memory_address (ptr_mode, dest_addr);
 	}
 
       return dest_addr;
@@ -3662,21 +3669,8 @@
 
   start_sequence ();
 
-#ifdef EXPAND_BUILTIN_SAVEREGS
   /* Do whatever the machine needs done in this case.  */
-  val = EXPAND_BUILTIN_SAVEREGS ();
-#else
-  /* ??? We used to try and build up a call to the out of line function,
-     guessing about what registers needed saving etc.  This became much
-     harder with __builtin_va_start, since we don't have a tree for a
-     call to __builtin_saveregs to fall back on.  There was exactly one
-     port (i860) that used this code, and I'm unconvinced it could actually
-     handle the general case.  So we no longer try to handle anything
-     weird and make the backend absorb the evil.  */
-
-  error ("__builtin_saveregs not supported by this target");
-  val = const0_rtx;
-#endif
+  val = targetm.calls.expand_builtin_saveregs ();
 
   seq = get_insns ();
   end_sequence ();
@@ -4004,10 +3998,7 @@
 #endif
     }
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (addr) != Pmode)
-    addr = convert_memory_address (Pmode, addr);
-#endif
+  addr = convert_memory_address (Pmode, addr);
 
   result = gen_rtx_MEM (TYPE_MODE (type), addr);
   set_mem_alias_set (result, get_varargs_alias_set ());
@@ -4066,13 +4057,8 @@
       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
 			  VOIDmode, EXPAND_NORMAL);
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-      if (GET_MODE (dstb) != Pmode)
-	dstb = convert_memory_address (Pmode, dstb);
-
-      if (GET_MODE (srcb) != Pmode)
-	srcb = convert_memory_address (Pmode, srcb);
-#endif
+      dstb = convert_memory_address (Pmode, dstb);
+      srcb = convert_memory_address (Pmode, srcb);
 
       /* "Dereference" to BLKmode memories.  */
       dstb = gen_rtx_MEM (BLKmode, dstb);
@@ -4155,11 +4141,7 @@
 
   /* Allocate the desired space.  */
   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
-
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (result) != ptr_mode)
-    result = convert_memory_address (ptr_mode, result);
-#endif
+  result = convert_memory_address (ptr_mode, result);
 
   return result;
 }
@@ -5409,15 +5391,14 @@
 	  && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
     return integer_one_node;
 
-  /* If we aren't going to be running CSE or this expression
-     has side effects, show we don't know it to be a constant.
-     Likewise if it's a pointer or aggregate type since in those
-     case we only want literals, since those are only optimized
+  /* If this expression has side effects, show we don't know it to be a
+     constant.  Likewise if it's a pointer or aggregate type since in
+     those case we only want literals, since those are only optimized
      when generating RTL, not later.
      And finally, if we are compiling an initializer, not code, we
      need to return a definite result now; there's not going to be any
      more optimization done.  */
-  if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
+  if (TREE_SIDE_EFFECTS (arglist)
       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
       || POINTER_TYPE_P (TREE_TYPE (arglist))
       || cfun == 0)
@@ -5664,6 +5645,8 @@
 	{
 	  tree rpart, ipart, result, arglist;
 
+	  arg = save_expr (arg);
+
 	  rpart = fold (build1 (REALPART_EXPR, type, arg));
 	  ipart = fold (build1 (IMAGPART_EXPR, type, arg));
 
@@ -5883,6 +5866,216 @@
   return NULL_TREE;
 }
 
+/* Return true if EXPR is the real constant contained in VALUE.  */
+
+static bool
+real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
+{
+  STRIP_NOPS (expr);
+
+  return ((TREE_CODE (expr) == REAL_CST
+           && ! TREE_CONSTANT_OVERFLOW (expr)
+           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
+          || (TREE_CODE (expr) == COMPLEX_CST
+              && real_dconstp (TREE_REALPART (expr), value)
+              && real_zerop (TREE_IMAGPART (expr))));
+}
+
+/* A subroutine of fold_builtin to fold the various logarithmic
+   functions.  EXP is the CALL_EXPR of a call to a builtin log*
+   function.  VALUE is the base of the log* function.  */
+
+static tree
+fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
+{
+  tree arglist = TREE_OPERAND (exp, 1);
+
+  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+    {
+      tree fndecl = get_callee_fndecl (exp);
+      tree type = TREE_TYPE (TREE_TYPE (fndecl));
+      tree arg = TREE_VALUE (arglist);
+      const enum built_in_function fcode = builtin_mathfn_code (arg);
+	
+      /* Optimize log*(1.0) = 0.0.  */
+      if (real_onep (arg))
+	return build_real (type, dconst0);
+
+      /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
+         exactly, then only do this if flag_unsafe_math_optimizations.  */
+      if (exact_real_truncate (TYPE_MODE (type), value)
+	  || flag_unsafe_math_optimizations)
+        {
+	  const REAL_VALUE_TYPE value_truncate =
+	    real_value_truncate (TYPE_MODE (type), *value);
+	  if (real_dconstp (arg, &value_truncate))
+	    return build_real (type, dconst1);
+	}
+      
+      /* Special case, optimize logN(expN(x)) = x.  */
+      if (flag_unsafe_math_optimizations
+	  && ((value == &dconste
+	       && (fcode == BUILT_IN_EXP
+		   || fcode == BUILT_IN_EXPF
+		   || fcode == BUILT_IN_EXPL))
+	      || (value == &dconst2
+		  && (fcode == BUILT_IN_EXP2
+		      || fcode == BUILT_IN_EXP2F
+		      || fcode == BUILT_IN_EXP2L))
+	      || (value == &dconst10
+		  && (fcode == BUILT_IN_EXP10
+		      || fcode == BUILT_IN_EXP10F
+		      || fcode == BUILT_IN_EXP10L))))
+	return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
+
+      /* Optimize log*(func()) for various exponential functions.  We
+         want to determine the value "x" and the power "exponent" in
+         order to transform logN(x**exponent) into exponent*logN(x).  */
+      if (flag_unsafe_math_optimizations)
+        {
+	  tree exponent = 0, x = 0;
+	  
+	  switch (fcode)
+	  {
+	  case BUILT_IN_EXP:
+	  case BUILT_IN_EXPF:
+	  case BUILT_IN_EXPL:
+	    /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
+	    x = build_real (type,
+			    real_value_truncate (TYPE_MODE (type), dconste));
+	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
+	    break;
+	  case BUILT_IN_EXP2:
+	  case BUILT_IN_EXP2F:
+	  case BUILT_IN_EXP2L:
+	    /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
+	    x = build_real (type, dconst2);
+	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
+	    break;
+	  case BUILT_IN_EXP10:
+	  case BUILT_IN_EXP10F:
+	  case BUILT_IN_EXP10L:
+	  case BUILT_IN_POW10:
+	  case BUILT_IN_POW10F:
+	  case BUILT_IN_POW10L:
+	    /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
+	    x = build_real (type, dconst10);
+	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
+	    break;
+	  case BUILT_IN_SQRT:
+	  case BUILT_IN_SQRTF:
+	  case BUILT_IN_SQRTL:
+	    /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
+	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
+	    exponent = build_real (type, dconsthalf);
+	    break;
+	  case BUILT_IN_CBRT:
+	  case BUILT_IN_CBRTF:
+	  case BUILT_IN_CBRTL:
+	    /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
+	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
+	    exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
+							      dconstthird));
+	    break;
+	  case BUILT_IN_POW:
+	  case BUILT_IN_POWF:
+	  case BUILT_IN_POWL:
+	    /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
+	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
+	    exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
+	    break;
+	  default:
+	    break;
+	  }
+
+	  /* Now perform the optimization.  */
+	  if (x && exponent)
+	    {
+	      tree logfn;
+	      arglist = build_tree_list (NULL_TREE, x);
+	      logfn = build_function_call_expr (fndecl, arglist);
+	      return fold (build (MULT_EXPR, type, exponent, logfn));
+	    }
+	}
+    }
+
+  return 0;
+}
+	  
+/* A subroutine of fold_builtin to fold the various exponent
+   functions.  EXP is the CALL_EXPR of a call to a builtin function.
+   VALUE is the value which will be raised to a power.  */
+
+static tree
+fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
+{
+  tree arglist = TREE_OPERAND (exp, 1);
+
+  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+    {
+      tree fndecl = get_callee_fndecl (exp);
+      tree type = TREE_TYPE (TREE_TYPE (fndecl));
+      tree arg = TREE_VALUE (arglist);
+
+      /* Optimize exp*(0.0) = 1.0.  */
+      if (real_zerop (arg))
+	return build_real (type, dconst1);
+
+      /* Optimize expN(1.0) = N.  */
+      if (real_onep (arg))
+        {
+	  REAL_VALUE_TYPE cst;
+
+	  real_convert (&cst, TYPE_MODE (type), value);
+	  return build_real (type, cst);
+	}
+
+      /* Attempt to evaluate expN(integer) at compile-time.  */
+      if (flag_unsafe_math_optimizations
+	  && TREE_CODE (arg) == REAL_CST
+	  && ! TREE_CONSTANT_OVERFLOW (arg))
+        {
+	  REAL_VALUE_TYPE cint;
+	  REAL_VALUE_TYPE c;
+	  HOST_WIDE_INT n;
+
+	  c = TREE_REAL_CST (arg);
+	  n = real_to_integer (&c);
+	  real_from_integer (&cint, VOIDmode, n,
+			     n < 0 ? -1 : 0, 0);
+	  if (real_identical (&c, &cint))
+	    {
+	      REAL_VALUE_TYPE x;
+
+	      real_powi (&x, TYPE_MODE (type), value, n);
+	      return build_real (type, x);
+	    }
+	}
+
+      /* Optimize expN(logN(x)) = x.  */
+      if (flag_unsafe_math_optimizations)
+        {
+	  const enum built_in_function fcode = builtin_mathfn_code (arg);
+
+	  if ((value == &dconste
+	       && (fcode == BUILT_IN_LOG
+		   || fcode == BUILT_IN_LOGF
+		   || fcode == BUILT_IN_LOGL))
+	      || (value == &dconst2
+		  && (fcode == BUILT_IN_LOG2
+		      || fcode == BUILT_IN_LOG2F
+		      || fcode == BUILT_IN_LOG2L))
+	      || (value == &dconst10
+		  && (fcode == BUILT_IN_LOG10
+		      || fcode == BUILT_IN_LOG10F
+		      || fcode == BUILT_IN_LOG10L)))
+	    return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
+	}
+    }
+
+  return 0;
+}
+
 /* Used by constant folding to eliminate some builtin calls early.  EXP is
    the CALL_EXPR of a call to a builtin function.  */
 
@@ -6020,107 +6213,32 @@
     case BUILT_IN_EXP:
     case BUILT_IN_EXPF:
     case BUILT_IN_EXPL:
-      if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
-	{
-	  enum built_in_function fcode;
-	  tree arg = TREE_VALUE (arglist);
-
-	  /* Optimize exp(0.0) = 1.0.  */
-	  if (real_zerop (arg))
-	    return build_real (type, dconst1);
-
-	  /* Optimize exp(1.0) = e.  */
-	  if (real_onep (arg))
-	    {
-	      REAL_VALUE_TYPE cst;
-
-	      if (! builtin_dconsts_init)
-		init_builtin_dconsts ();
-	      real_convert (&cst, TYPE_MODE (type), &dconste);
-	      return build_real (type, cst);
-	    }
-
-	  /* Attempt to evaluate exp at compile-time.  */
-	  if (flag_unsafe_math_optimizations
-	      && TREE_CODE (arg) == REAL_CST
-	      && ! TREE_CONSTANT_OVERFLOW (arg))
-	    {
-	      REAL_VALUE_TYPE cint;
-	      REAL_VALUE_TYPE c;
-	      HOST_WIDE_INT n;
-
-	      c = TREE_REAL_CST (arg);
-	      n = real_to_integer (&c);
-	      real_from_integer (&cint, VOIDmode, n,
-				 n < 0 ? -1 : 0, 0);
-	      if (real_identical (&c, &cint))
-		{
-		  REAL_VALUE_TYPE x;
-
-		  if (! builtin_dconsts_init)
-		    init_builtin_dconsts ();
-		  real_powi (&x, TYPE_MODE (type), &dconste, n);
-		  return build_real (type, x);
-		}
-	    }
-
-	  /* Optimize exp(log(x)) = x.  */
-	  fcode = builtin_mathfn_code (arg);
-	  if (flag_unsafe_math_optimizations
-	      && (fcode == BUILT_IN_LOG
-		  || fcode == BUILT_IN_LOGF
-		  || fcode == BUILT_IN_LOGL))
-	    return TREE_VALUE (TREE_OPERAND (arg, 1));
-	}
-      break;
-
+      return fold_builtin_exponent (exp, &dconste);
+    case BUILT_IN_EXP2:
+    case BUILT_IN_EXP2F:
+    case BUILT_IN_EXP2L:
+      return fold_builtin_exponent (exp, &dconst2);
+    case BUILT_IN_EXP10:
+    case BUILT_IN_EXP10F:
+    case BUILT_IN_EXP10L:
+    case BUILT_IN_POW10:
+    case BUILT_IN_POW10F:
+    case BUILT_IN_POW10L:
+      return fold_builtin_exponent (exp, &dconst10);
     case BUILT_IN_LOG:
     case BUILT_IN_LOGF:
     case BUILT_IN_LOGL:
-      if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
-	{
-	  enum built_in_function fcode;
-	  tree arg = TREE_VALUE (arglist);
-
-	  /* Optimize log(1.0) = 0.0.  */
-	  if (real_onep (arg))
-	    return build_real (type, dconst0);
-
-	  /* Optimize log(exp(x)) = x.  */
-	  fcode = builtin_mathfn_code (arg);
-	  if (flag_unsafe_math_optimizations
-	      && (fcode == BUILT_IN_EXP
-		  || fcode == BUILT_IN_EXPF
-		  || fcode == BUILT_IN_EXPL))
-	    return TREE_VALUE (TREE_OPERAND (arg, 1));
-
-	  /* Optimize log(sqrt(x)) = log(x)*0.5.  */
-	  if (flag_unsafe_math_optimizations
-	      && (fcode == BUILT_IN_SQRT
-		  || fcode == BUILT_IN_SQRTF
-		  || fcode == BUILT_IN_SQRTL))
-	    {
-	      tree logfn = build_function_call_expr (fndecl,
-						     TREE_OPERAND (arg, 1));
-	      return fold (build (MULT_EXPR, type, logfn,
-				  build_real (type, dconsthalf)));
-	    }
-
-	  /* Optimize log(pow(x,y)) = y*log(x).  */
-          if (flag_unsafe_math_optimizations
-	      && (fcode == BUILT_IN_POW
-		  || fcode == BUILT_IN_POWF
-		  || fcode == BUILT_IN_POWL))
-	    {
-	      tree arg0, arg1, logfn;
-
-	      arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
-	      arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
-	      arglist = build_tree_list (NULL_TREE, arg0);
-	      logfn = build_function_call_expr (fndecl, arglist);
-	      return fold (build (MULT_EXPR, type, arg1, logfn));
-	    }
-	}
+      return fold_builtin_logarithm (exp, &dconste);
+      break;
+    case BUILT_IN_LOG2:
+    case BUILT_IN_LOG2F:
+    case BUILT_IN_LOG2L:
+      return fold_builtin_logarithm (exp, &dconst2);
+      break;
+    case BUILT_IN_LOG10:
+    case BUILT_IN_LOG10F:
+    case BUILT_IN_LOG10L:
+      return fold_builtin_logarithm (exp, &dconst10);
       break;
 
     case BUILT_IN_TAN:
@@ -6161,8 +6279,6 @@
 	    {
 	      REAL_VALUE_TYPE cst;
 
-	      if (! builtin_dconsts_init)
-		init_builtin_dconsts ();
 	      real_convert (&cst, TYPE_MODE (type), &dconstpi);
 	      cst.exp -= 2;
 	      return build_real (type, cst);


Index: gcc-3.4/gcc/c-common.c
diff -u gcc-3.4/gcc/c-common.c:1.2 gcc-3.4/gcc/c-common.c:1.3
--- gcc-3.4/gcc/c-common.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-common.c	Thu Feb  5 10:05:44 2004
@@ -430,6 +430,10 @@
 
 int warn_nonnull;
 
+/* Warn about old-style parameter declaration.  */
+
+int warn_old_style_definition;
+
 
 /* ObjC language option variables.  */
 
@@ -770,6 +774,8 @@
 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
 static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
+static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
+						 bool *);
 static tree vector_size_helper (tree, tree);
 
 static void check_function_nonnull (tree, tree);
@@ -847,6 +853,8 @@
   { "may_alias",	      0, 0, false, true, false, NULL },
   { "cleanup",		      1, 1, true, false, false,
 			      handle_cleanup_attribute },
+  { "warn_unused_result",     0, 0, false, true, true,
+			      handle_warn_unused_result_attribute },
   { NULL,                     0, 0, false, false, false, NULL }
 };
 
@@ -1072,16 +1080,18 @@
 const char *
 fname_as_string (int pretty_p)
 {
-  const char *name = NULL;
+  const char *name = "top level";
+  int vrb = 2;
+
+  if (! pretty_p)
+    {
+      name = "";
+      vrb = 0;
+    }
+
+  if (current_function_decl)
+    name = (*lang_hooks.decl_printable_name) (current_function_decl, vrb);
 
-  if (pretty_p)
-    name = (current_function_decl
-	    ? (*lang_hooks.decl_printable_name) (current_function_decl, 2)
-	    : "top level");
-  else if (current_function_decl && DECL_NAME (current_function_decl))
-    name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
-  else
-    name = "";
   return name;
 }
 
@@ -1131,8 +1141,7 @@
       input_line = saved_lineno;
     }
   if (!ix && !current_function_decl)
-    pedwarn ("%H'%D' is not defined outside of function scope",
-             &DECL_SOURCE_LOCATION (decl), decl);
+    pedwarn ("%J'%D' is not defined outside of function scope", decl, decl);
 
   return decl;
 }
@@ -1854,6 +1863,9 @@
   if (mode == TYPE_MODE (long_double_type_node))
     return long_double_type_node;
 
+  if (mode == TYPE_MODE (void_type_node))
+    return void_type_node;
+  
   if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
     return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
 
@@ -1974,36 +1986,56 @@
       || TREE_UNSIGNED (type) == unsignedp)
     return type;
 
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
+  /* Must check the mode of the types, not the precision.  Enumeral types
+     in C++ have precision set to match their range, but may use a wider
+     mode to match an ABI.  If we change modes, we may wind up with bad
+     conversions.  */
+
+  if (TYPE_MODE (type) == TYPE_MODE (signed_char_type_node))
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (integer_type_node))
     return unsignedp ? unsigned_type_node : integer_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (short_integer_type_node))
     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (long_integer_type_node))
     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (long_long_integer_type_node))
     return (unsignedp ? long_long_unsigned_type_node
 	    : long_long_integer_type_node);
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (widest_integer_literal_type_node))
     return (unsignedp ? widest_unsigned_literal_type_node
 	    : widest_integer_literal_type_node);
 
 #if HOST_BITS_PER_WIDE_INT >= 64
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
 #endif
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (intSI_type_node))
     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (intHI_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (intHI_type_node))
     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node))
+  if (TYPE_MODE (type) == TYPE_MODE (intQI_type_node))
     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 
   return type;
 }
+
+/* The C version of the register_builtin_type langhook.  */
+
+void
+c_register_builtin_type (tree type, const char* name)
+{
+  tree decl;
+
+  decl = build_decl (TYPE_DECL, get_identifier (name), type);
+  DECL_ARTIFICIAL (decl) = 1;
+  if (!TYPE_NAME (type))
+    TYPE_NAME (type) = decl;
+  pushdecl (decl);
+}
+
 
 /* Return the minimum number of bits needed to represent VALUE in a
    signed or unsigned type, UNSIGNEDP says which.  */
@@ -2654,8 +2686,6 @@
     case NEGATE_EXPR:
     case ABS_EXPR:
     case FLOAT_EXPR:
-    case FFS_EXPR:
-    case POPCOUNT_EXPR:
       /* These don't change whether an object is nonzero or zero.  */
       return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
 
@@ -3948,19 +3978,17 @@
       if (high_value)
 	{
 	  error ("duplicate (or overlapping) case value");
-	  error ("%Hthis is the first entry overlapping that value",
-                 &DECL_SOURCE_LOCATION (duplicate));
+	  error ("%Jthis is the first entry overlapping that value", duplicate);
 	}
       else if (low_value)
 	{
 	  error ("duplicate case value") ;
-	  error ("%Hpreviously used here", &DECL_SOURCE_LOCATION (duplicate));
+	  error ("%Jpreviously used here", duplicate);
 	}
       else
 	{
 	  error ("multiple default labels in one switch");
-	  error ("%Hthis is the first default label",
-                 &DECL_SOURCE_LOCATION (duplicate));
+	  error ("%Jthis is the first default label", duplicate);
 	}
       if (!cases->root)
 	add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
@@ -4021,6 +4049,26 @@
 	bool preserve_result = false;
 	bool return_target = false;
 
+	if (STMT_EXPR_WARN_UNUSED_RESULT (exp) && target == const0_rtx)
+	  {
+	    tree stmt = STMT_EXPR_STMT (exp);
+	    tree scope;
+
+	    for (scope = COMPOUND_BODY (stmt);
+		 scope && TREE_CODE (scope) != SCOPE_STMT;
+		 scope = TREE_CHAIN (scope));
+
+	    if (scope && SCOPE_STMT_BLOCK (scope))
+	      warning ("%Hignoring return value of `%D', "
+		       "declared with attribute warn_unused_result",
+		       &expr_wfl_stack->location,
+		       BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope)));
+	    else
+	      warning ("%Hignoring return value of function "
+		       "declared with attribute warn_unused_result",
+		       &expr_wfl_stack->location);
+	  }
+
 	/* Since expand_expr_stmt calls free_temp_slots after every
 	   expression statement, we must call push_temp_slots here.
 	   Otherwise, any temporaries in use now would be considered
@@ -4241,7 +4289,7 @@
   };
 
   warning (msgs[msgcode], name);
-  warning ("%Hshadowed declaration is here", &DECL_SOURCE_LOCATION (decl));
+  warning ("%Jshadowed declaration is here", decl);
 }
 
 /* Attribute handlers common to C front ends.  */
@@ -4682,8 +4730,8 @@
 	      && current_function_decl != NULL_TREE
 	      && ! TREE_STATIC (decl))
 	    {
-	      error ("%Hsection attribute cannot be specified for "
-                     "local variables", &DECL_SOURCE_LOCATION (decl));
+	      error ("%Jsection attribute cannot be specified for "
+                     "local variables", decl);
 	      *no_add_attrs = true;
 	    }
 
@@ -4693,8 +4741,8 @@
 		   && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
 			      TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
 	    {
-	      error ("%Hsection of '%D' conflicts with previous declaration",
-                     &DECL_SOURCE_LOCATION (*node), *node);
+	      error ("%Jsection of '%D' conflicts with previous declaration",
+                     *node, *node);
 	      *no_add_attrs = true;
 	    }
 	  else
@@ -4702,15 +4750,13 @@
 	}
       else
 	{
-	  error ("%Hsection attribute not allowed for '%D'",
-                 &DECL_SOURCE_LOCATION (*node), *node);
+	  error ("%Jsection attribute not allowed for '%D'", *node, *node);
 	  *no_add_attrs = true;
 	}
     }
   else
     {
-      error ("%Hsection attributes are not supported for this target",
-             &DECL_SOURCE_LOCATION (*node));
+      error ("%Jsection attributes are not supported for this target", *node);
       *no_add_attrs = true;
     }
 
@@ -4784,8 +4830,7 @@
   else if (TREE_CODE (decl) != VAR_DECL
 	   && TREE_CODE (decl) != FIELD_DECL)
     {
-      error ("%Halignment may not be specified for '%D'",
-             &DECL_SOURCE_LOCATION (decl), decl);
+      error ("%Jalignment may not be specified for '%D'", decl, decl);
       *no_add_attrs = true;
     }
   else
@@ -4823,8 +4868,7 @@
   if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
       || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
     {
-      error ("%H'%D' defined both normally and as an alias",
-             &DECL_SOURCE_LOCATION (decl), decl);
+      error ("%J'%D' defined both normally and as an alias", decl, decl);
       *no_add_attrs = true;
     }
   else if (decl_function_context (decl) == 0)
@@ -4948,14 +4992,12 @@
 
   if (TREE_CODE (decl) != FUNCTION_DECL)
     {
-      error ("%H'%E' attribute applies only to functions",
-             &DECL_SOURCE_LOCATION (decl), name);
+      error ("%J'%E' attribute applies only to functions", decl, name);
       *no_add_attrs = true;
     }
   else if (DECL_INITIAL (decl))
     {
-      error ("%Hcan't set '%E' attribute after definition",
-             &DECL_SOURCE_LOCATION (decl), name);
+      error ("%Jcan't set '%E' attribute after definition", decl, name);
       *no_add_attrs = true;
     }
   else
@@ -4996,14 +5038,12 @@
 
   if (TREE_CODE (decl) != FUNCTION_DECL)
     {
-      error ("%H'%E' attribute applies only to functions",
-             &DECL_SOURCE_LOCATION (decl), name);
+      error ("%J'%E' attribute applies only to functions", decl, name);
       *no_add_attrs = true;
     }
   else if (DECL_INITIAL (decl))
     {
-      error ("%Hcan't set '%E' attribute after definition",
-             &DECL_SOURCE_LOCATION (decl), name);
+      error ("%Jcan't set '%E' attribute after definition", decl, name);
       *no_add_attrs = true;
     }
   else
@@ -5507,6 +5547,23 @@
 
   /* That the function has proper type is checked with the
      eventual call to build_function_call.  */
+
+  return NULL_TREE;
+}
+
+/* Handle a "warn_unused_result" attribute.  No special handling.  */
+
+static tree
+handle_warn_unused_result_attribute (tree *node, tree name,
+			       tree args ATTRIBUTE_UNUSED,
+			       int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+  /* Ignore the attribute for functions not returning any value.  */
+  if (VOID_TYPE_P (TREE_TYPE (*node)))
+    {
+      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
 
   return NULL_TREE;
 }


Index: gcc-3.4/gcc/c-common.h
diff -u gcc-3.4/gcc/c-common.h:1.2 gcc-3.4/gcc/c-common.h:1.3
--- gcc-3.4/gcc/c-common.h:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-common.h	Thu Feb  5 10:05:44 2004
@@ -44,6 +44,7 @@
    2: STMT_LINENO_FOR_FN_P (in _STMT)
    3: SCOPE_NO_CLEANUPS_P (in SCOPE_STMT)
       COMPOUND_STMT_BODY_BLOCK (in COMPOUND_STMT)
+      STMT_EXPR_WARN_UNUSED_RESULT (in STMT_EXPR)
    4: SCOPE_PARTIAL_P (in SCOPE_STMT)
 */
 
@@ -595,6 +596,10 @@
       
 extern int warn_nonnull;
 
+/* Warn about old-style parameter declaration.  */
+
+extern int warn_old_style_definition;
+
 
 /* ObjC language option variables.  */
 
@@ -952,6 +957,7 @@
 extern void c_common_finish (void);
 extern void c_common_parse_file (int);
 extern HOST_WIDE_INT c_common_get_alias_set (tree);
+extern void c_register_builtin_type (tree, const char*);
 extern bool c_promoting_integer_type_p (tree);
 extern int self_promoting_args_p (tree);
 extern tree strip_array_types (tree);
@@ -1052,6 +1058,11 @@
 /* Nonzero if this statement-expression does not have an associated scope.  */
 #define STMT_EXPR_NO_SCOPE(NODE) \
    TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
+
+/* Nonzero if this statement-expression should cause warning if its result
+   is not used.  */
+#define STMT_EXPR_WARN_UNUSED_RESULT(NODE) \
+   TREE_LANG_FLAG_3 (STMT_EXPR_CHECK (NODE))
 
 /* LABEL_STMT accessor. This gives access to the label associated with
    the given label statement.  */


Index: gcc-3.4/gcc/c-decl.c
diff -u gcc-3.4/gcc/c-decl.c:1.2 gcc-3.4/gcc/c-decl.c:1.3
--- gcc-3.4/gcc/c-decl.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-decl.c	Thu Feb  5 10:05:44 2004
@@ -187,7 +187,7 @@
    the end of the list on each insertion, or reverse the lists later,
    we maintain a pointer to the last list entry for each of the lists.
 
-   The order of the tags, shadowed, shadowed_tags, and incomplete
+   The order of the tags, shadowed, and shadowed_tags
    lists does not matter, so we just prepend to these lists.  */
 
 struct c_scope GTY(())
@@ -227,9 +227,6 @@
   tree blocks;
   tree blocks_last;
 
-  /* Variable declarations with incomplete type in this scope.  */
-  tree incomplete;
-
   /* True if we are currently filling this scope with parameter
      declarations.  */
   bool parm_flag : 1;
@@ -372,8 +369,7 @@
 	  && ! DECL_EXTERNAL (decl)
 	  && TYPE_DOMAIN (type) == 0)
 	{
-	  warning ("%Harray '%D' assumed to have one element",
-                   &DECL_SOURCE_LOCATION (decl), decl);
+	  warning ("%Jarray '%D' assumed to have one element", decl, decl);
 
 	  complete_array_type (type, NULL_TREE, 1);
 
@@ -510,7 +506,8 @@
   tree decl;
   tree p;
 
-  scope->function_body |= functionbody;
+  /* The following line does not use |= due to a bug in HP's C compiler */
+  scope->function_body = scope->function_body | functionbody;
 
   if (keep == KEEP_MAYBE)
     keep = (scope->names || scope->tags);
@@ -543,22 +540,20 @@
 
   for (p = scope->names; p; p = TREE_CHAIN (p))
     {
-      const location_t *locus = &DECL_SOURCE_LOCATION (p);
-
       switch (TREE_CODE (p))
 	{
 	case LABEL_DECL:
 	  if (TREE_USED (p) && !DECL_INITIAL (p))
 	    {
-	      error ("%Hlabel `%D' used but not defined", locus, p);
+	      error ("%Jlabel `%D' used but not defined", p, p);
 	      DECL_INITIAL (p) = error_mark_node;
 	    }
 	  else if (!TREE_USED (p) && warn_unused_label)
 	    {
 	      if (DECL_INITIAL (p))
-		warning ("%Hlabel `%D' defined but not used", locus, p);
+		warning ("%Jlabel `%D' defined but not used", p, p);
 	      else
-		warning ("%Hlabel `%D' declared but not defined", locus, p);
+		warning ("%Jlabel `%D' declared but not defined", p, p);
 	    }
 
 	  IDENTIFIER_LABEL_VALUE (DECL_NAME (p)) = 0;
@@ -583,7 +578,7 @@
 	      && !DECL_IN_SYSTEM_HEADER (p)
 	      && DECL_NAME (p)
 	      && !DECL_ARTIFICIAL (p))
-	    warning ("%Hunused variable `%D'", locus, p);
+	    warning ("%Junused variable `%D'", p, p);
 	  /* fall through */
 
 	default:
@@ -780,10 +775,8 @@
 duplicate_decls (tree newdecl, tree olddecl, int different_binding_level,
 		 int different_tu)
 {
-  int comptype_flags = (different_tu ? COMPARE_DIFFERENT_TU
-			: COMPARE_STRICT);
   int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl),
-			       comptype_flags);
+			       COMPARE_STRICT);
   int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
 			   && DECL_INITIAL (newdecl) != 0);
   tree oldtype = TREE_TYPE (olddecl);
@@ -809,20 +802,19 @@
 		   && DECL_UNINLINABLE (olddecl)
 		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
 	    {
-	      warning ("%Hfunction '%D' redeclared as inline",
-                       &DECL_SOURCE_LOCATION (newdecl), newdecl);
-	      warning ("%Hprevious declaration of function '%D' "
-                       "with attribute noinline",
-                       &DECL_SOURCE_LOCATION (olddecl), olddecl);
+	      warning ("%Jfunction '%D' redeclared as inline",
+		       newdecl, newdecl);
+	      warning ("%Jprevious declaration of function '%D' "
+                       "with attribute noinline", olddecl, olddecl);
 	    }
 	  else if (DECL_DECLARED_INLINE_P (olddecl)
 		   && DECL_UNINLINABLE (newdecl)
 		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
 	    {
-	      warning ("%Hfunction '%D' redeclared with attribute noinline",
-                       &DECL_SOURCE_LOCATION (newdecl), newdecl);
-	      warning ("%Hprevious declaration of function '%D' was inline",
-                       &DECL_SOURCE_LOCATION (olddecl), olddecl);
+	      warning ("%Jfunction '%D' redeclared with attribute noinline",
+                       newdecl, newdecl);
+	      warning ("%Jprevious declaration of function '%D' was inline",
+                       olddecl, olddecl);
 	    }
 	}
 
@@ -848,19 +840,18 @@
 	  if (!TREE_PUBLIC (newdecl))
 	    {
 	      if (warn_shadow)
-		warning ("%Hshadowing built-in function '%D'",
-                         &DECL_SOURCE_LOCATION (newdecl), newdecl);
+		warning ("%Jshadowing built-in function '%D'",
+			 newdecl, newdecl);
 	    }
 	  else
-	    warning ("%Hbuilt-in function '%D' declared as non-function",
-                     &DECL_SOURCE_LOCATION (newdecl), newdecl);
+	    warning ("%Jbuilt-in function '%D' declared as non-function",
+                     newdecl, newdecl);
 	}
       else
 	{
-	  error ("%H'%D' redeclared as different kind of symbol",
-                 &DECL_SOURCE_LOCATION (newdecl), newdecl);
-	  error ("%Hprevious declaration of '%D'",
-                 &DECL_SOURCE_LOCATION (olddecl), olddecl);
+	  error ("%J'%D' redeclared as different kind of symbol",
+		 newdecl, newdecl);
+	  error ("%Jprevious declaration of '%D'", olddecl, olddecl);
 	}
 
       return 0;
@@ -889,8 +880,7 @@
 	     built-in definition is overridden,
 	     but optionally warn this was a bad choice of name.  */
 	  if (warn_shadow)
-	    warning ("%Hshadowing built-in function '%D'",
-                     &DECL_SOURCE_LOCATION (newdecl), newdecl);
+	    warning ("%Jshadowing built-in function '%D'", newdecl, newdecl);
 	  /* Discard the old built-in function.  */
 	  return 0;
 	}
@@ -902,7 +892,7 @@
 
 	  if (trytype)
 	    {
-	      types_match = comptypes (newtype, trytype, comptype_flags);
+	      types_match = comptypes (newtype, trytype, COMPARE_STRICT);
 	      if (types_match)
 		oldtype = trytype;
 	      if (! different_binding_level)
@@ -912,8 +902,8 @@
       if (!types_match)
 	{
 	  /* If types don't match for a built-in, throw away the built-in.  */
-	  warning ("%Hconflicting types for built-in function '%D'",
-                   &DECL_SOURCE_LOCATION (newdecl), newdecl);
+	  warning ("%Jconflicting types for built-in function '%D'",
+		   newdecl, newdecl);
 	  return 0;
 	}
     }
@@ -956,8 +946,7 @@
 		&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)))
     {
       if (pedantic)
-	pedwarn ("%Hconflicting types for '%D'",
-                 &DECL_SOURCE_LOCATION (newdecl), newdecl);
+	pedwarn ("%Jconflicting types for '%D'", newdecl, newdecl);
       /* Make sure we keep void * as ret type, not char *.  */
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)
 	TREE_TYPE (newdecl) = newtype = oldtype;
@@ -975,8 +964,7 @@
 	   && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
 	   && C_FUNCTION_IMPLICIT_INT (newdecl))
     {
-      pedwarn ("%Hconflicting types for '%D'",
-               &DECL_SOURCE_LOCATION (newdecl), newdecl);
+      pedwarn ("%Jconflicting types for '%D'", newdecl, newdecl);
       /* Make sure we keep void as the return type.  */
       TREE_TYPE (newdecl) = newtype = oldtype;
       C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
@@ -988,16 +976,15 @@
 		 && ! pedantic
 		 /* Return types must still match.  */
 		 && comptypes (TREE_TYPE (oldtype),
-			       TREE_TYPE (newtype), comptype_flags)
+			       TREE_TYPE (newtype), COMPARE_STRICT)
 		 && TYPE_ARG_TYPES (newtype) == 0))
     {
-      error ("%Hconflicting types for '%D'",
-             &DECL_SOURCE_LOCATION (newdecl), newdecl);
+      error ("%Jconflicting types for '%D'", newdecl, newdecl);
       /* Check for function type mismatch
 	 involving an empty arglist vs a nonempty one.  */
       if (TREE_CODE (olddecl) == FUNCTION_DECL
 	  && comptypes (TREE_TYPE (oldtype),
-			TREE_TYPE (newtype), comptype_flags)
+			TREE_TYPE (newtype), COMPARE_STRICT)
 	  && ((TYPE_ARG_TYPES (oldtype) == 0
 	       && DECL_INITIAL (olddecl) == 0)
 	      ||
@@ -1027,11 +1014,9 @@
 	    }
 	}
       if (C_DECL_IMPLICIT (olddecl))
-	error ("%Hprevious implicit declaration of '%D'",
-               &DECL_SOURCE_LOCATION (olddecl), olddecl);
+	error ("%Jprevious implicit declaration of '%D'", olddecl, olddecl);
       else
-	error ("%Hprevious declaration of '%D'",
-               &DECL_SOURCE_LOCATION (olddecl), olddecl);
+	error ("%Jprevious declaration of '%D'", olddecl, olddecl);
 
       /* This is safer because the initializer might contain references
 	 to variables that were declared between olddecl and newdecl. This
@@ -1044,62 +1029,54 @@
   else if (TREE_CODE (olddecl) == VAR_DECL && TREE_CODE (newdecl) == VAR_DECL
 	   && !DECL_THREAD_LOCAL (olddecl) && DECL_THREAD_LOCAL (newdecl))
     {
-      error ("%Hthread-local declaration of '%D' follows non thread-local "
-             "declaration", &DECL_SOURCE_LOCATION (newdecl), newdecl);
-      error ("%Hprevious declaration of '%D'",
-             &DECL_SOURCE_LOCATION (olddecl), olddecl);
+      error ("%Jthread-local declaration of '%D' follows non thread-local "
+             "declaration", newdecl, newdecl);
+      error ("%Jprevious declaration of '%D'", olddecl, olddecl);
     }
   /* non-TLS declaration cannot follow TLS declaration.  */
   else if (TREE_CODE (olddecl) == VAR_DECL && TREE_CODE (newdecl) == VAR_DECL
 	   && DECL_THREAD_LOCAL (olddecl) && !DECL_THREAD_LOCAL (newdecl))
     {
-      error ("%Hnon thread-local declaration of '%D' follows "
-             "thread-local declaration",
-             &DECL_SOURCE_LOCATION (newdecl), newdecl);
-      error ("%Hprevious declaration of '%D'",
-             &DECL_SOURCE_LOCATION (olddecl), olddecl);
+      error ("%Jnon thread-local declaration of '%D' follows "
+             "thread-local declaration", newdecl, newdecl);
+      error ("%Jprevious declaration of '%D'", olddecl, olddecl);
     }
   else
     {
       errmsg = redeclaration_error_message (newdecl, olddecl);
       if (errmsg)
 	{
-          const location_t *locus = &DECL_SOURCE_LOCATION (newdecl);
 	  switch (errmsg)
 	    {
 	    case 1:
-	      error ("%Hredefinition of '%D'", locus, newdecl);
+	      error ("%Jredefinition of '%D'", newdecl, newdecl);
 	      break;
 	    case 2:
-	      error ("%Hredeclaration of '%D'", locus, newdecl);
+	      error ("%Jredeclaration of '%D'", newdecl, newdecl);
 	      break;
 	    case 3:
-	      error ("%Hconflicting declarations of '%D'", locus, newdecl);
+	      error ("%Jconflicting declarations of '%D'", newdecl, newdecl);
 	      break;
 	    default:
 	      abort ();
 	    }
 
-          locus = &DECL_SOURCE_LOCATION (olddecl);
           if (DECL_INITIAL (olddecl)
               && current_scope == global_scope)
-            error ("%H'%D' previously defined here", locus, olddecl);
+            error ("%J'%D' previously defined here", olddecl, olddecl);
           else
-            error ("%H'%D' previously declared here", locus, olddecl);
+            error ("%J'%D' previously declared here", olddecl, olddecl);
 	  return 0;
 	}
       else if (TREE_CODE (newdecl) == TYPE_DECL
                && (DECL_IN_SYSTEM_HEADER (olddecl)
                    || DECL_IN_SYSTEM_HEADER (newdecl)))
 	{
-          const location_t *locus = &DECL_SOURCE_LOCATION (newdecl);
-	  warning ("%Hredefinition of '%D'", locus, newdecl);
-          locus = &DECL_SOURCE_LOCATION (olddecl);
-          if (DECL_INITIAL (olddecl)
-              && current_scope == global_scope)
-            warning ("%H'%D' previously defined here", locus, olddecl);
+	  warning ("%Jredefinition of '%D'", newdecl, newdecl);
+          if (DECL_INITIAL (olddecl) && current_scope == global_scope)
+            warning ("%J'%D' previously defined here", olddecl, olddecl);
           else
-            warning ("%H'%D' previously declared here", locus, olddecl);
+            warning ("%J'%D' previously declared here", olddecl, olddecl);
 	}
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
 	       && DECL_INITIAL (olddecl) != 0
@@ -1120,33 +1097,27 @@
 	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
 		  && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
 		{
-                  const location_t *locus = &DECL_SOURCE_LOCATION (newdecl);
-		  warning ("%Hprototype for '%D' follows", locus, newdecl);
-                  locus = &DECL_SOURCE_LOCATION (olddecl);
-		  warning ("%Hnon-prototype definition here", locus);
+		  warning ("%Jprototype for '%D' follows", newdecl, newdecl);
+		  warning ("%Jnon-prototype definition here", olddecl);
 		  break;
 		}
 	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
 		  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
 		{
-                  const location_t *locus = &DECL_SOURCE_LOCATION (newdecl);
-		  error ("%Hprototype for '%D' follows and number of "
-                         "arguments doesn't match", locus, newdecl);
-                  locus = &DECL_SOURCE_LOCATION (olddecl);
-		  error ("%Hnon-prototype definition here", locus);
+		  error ("%Jprototype for '%D' follows and number of "
+                         "arguments doesn't match", newdecl, newdecl);
+		  error ("%Jnon-prototype definition here", olddecl);
 		  errmsg = 1;
 		  break;
 		}
 	      /* Type for passing arg must be consistent
 		 with that declared for the arg.  */
 	      if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type),
-			       comptype_flags))
+			       COMPARE_STRICT))
 		{
-                  const location_t *locus = &DECL_SOURCE_LOCATION (newdecl);
-		  error ("%Hprototype for '%D' follows and argument %d "
-                         "doesn't match", locus, newdecl, nargs);
-                  locus = &DECL_SOURCE_LOCATION (olddecl);
-		  error ("%Hnon-prototype definition here", locus);
+		  error ("%Jprototype for '%D' follows and argument %d "
+                         "doesn't match", newdecl, newdecl, nargs);
+		  error ("%Jnon-prototype definition here", olddecl);
 		  errmsg = 1;
 		  break;
 		}
@@ -1155,30 +1126,28 @@
       /* Warn about mismatches in various flags.  */
       else
 	{
-	  const location_t *locus = &DECL_SOURCE_LOCATION (newdecl);
-
 	  /* Warn if function is now inline
 	     but was previously declared not inline and has been called.  */
 	  if (TREE_CODE (olddecl) == FUNCTION_DECL
 	      && ! DECL_DECLARED_INLINE_P (olddecl)
 	      && DECL_DECLARED_INLINE_P (newdecl)
 	      && TREE_USED (olddecl))
-	    warning ("%H'%D' declared inline after being called",
-		     locus, newdecl);
+	    warning ("%J'%D' declared inline after being called",
+		     newdecl, newdecl);
 	  if (TREE_CODE (olddecl) == FUNCTION_DECL
 	      && ! DECL_DECLARED_INLINE_P (olddecl)
 	      && DECL_DECLARED_INLINE_P (newdecl)
 	      && DECL_INITIAL (olddecl) != 0)
-	    warning ("%H'%D' declared inline after its definition",
-		     locus, newdecl);
+	    warning ("%J'%D' declared inline after its definition",
+		     newdecl, newdecl);
 
 	  /* If pedantic, warn when static declaration follows a non-static
 	     declaration.  Otherwise, do so only for functions.	 */
 	  if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL)
 	      && TREE_PUBLIC (olddecl)
 	      && !TREE_PUBLIC (newdecl))
-	    warning ("%Hstatic declaration for '%D' follows non-static",
-		     locus, newdecl);
+	    warning ("%Jstatic declaration for '%D' follows non-static",
+		     newdecl, newdecl);
 
 	  /* If warn_traditional, warn when a non-static function
 	     declaration follows a static one.	*/
@@ -1186,24 +1155,24 @@
 	      && TREE_CODE (olddecl) == FUNCTION_DECL
 	      && !TREE_PUBLIC (olddecl)
 	      && TREE_PUBLIC (newdecl))
-	    warning ("%Hnon-static declaration for '%D' follows static",
-		     locus, newdecl);
+	    warning ("%Jnon-static declaration for '%D' follows static",
+		     newdecl, newdecl);
 
 	  /* Warn when const declaration follows a non-const
 	     declaration, but not for functions.  */
 	  if (TREE_CODE (olddecl) != FUNCTION_DECL
 	      && !TREE_READONLY (olddecl)
 	      && TREE_READONLY (newdecl))
-	    warning ("%Hconst declaration for '%D' follows non-const",
-		     locus, newdecl);
+	    warning ("%Jconst declaration for '%D' follows non-const",
+		     newdecl, newdecl);
 	  /* These bits are logically part of the type, for variables.
 	     But not for functions
 	     (where qualifiers are not valid ANSI anyway).  */
 	  else if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL
 	      && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
 		  || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
-	    pedwarn ("%Htype qualifiers for '%D' conflict with previous "
-		     "declaration", locus, newdecl);
+	    pedwarn ("%Jtype qualifiers for '%D' conflict with previous "
+		     "declaration", newdecl, newdecl);
 	}
     }
 
@@ -1216,10 +1185,9 @@
       /* Don't warn about extern decl followed by (tentative) definition.  */
       && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
     {
-      warning ("%Hredundant redeclaration of '%D' in same scope",
-               &DECL_SOURCE_LOCATION (newdecl), newdecl);
-      warning ("%Hprevious declaration of '%D'",
-               &DECL_SOURCE_LOCATION (olddecl), olddecl);
+      warning ("%Jredundant redeclaration of '%D' in same scope",
+	       newdecl, newdecl);
+      warning ("%Jprevious declaration of '%D'", olddecl, olddecl);
     }
 
   /* Copy all the DECL_... slots specified in the new decl
@@ -1574,7 +1542,7 @@
   name = IDENTIFIER_POINTER (DECL_NAME (x));
   if (TREE_CODE (old) == PARM_DECL)
     shadow_warning (SW_PARAM, name, old);
-  else if (C_DECL_FILE_SCOPE (old))
+  else if (DECL_FILE_SCOPE_P (old))
     shadow_warning (SW_GLOBAL, name, old);
   else
     shadow_warning (SW_LOCAL, name, old);
@@ -1748,14 +1716,15 @@
       IDENTIFIER_SYMBOL_VALUE (name) = x;
       C_DECL_INVISIBLE (x) = 0;
 
-      /* Keep list of variables in this scope with incomplete type.
+      /* If x's type is incomplete because it's based on a
+	 structure or union which has not yet been fully declared,
+	 attach it to that structure or union type, so we can go
+	 back and complete the variable declaration later, if the
+	 structure or union gets fully declared.
+
 	 If the input is erroneous, we can have error_mark in the type
 	 slot (e.g. "f(void a, ...)") - that doesn't count as an
-	 incomplete type.
-
-	 FIXME: Chain these off the TYPE_DECL for the incomplete type,
-	 then we don't have to do (potentially quite costly) searches
-	 in finish_struct.  */
+	 incomplete type.  */
       if (TREE_TYPE (x) != error_mark_node
 	  && !COMPLETE_TYPE_P (TREE_TYPE (x)))
 	{
@@ -1763,11 +1732,15 @@
 
 	  while (TREE_CODE (element) == ARRAY_TYPE)
 	    element = TREE_TYPE (element);
+	  element = TYPE_MAIN_VARIANT (element);
+
 	  if ((TREE_CODE (element) == RECORD_TYPE
 	       || TREE_CODE (element) == UNION_TYPE)
 	      && (TREE_CODE (x) != TYPE_DECL
-		  || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE))
-	    scope->incomplete = tree_cons (NULL_TREE, x, scope->incomplete);
+		  || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+	      && !COMPLETE_TYPE_P (element))
+	    C_TYPE_INCOMPLETE_VARS (element)
+	      = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element));
 	}
     }
 
@@ -1821,9 +1794,8 @@
       if (!C_DECL_IMPLICIT (decl))
 	{
 	  implicit_decl_warning (DECL_NAME (decl));
-	  if (! C_DECL_FILE_SCOPE (decl))
-	    warning ("%Hprevious declaration of '%D'",
-                     &DECL_SOURCE_LOCATION (decl), decl);
+	  if (! DECL_FILE_SCOPE_P (decl))
+	    warning ("%Jprevious declaration of '%D'", decl, decl);
 	  C_DECL_IMPLICIT (decl) = 1;
 	}
       /* If this function is global, then it must already be in the
@@ -1901,7 +1873,7 @@
 	return 1;
       return 0;
     }
-  else if (C_DECL_FILE_SCOPE (newdecl))
+  else if (DECL_FILE_SCOPE_P (newdecl))
     {
       /* Objects declared at file scope:  */
       /* If at least one is a reference, it's ok.  */
@@ -2058,8 +2030,7 @@
     if (dup == label)
       {
 	error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
-	error ("%Hthis is a previous declaration",
-	       &DECL_SOURCE_LOCATION (dup));
+	error ("%Jthis is a previous declaration", dup);
 
 	/* Just use the previous declaration.  */
 	return dup;
@@ -2094,12 +2065,11 @@
 	  || (DECL_CONTEXT (label) != current_function_decl
 	      && C_DECLARED_LABEL_FLAG (label))))
     {
-      location_t *prev_loc = &DECL_SOURCE_LOCATION (label);
       error ("%Hduplicate label `%D'", &location, label);
       if (DECL_INITIAL (label))
-	error ("%H`%D' previously defined here", prev_loc, label);
+	error ("%J`%D' previously defined here", label, label);
       else
-	error ("%H`%D' previously declared here", prev_loc, label);
+	error ("%J`%D' previously declared here", label, label);
       return 0;
     }
   else if (label && DECL_CONTEXT (label) == current_function_decl)
@@ -2578,8 +2548,7 @@
 
   if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
       && MAIN_NAME_P (DECL_NAME (decl)))
-    warning ("%H'%D' is usually a function",
-             &DECL_SOURCE_LOCATION (decl), decl);
+    warning ("%J'%D' is usually a function", decl, decl);
 
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
@@ -2679,11 +2648,30 @@
   decl_attributes (&decl, attributes, 0);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
+      && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
+    {
+      tree ce = declarator;
+
+      if (TREE_CODE (ce) == INDIRECT_REF)
+	ce = TREE_OPERAND (declarator, 0);
+      if (TREE_CODE (ce) == CALL_EXPR)
+	{
+	  tree args = TREE_PURPOSE (TREE_OPERAND (ce, 1));
+	  for (; args; args = TREE_CHAIN (args))
+	    {
+	      tree type = TREE_TYPE (args);
+	      if (INTEGRAL_TYPE_P (type)
+		  && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+		DECL_ARG_TYPE (args) = integer_type_node;
+	    }
+	}
+    }
+
+  if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
-    warning ("%Hinline function '%D' given attribute noinline",
-             &DECL_SOURCE_LOCATION (decl), decl);
+    warning ("%Jinline function '%D' given attribute noinline", decl, decl);
 
   /* Add this decl to the current scope.
      TEM may equal DECL or it may be a previous decl of the same name.  */
@@ -2695,7 +2683,7 @@
 	 and we preserved the rtl from the previous one
 	 (which may or may not happen).  */
       && !DECL_RTL_SET_P (tem)
-      && C_DECL_FILE_SCOPE (tem))
+      && DECL_FILE_SCOPE_P (tem))
     {
       if (TREE_TYPE (tem) != error_mark_node
 	  && (COMPLETE_TYPE_P (TREE_TYPE (tem))
@@ -2754,14 +2742,12 @@
       type = TREE_TYPE (decl);
 
       if (failure == 1)
-	error ("%Hinitializer fails to determine size of '%D'",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%Jinitializer fails to determine size of '%D'", decl, decl);
 
       else if (failure == 2)
 	{
 	  if (do_default)
-	    error ("%Harray size missing in '%D'",
-                   &DECL_SOURCE_LOCATION (decl), decl);
+	    error ("%Jarray size missing in '%D'", decl, decl);
 	  /* If a `static' var's size isn't known,
 	     make it extern as well as static, so it does not get
 	     allocated.
@@ -2777,8 +2763,7 @@
 	 warn only if the value is less than zero.  */
       else if (pedantic && TYPE_DOMAIN (type) != 0
 	      && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
-	error ("%Hzero or negative size array '%D'",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%Jzero or negative size array '%D'", decl, decl);
 
       layout_decl (decl, 0);
     }
@@ -2800,14 +2785,13 @@
 		   Otherwise, let it through, but if it is not `extern'
 		   then it may cause an error message later.  */
 		(DECL_INITIAL (decl) != 0
-		 || !C_DECL_FILE_SCOPE (decl))
+		 || !DECL_FILE_SCOPE_P (decl))
 	      :
 		/* An automatic variable with an incomplete type
 		   is an error.  */
 		!DECL_EXTERNAL (decl)))
 	{
-	  error ("%Hstorage size of '%D' isn't known",
-                 &DECL_SOURCE_LOCATION (decl), decl);
+	  error ("%Jstorage size of '%D' isn't known", decl, decl);
 	  TREE_TYPE (decl) = error_mark_node;
 	}
 
@@ -2817,8 +2801,7 @@
 	  if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
 	    constant_expression_warning (DECL_SIZE (decl));
 	  else
-	    error ("%Hstorage size of '%D' isn't constant",
-                   &DECL_SOURCE_LOCATION (decl), decl);
+	    error ("%Jstorage size of '%D' isn't constant", decl, decl);
 	}
 
       if (TREE_USED (type))
@@ -2871,7 +2854,7 @@
       if (c_dialect_objc ())
 	objc_check_decl (decl);
 
-      if (C_DECL_FILE_SCOPE (decl))
+      if (DECL_FILE_SCOPE_P (decl))
 	{
 	  if (DECL_INITIAL (decl) == NULL_TREE
 	      || DECL_INITIAL (decl) == error_mark_node)
@@ -2901,8 +2884,8 @@
 	      if (TREE_CODE (decl) == VAR_DECL
 		  && !DECL_REGISTER (decl)
 		  && !TREE_STATIC (decl))
-		warning ("%Hignoring asm-specifier for non-static local "
-                         "variable '%D'", &DECL_SOURCE_LOCATION (decl), decl);
+		warning ("%Jignoring asm-specifier for non-static local "
+                         "variable '%D'", decl, decl);
 	      else
 		SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
 	    }
@@ -2911,7 +2894,7 @@
 	    add_decl_stmt (decl);
 	}
 
-      if (!C_DECL_FILE_SCOPE (decl))
+      if (!DECL_FILE_SCOPE_P (decl))
 	{
 	  /* Recompute the RTL of a local array now
 	     if it used to be an incomplete type.  */
@@ -2936,7 +2919,7 @@
       /* This is a no-op in c-lang.c or something real in objc-act.c.  */
       if (c_dialect_objc ())
 	objc_check_decl (decl);
-      rest_of_decl_compilation (decl, NULL, C_DECL_FILE_SCOPE (decl), 0);
+      rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
     }
 
   /* At the end of a declaration, throw away any variable type sizes
@@ -4387,8 +4370,7 @@
 	  C_DECL_VARIABLE_SIZE (decl) = 1;
 
 	if (inlinep)
-	  pedwarn ("%Hvariable '%D' declared `inline'",
-                   &DECL_SOURCE_LOCATION (decl), decl);
+	  pedwarn ("%Jvariable '%D' declared `inline'", decl, decl);
 
 	DECL_EXTERNAL (decl) = extern_ref;
 
@@ -4580,10 +4562,6 @@
 	 declared types.  The back end may override this.  */
       type = TREE_TYPE (decl);
       DECL_ARG_TYPE (decl) = type;
-      if (PROMOTE_PROTOTYPES
-	  && INTEGRAL_TYPE_P (type)
-	  && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
-	DECL_ARG_TYPE (decl) = integer_type_node;
 
       /* Check for (..., void, ...) and issue an error.  */
       if (VOID_TYPE_P (type) && !DECL_NAME (decl) && !gave_void_only_once_err)
@@ -4605,8 +4583,8 @@
 	if (!TREE_ASM_WRITTEN (decl))
 	  abort ();
 
-	  error ("%Hparameter \"%D\" has just a forward declaration",
-		 &DECL_SOURCE_LOCATION (decl), decl);
+	  error ("%Jparameter \"%D\" has just a forward declaration",
+		 decl, decl);
       }
 
   /* Warn about any struct, union or enum tags defined within this
@@ -4842,8 +4820,7 @@
 	    for (y = fieldlist; y != x; y = TREE_CHAIN (y))
 	      if (DECL_NAME (y) == DECL_NAME (x))
 		{
-		  error ("%Hduplicate member '%D'",
-                         &DECL_SOURCE_LOCATION (x), x);
+		  error ("%Jduplicate member '%D'", x, x);
 		  DECL_NAME (x) = NULL_TREE;
 		}
 	  }
@@ -4859,8 +4836,7 @@
 	    slot = htab_find_slot (htab, y, INSERT);
 	    if (*slot)
 	      {
-		error ("%Hduplicate member '%D'",
-                       &DECL_SOURCE_LOCATION (x), x);
+		error ("%Jduplicate member '%D'", x, x);
 		DECL_NAME (x) = NULL_TREE;
 	      }
 	    *slot = y;
@@ -4961,8 +4937,7 @@
 	    constant_expression_warning (DECL_INITIAL (x));
 	  else
 	    {
-	      error ("%Hbit-field '%D' width not an integer constant",
-                     &DECL_SOURCE_LOCATION (x), x);
+	      error ("%Jbit-field '%D' width not an integer constant", x, x);
 	      DECL_INITIAL (x) = NULL;
 	    }
 	}
@@ -4973,8 +4948,7 @@
 	  && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
 	  && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
 	{
-	  error ("%Hbit-field '%D' has invalid type",
-                 &DECL_SOURCE_LOCATION (x), x);
+	  error ("%Jbit-field '%D' has invalid type", x, x);
 	  DECL_INITIAL (x) = NULL;
 	}
 
@@ -4986,8 +4960,7 @@
 	  && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
 	       && (TYPE_PRECISION (TREE_TYPE (x))
 		   == TYPE_PRECISION (integer_type_node))))
-	pedwarn ("%Hbit-field '%D' type invalid in ISO C",
-                 &DECL_SOURCE_LOCATION (x), x);
+	pedwarn ("%Jbit-field '%D' type invalid in ISO C", x, x);
 
       /* Detect and ignore out of range field width and process valid
 	 field widths.  */
@@ -4998,14 +4971,11 @@
 	       ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
 
 	  if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
-	    error ("%Hnegative width in bit-field '%D'",
-                   &DECL_SOURCE_LOCATION (x), x);
+	    error ("%Jnegative width in bit-field '%D'", x, x);
 	  else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
-	    pedwarn ("%Hwidth of '%D' exceeds its type",
-                     &DECL_SOURCE_LOCATION (x), x);
+	    pedwarn ("%Jwidth of '%D' exceeds its type", x, x);
 	  else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
-	    error ("%Hzero width for bit-field '%D'",
-                   &DECL_SOURCE_LOCATION (x), x);
+	    error ("%Jzero width for bit-field '%D'", x, x);
 	  else
 	    {
 	      /* The test above has assured us that TREE_INT_CST_HIGH is 0.  */
@@ -5018,8 +4988,7 @@
 		      || (width
 			  < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
 					   TREE_UNSIGNED (TREE_TYPE (x))))))
-		warning ("%H'%D' is narrower than values of its type",
-                         &DECL_SOURCE_LOCATION (x), x);
+		warning ("%J'%D' is narrower than values of its type", x, x);
 
 	      DECL_SIZE (x) = bitsize_int (width);
 	      DECL_BIT_FIELD (x) = 1;
@@ -5036,20 +5005,16 @@
 	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
 	{
 	  if (TREE_CODE (t) == UNION_TYPE)
-	    error ("%Hflexible array member in union",
-                   &DECL_SOURCE_LOCATION (x));
+	    error ("%Jflexible array member in union", x);
 	  else if (TREE_CHAIN (x) != NULL_TREE)
-	    error ("%Hflexible array member not at end of struct",
-                   &DECL_SOURCE_LOCATION (x));
+	    error ("%Jflexible array member not at end of struct", x);
 	  else if (! saw_named_field)
-	    error ("%Hflexible array member in otherwise empty struct",
-                   &DECL_SOURCE_LOCATION (x));
+	    error ("%Jflexible array member in otherwise empty struct", x);
 	}
 
       if (pedantic && TREE_CODE (t) == RECORD_TYPE
 	  && flexible_array_type_p (TREE_TYPE (x)))
-	pedwarn ("%Hinvalid use of structure with flexible array member",
-                 &DECL_SOURCE_LOCATION (x));
+	pedwarn ("%Jinvalid use of structure with flexible array member", x);
 
       if (DECL_NAME (x))
 	saw_named_field = 1;
@@ -5149,63 +5114,24 @@
 
   /* If this structure or union completes the type of any previous
      variable declaration, lay it out and output its rtl.  */
-
-  if (current_scope->incomplete != NULL_TREE)
-    {
-      tree prev = NULL_TREE;
-
-      for (x = current_scope->incomplete; x; x = TREE_CHAIN (x))
-        {
-	  tree decl = TREE_VALUE (x);
-
-	  if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
-	      && TREE_CODE (decl) != TYPE_DECL)
-	    {
-	      layout_decl (decl, 0);
-	      /* This is a no-op in c-lang.c or something real in
-		 objc-act.c.  */
-	      if (c_dialect_objc ())
-		objc_check_decl (decl);
-	      rest_of_decl_compilation (decl, NULL, toplevel, 0);
-	      if (! toplevel)
-		expand_decl (decl);
-	      /* Unlink X from the incomplete list.  */
-	      if (prev)
-		TREE_CHAIN (prev) = TREE_CHAIN (x);
-	      else
-	        current_scope->incomplete = TREE_CHAIN (x);
-	    }
-	  else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
-		   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
-	    {
-	      tree element = TREE_TYPE (decl);
-	      while (TREE_CODE (element) == ARRAY_TYPE)
-		element = TREE_TYPE (element);
-	      if (element == t)
-		{
-		  layout_array_type (TREE_TYPE (decl));
-		  if (TREE_CODE (decl) != TYPE_DECL)
-		    {
-		      layout_decl (decl, 0);
-		      if (c_dialect_objc ())
-			objc_check_decl (decl);
-		      rest_of_decl_compilation (decl, NULL, toplevel, 0);
-		      if (! toplevel)
-			expand_decl (decl);
-		    }
-		  /* Unlink X from the incomplete list.  */
-		  if (prev)
-		    TREE_CHAIN (prev) = TREE_CHAIN (x);
-		  else
-		    current_scope->incomplete = TREE_CHAIN (x);
-		}
-	      else
-		prev = x;
-	    }
-	  else
-	    prev = x;
+  for (x = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
+       x;
+       x = TREE_CHAIN (x))
+    {
+      tree decl = TREE_VALUE (x);
+      if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+	layout_array_type (TREE_TYPE (decl));
+      if (TREE_CODE (decl) != TYPE_DECL)
+	{
+	  layout_decl (decl, 0);
+	  if (c_dialect_objc ())
+	    objc_check_decl (decl);
+	  rest_of_decl_compilation (decl, NULL, toplevel, 0);
+	  if (! toplevel)
+	    expand_decl (decl);
 	}
     }
+  C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
 
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (t, toplevel);
@@ -5505,8 +5431,7 @@
   if (DECL_DECLARED_INLINE_P (decl1)
       && DECL_UNINLINABLE (decl1)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
-    warning ("%Hinline function '%D' given attribute noinline",
-             &DECL_SOURCE_LOCATION (decl1), decl1);
+    warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
 
   announce_function (decl1);
 
@@ -5556,29 +5481,27 @@
 	   && TREE_PUBLIC (decl1)
 	   && ! MAIN_NAME_P (DECL_NAME (decl1))
 	   && C_DECL_ISNT_PROTOTYPE (old_decl))
-    warning ("%Hno previous prototype for '%D'",
-             &DECL_SOURCE_LOCATION (decl1), decl1);
+    warning ("%Jno previous prototype for '%D'", decl1, decl1);
   /* Optionally warn of any def with no previous prototype
      if the function has already been used.  */
   else if (warn_missing_prototypes
 	   && old_decl != 0 && TREE_USED (old_decl)
 	   && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
-    warning ("%H'%D' was used with no prototype before its definition",
-             &DECL_SOURCE_LOCATION (decl1), decl1);
+    warning ("%J'%D' was used with no prototype before its definition",
+	     decl1, decl1);
   /* Optionally warn of any global def with no previous declaration.  */
   else if (warn_missing_declarations
 	   && TREE_PUBLIC (decl1)
 	   && old_decl == 0
 	   && ! MAIN_NAME_P (DECL_NAME (decl1)))
-    warning ("%Hno previous declaration for '%D'",
-             &DECL_SOURCE_LOCATION (decl1), decl1);
+    warning ("%Jno previous declaration for '%D'", decl1, decl1);
   /* Optionally warn of any def with no previous declaration
      if the function has already been used.  */
   else if (warn_missing_declarations
 	   && old_decl != 0 && TREE_USED (old_decl)
 	   && C_DECL_IMPLICIT (old_decl))
-    warning ("%H`%D' was used with no declaration before its definition",
-             &DECL_SOURCE_LOCATION (decl1), decl1);
+    warning ("%J`%D' was used with no declaration before its definition",
+	     decl1, decl1);
 
   /* This is a definition, not a reference.
      So normally clear DECL_EXTERNAL.
@@ -5610,11 +5533,10 @@
     {
       tree args;
       int argct = 0;
-      const location_t *locus = &DECL_SOURCE_LOCATION (decl1);
 
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
 	  != integer_type_node)
-	pedwarn ("%Hreturn type of '%D' is not `int'", locus, decl1);
+	pedwarn ("%Jreturn type of '%D' is not `int'", decl1, decl1);
 
       for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
 	   args = TREE_CHAIN (args))
@@ -5629,8 +5551,8 @@
 	    {
 	    case 1:
 	      if (TYPE_MAIN_VARIANT (type) != integer_type_node)
-		pedwarn ("%Hfirst argument of '%D' should be `int'",
-                         locus, decl1);
+		pedwarn ("%Jfirst argument of '%D' should be `int'",
+			 decl1, decl1);
 	      break;
 
 	    case 2:
@@ -5638,8 +5560,8 @@
 		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
 		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
 		      != char_type_node))
-		pedwarn ("%Hsecond argument of '%D' should be 'char **'",
-                         locus, decl1);
+		pedwarn ("%Jsecond argument of '%D' should be 'char **'",
+                         decl1, decl1);
 	      break;
 
 	    case 3:
@@ -5647,8 +5569,8 @@
 		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
 		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
 		      != char_type_node))
-		pedwarn ("%Hthird argument of '%D' should probably be "
-                         "'char **'", locus, decl1);
+		pedwarn ("%Jthird argument of '%D' should probably be "
+                         "'char **'", decl1, decl1);
 	      break;
 	    }
 	}
@@ -5657,10 +5579,10 @@
 	 argument because it's only mentioned in an appendix of the
 	 standard.  */
       if (argct > 0 && (argct < 2 || argct > 3))
-	pedwarn ("%H'%D' takes only zero or two arguments", locus, decl1);
+	pedwarn ("%J'%D' takes only zero or two arguments", decl1, decl1);
 
       if (! TREE_PUBLIC (decl1))
-	pedwarn ("%H'%D' is normally a non-static function", locus, decl1);
+	pedwarn ("%J'%D' is normally a non-static function", decl1, decl1);
     }
 
   /* Record the decl so that the function name is defined.
@@ -5719,8 +5641,8 @@
 
   if (current_scope->parms || current_scope->names || current_scope->tags)
     {
-      error ("%Hold-style parameter declarations in prototyped "
-	     "function definition", &DECL_SOURCE_LOCATION (fndecl));
+      error ("%Jold-style parameter declarations in prototyped "
+	     "function definition", fndecl);
 
       /* Get rid of the old-style declarations.  */
       poplevel (0, 0, 0);
@@ -5733,7 +5655,7 @@
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl) == 0)
-	error ("%Hparameter name omitted", &DECL_SOURCE_LOCATION (decl));
+	error ("%Jparameter name omitted", decl);
       else
 	{
 	  if (IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)))
@@ -5808,8 +5730,7 @@
     {
       if (TREE_VALUE (parm) == 0)
 	{
-	  error ("%Hparameter name missing from parameter list",
-		 &DECL_SOURCE_LOCATION (fndecl));
+	  error ("%Jparameter name missing from parameter list", fndecl);
 	  TREE_PURPOSE (parm) = 0;
 	  continue;
 	}
@@ -5817,15 +5738,14 @@
       decl = IDENTIFIER_SYMBOL_VALUE (TREE_VALUE (parm));
       if (decl && DECL_CONTEXT (decl) == fndecl)
 	{
-	  const location_t *locus = &DECL_SOURCE_LOCATION (decl);
 	  /* If we got something other than a PARM_DECL it is an error.  */
 	  if (TREE_CODE (decl) != PARM_DECL)
-	    error ("%H\"%D\" declared as a non-parameter", locus, decl);
+	    error ("%J\"%D\" declared as a non-parameter", decl, decl);
 	  /* If the declaration is already marked, we have a duplicate
 	     name.  Complain and ignore the duplicate.  */
 	  else if (DECL_WEAK (decl))
 	    {
-	      error ("%Hmultiple parameters named \"%D\"", locus, decl);
+	      error ("%Jmultiple parameters named \"%D\"", decl, decl);
 	      TREE_PURPOSE (parm) = 0;
 	      continue;
 	    }
@@ -5833,7 +5753,7 @@
 	     an int.  */
 	  else if (VOID_TYPE_P (TREE_TYPE (decl)))
 	    {
-	      error ("%Hparameter \"%D\" declared void", locus, decl);
+	      error ("%Jparameter \"%D\" declared void", decl, decl);
 	      TREE_TYPE (decl) = integer_type_node;
 	      DECL_ARG_TYPE (decl) = integer_type_node;
 	      layout_decl (decl, 0);
@@ -5842,16 +5762,15 @@
       /* If no declaration found, default to int.  */
       else
 	{
-	  const location_t *locus = &DECL_SOURCE_LOCATION (fndecl);
 	  decl = build_decl (PARM_DECL, TREE_VALUE (parm), integer_type_node);
 	  DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
-	  DECL_SOURCE_LOCATION (decl) = *locus;
+	  DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (fndecl);
 	  pushdecl (decl);
 
 	  if (flag_isoc99)
-	    pedwarn ("%Htype of \"%D\" defaults to \"int\"", locus, decl);
+	    pedwarn ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
 	  else if (extra_warnings)
-	    warning ("%Htype of \"%D\" defaults to \"int\"", locus, decl);
+	    warning ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
 	}
 
       TREE_PURPOSE (parm) = decl;
@@ -5863,18 +5782,16 @@
 
   for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
     {
-      const location_t *locus = &DECL_SOURCE_LOCATION (parm);
-
       if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
 	{
-	  error ("%Hparameter \"%D\" has incomplete type", locus, parm);
+	  error ("%Jparameter \"%D\" has incomplete type", parm, parm);
 	  TREE_TYPE (parm) = error_mark_node;
 	}
 
       if (! DECL_WEAK (parm))
 	{
-	  error ("%Hdeclaration for parameter \"%D\" but no such parameter",
-		 locus, parm);
+	  error ("%Jdeclaration for parameter \"%D\" but no such parameter",
+		 parm, parm);
 
 	  /* Pretend the parameter was not missing.
 	     This gets us to a standard state and minimizes
@@ -5947,7 +5864,7 @@
 		     useful for argument types like uid_t.  */
 		  DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
 
-		  if (PROMOTE_PROTOTYPES
+		  if (targetm.calls.promote_prototypes (TREE_TYPE (current_function_decl))
 		      && INTEGRAL_TYPE_P (TREE_TYPE (parm))
 		      && TYPE_PRECISION (TREE_TYPE (parm))
 		      < TYPE_PRECISION (integer_type_node))
@@ -6041,7 +5958,7 @@
   gen_aux_info_record (fndecl, 1, 0, prototype);
 
   /* Initialize the RTL code for the function.  */
-  init_function_start (fndecl);
+  allocate_struct_function (fndecl);
 
   /* Begin the statement tree for this function.  */
   begin_stmt_tree (&DECL_SAVED_TREE (fndecl));
@@ -6078,13 +5995,10 @@
    all the way to assembler language output.  The free the storage
    for the function definition.
 
-   This is called after parsing the body of the function definition.
-
-   NESTED is nonzero if the function being finished is nested in another.
-   CAN_DEFER_P is nonzero if the function may be deferred.  */
+   This is called after parsing the body of the function definition.  */
 
 void
-finish_function (int nested, int can_defer_p)
+finish_function ()
 {
   tree fndecl = current_function_decl;
 
@@ -6104,6 +6018,19 @@
       poplevel (0, 0, 0);
     }
 
+  if (TREE_CODE (fndecl) == FUNCTION_DECL
+      && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
+    {
+      tree args = DECL_ARGUMENTS (fndecl);
+      for (; args; args = TREE_CHAIN (args))
+ 	{
+ 	  tree type = TREE_TYPE (args);
+ 	  if (INTEGRAL_TYPE_P (type)
+ 	      && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ 	    DECL_ARG_TYPE (args) = integer_type_node;
+ 	}
+    }
+
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
 
   /* Must mark the RESULT_DECL as being in this function.  */
@@ -6118,8 +6045,7 @@
 	  /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
 	     If warn_main is -1 (-Wno-main) we don't want to be warned.  */
 	  if (!warn_main)
-	    pedwarn ("%Hreturn type of '%D' is not `int'",
-                     &DECL_SOURCE_LOCATION (fndecl), fndecl);
+	    pedwarn ("%Jreturn type of '%D' is not `int'", fndecl, fndecl);
 	}
       else
 	{
@@ -6153,84 +6079,27 @@
       && DECL_INLINE (fndecl))
     warning ("no return statement in function returning non-void");
 
-  /* Clear out memory we no longer need.  */
-  free_after_parsing (cfun);
-  /* Since we never call rest_of_compilation, we never clear
-     CFUN.  Do so explicitly.  */
-  free_after_compilation (cfun);
-  cfun = NULL;
-
-  if (flag_unit_at_a_time && can_defer_p)
-    {
-      cgraph_finalize_function (fndecl, DECL_SAVED_TREE (fndecl));
-      current_function_decl = NULL;
-      return;
-    }
-
-  if (! nested)
-    {
-      /* Function is parsed.
-	 Generate RTL for the body of this function or defer
-	 it for later expansion.  */
-      bool uninlinable = true;
-
-      /* There's no reason to do any of the work here if we're only doing
-	 semantic analysis; this code just generates RTL.  */
-      if (flag_syntax_only)
-	{
-	  current_function_decl = NULL;
-	  DECL_SAVED_TREE (fndecl) = NULL_TREE;
-	  return;
-	}
-
-      if (flag_inline_trees && !EMIT_LLVM)
-	{
-	  /* First, cache whether the current function is inlinable.  Some
-	     predicates depend on cfun and current_function_decl to
-	     function completely.  */
-	  timevar_push (TV_INTEGRATION);
-	  uninlinable = !tree_inlinable_function_p (fndecl);
-
-	  if (can_defer_p
-	      /* We defer functions marked inline *even if* the function
-		 itself is not inlinable.  This is because we don't yet
-		 know if the function will actually be used; we may be
-		 able to avoid emitting it entirely.  */
-	      && (!uninlinable || DECL_DECLARED_INLINE_P (fndecl))
-	      /* Save function tree for inlining.  Should return 0 if the
-		 language does not support function deferring or the
-		 function could not be deferred.  */
-	      && defer_fn (fndecl))
-	    {
-	      /* Let the back-end know that this function exists.  */
-	      (*debug_hooks->deferred_inline_function) (fndecl);
-	      timevar_pop (TV_INTEGRATION);
-	      current_function_decl = NULL;
-	      return;
-	    }
-
-	  /* Then, inline any functions called in it.  */
-	  optimize_inline_calls (fndecl);
-	  timevar_pop (TV_INTEGRATION);
-	}
-
-      if (EMIT_LLVM)
-        llvm_c_expand_body (fndecl);
-      else
-        c_expand_body (fndecl);
+  /* With just -Wextra, complain only if function returns both with
+     and without a value.  */
+  if (extra_warnings
+      && current_function_returns_value
+      && current_function_returns_null)
+    warning ("this function may return with or without a value");
 
-      /* Keep the function body if it's needed for inlining or dumping.  */
-      if (uninlinable && !dump_enabled_p (TDI_all))
-	{
-	  /* Allow the body of the function to be garbage collected.  */
-	  DECL_SAVED_TREE (fndecl) = NULL_TREE;
-	}
+  /* We're leaving the context of this function, so zap cfun.  It's still in
+     DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation.  */
+  cfun = NULL;
 
-      /* Let the error reporting routines know that we're outside a
-	 function.  For a nested function, this value is used in
-	 c_pop_function_context and then reset via pop_function_context.  */
-      current_function_decl = NULL;
-    }
+  /* ??? Objc emits functions after finalizing the compilation unit.
+     This should be cleaned up later and this conditional removed.  */
+  if (!cgraph_global_info_ready)
+    cgraph_finalize_function (fndecl, false);
+  else
+    if (EMIT_LLVM)
+      llvm_c_expand_body (fndecl);
+    else
+      c_expand_body (fndecl);
+  current_function_decl = NULL;
 }
 
 /* Generate the RTL for a deferred function FNDECL.  */
@@ -6256,152 +6125,28 @@
     }
 }
 
-/* Called to move the SAVE_EXPRs for parameter declarations in a
-   nested function into the nested function.  DATA is really the
-   nested FUNCTION_DECL.  */
-
-static tree
-set_save_expr_context (tree *tp,
-		       int *walk_subtrees,
-		       void *data)
-{
-  if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
-    SAVE_EXPR_CONTEXT (*tp) = (tree) data;
-  /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
-     circularity.  */
-  else if (DECL_P (*tp))
-    *walk_subtrees = 0;
-
-  return NULL_TREE;
-}
-
 /* Generate the RTL for the body of FNDECL.  If NESTED_P is nonzero,
    then we are already in the process of generating RTL for another
-   function.  If can_defer_p is zero, we won't attempt to defer the
-   generation of RTL.  */
+   function.  */
 
 static void
 c_expand_body_1 (tree fndecl, int nested_p)
 {
-  timevar_push (TV_EXPAND);
-
   if (nested_p)
     {
       /* Make sure that we will evaluate variable-sized types involved
 	 in our function's type.  */
       expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes);
+
       /* Squirrel away our current state.  */
       push_function_context ();
     }
 
-  /* Initialize the RTL code for the function.  */
-  current_function_decl = fndecl;
-  input_location = DECL_SOURCE_LOCATION (fndecl);
-  init_function_start (fndecl);
-
-  /* This function is being processed in whole-function mode.  */
-  cfun->x_whole_function_mode_p = 1;
-
-  /* Even though we're inside a function body, we still don't want to
-     call expand_expr to calculate the size of a variable-sized array.
-     We haven't necessarily assigned RTL to all variables yet, so it's
-     not safe to try to expand expressions involving them.  */
-  immediate_size_expand = 0;
-  cfun->x_dont_save_pending_sizes_p = 1;
-
-  /* Set up parameters and prepare for return, for the function.  */
-  expand_function_start (fndecl, 0);
-
-  /* If the function has a variably modified type, there may be
-     SAVE_EXPRs in the parameter types.  Their context must be set to
-     refer to this function; they cannot be expanded in the containing
-     function.  */
-  if (decl_function_context (fndecl)
-      && variably_modified_type_p (TREE_TYPE (fndecl)))
-    walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
-	       NULL);
-
-  /* If this function is `main', emit a call to `__main'
-     to run global initializers, etc.  */
-  if (DECL_NAME (fndecl)
-      && MAIN_NAME_P (DECL_NAME (fndecl))
-      && C_DECL_FILE_SCOPE (fndecl))
-    expand_main_function ();
-
-  /* Generate the RTL for this function.  */
-  expand_stmt (DECL_SAVED_TREE (fndecl));
-
-  /* We hard-wired immediate_size_expand to zero above.
-     expand_function_end will decrement this variable.  So, we set the
-     variable to one here, so that after the decrement it will remain
-     zero.  */
-  immediate_size_expand = 1;
-
-  /* Allow language dialects to perform special processing.  */
-  if (lang_expand_function_end)
-    (*lang_expand_function_end) ();
-
-  /* Generate rtl for function exit.  */
-  expand_function_end ();
-
-  /* If this is a nested function, protect the local variables in the stack
-     above us from being collected while we're compiling this function.  */
-  if (nested_p)
-    ggc_push_context ();
-
-  /* Run the optimizers and output the assembler code for this function.  */
-  rest_of_compilation (fndecl);
+  tree_rest_of_compilation (fndecl, nested_p);
 
-  /* Undo the GC context switch.  */
   if (nested_p)
-    ggc_pop_context ();
-
-  /* With just -Wextra, complain only if function returns both with
-     and without a value.  */
-  if (extra_warnings
-      && current_function_returns_value
-      && current_function_returns_null)
-    warning ("this function may return with or without a value");
-
-  /* If requested, warn about function definitions where the function will
-     return a value (usually of some struct or union type) which itself will
-     take up a lot of stack space.  */
-
-  if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
-    {
-      tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
-
-      if (ret_type && TYPE_SIZE_UNIT (ret_type)
-	  && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
-	  && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
-				   larger_than_size))
-	{
-          const location_t *locus = &DECL_SOURCE_LOCATION (fndecl);
-	  unsigned int size_as_int
-	    = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
-
-	  if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
-	    warning ("%Hsize of return value of '%D' is %u bytes",
-                     locus, fndecl, size_as_int);
-	  else
-	    warning ("%Hsize of return value of '%D' is larger than %wd bytes",
-                     locus, fndecl, larger_than_size);
-	}
-    }
-
-  if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested_p
-      && ! flag_inline_trees)
-    {
-      /* Stop pointing to the local nodes about to be freed.
-	 But DECL_INITIAL must remain nonzero so we know this
-	 was an actual function definition.
-	 For a nested function, this is done in c_pop_function_context.
-	 If rest_of_compilation set this to 0, leave it 0.  */
-      if (DECL_INITIAL (fndecl) != 0)
-	DECL_INITIAL (fndecl) = error_mark_node;
-
-      DECL_ARGUMENTS (fndecl) = 0;
-    }
+    /* Return to the enclosing function.  */
+    pop_function_context ();
 
   if (DECL_STATIC_CONSTRUCTOR (fndecl))
     {
@@ -6420,11 +6165,6 @@
       else
 	static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
     }
-
-  if (nested_p)
-    /* Return to the enclosing function.  */
-    pop_function_context ();
-  timevar_pop (TV_EXPAND);
 }
 
 /* Like c_expand_body_1 but only for unnested functions.  */
@@ -6485,16 +6225,15 @@
 
   for (t = getdecls (); t; t = TREE_CHAIN (t))
     {
-      const location_t *locus = &DECL_SOURCE_LOCATION (t);
       if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
-	error ("%Hdeclaration of non-variable '%D' in 'for' loop "
-               "initial declaration", locus, t);
+	error ("%Jdeclaration of non-variable '%D' in 'for' loop "
+               "initial declaration", t, t);
       else if (TREE_STATIC (t))
-	error ("%Hdeclaration of static variable '%D' in 'for' loop "
-	       "initial declaration", locus, t);
+	error ("%Jdeclaration of static variable '%D' in 'for' loop "
+	       "initial declaration", t, t);
       else if (DECL_EXTERNAL (t))
-	error ("%Hdeclaration of 'extern' variable '%D' in 'for' loop "
-               "initial declaration", locus, t);
+	error ("%Jdeclaration of 'extern' variable '%D' in 'for' loop "
+               "initial declaration", t, t);
     }
 }
 
@@ -6658,7 +6397,7 @@
 identifier_global_value	(tree t)
 {
   tree decl = IDENTIFIER_SYMBOL_VALUE (t);
-  if (decl == 0 || C_DECL_FILE_SCOPE (decl))
+  if (decl == 0 || DECL_FILE_SCOPE_P (decl))
     return decl;
 
   /* Shadowed by something else; find the true global value.  */
@@ -6816,10 +6555,8 @@
 		}
 	      else
 		{
-		  error ("%Hredefinition of global '%D'",
-                         &DECL_SOURCE_LOCATION (decl), decl);
-		  error ("%H'%D' previously defined here",
-                         &DECL_SOURCE_LOCATION (old_decl), old_decl);
+		  error ("%Jredefinition of global '%D'", decl, decl);
+		  error ("%J'%D' previously defined here", old_decl, old_decl);
 		}
 	    }
 	  else
@@ -6888,6 +6625,7 @@
       current_scope = global_scope;
   file_scope_decl = current_file_decl;
   DECL_INITIAL (file_scope_decl) = poplevel (1, 0, 0);
+  BLOCK_SUPERCONTEXT (DECL_INITIAL (file_scope_decl)) = file_scope_decl;
   truly_local_externals = NULL_TREE;
 
   /* Start a new global binding level.  */


Index: gcc-3.4/gcc/c-lang.c
diff -u gcc-3.4/gcc/c-lang.c:1.2 gcc-3.4/gcc/c-lang.c:1.3
--- gcc-3.4/gcc/c-lang.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-lang.c	Thu Feb  5 10:05:44 2004
@@ -33,6 +33,9 @@
 #include "diagnostic.h"
 #include "c-pretty-print.h"
 
+#include "llvm-out.h"
+#include "llvm-internals.h"
+
 static void c_initialize_diagnostics (diagnostic_context *);
 
 enum c_language_kind c_language = clk_c;
@@ -96,6 +99,14 @@
 #undef LANG_HOOKS_DECL_UNINIT
 #define LANG_HOOKS_DECL_UNINIT c_decl_uninit
 
+#undef LANG_HOOKS_RTL_EXPAND_STMT
+#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
+
+#ifdef EMIT_LLVM
+#undef LANG_HOOKS_LLVM_IR_EXPAND_STMT
+#define LANG_HOOKS_LLVM_IR_EXPAND_STMT llvm_expand_stmt
+#endif
+
 /* Attribute hooks.  */
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
@@ -122,6 +133,9 @@
 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
 
+#undef LANG_HOOKS_LLVM_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_LLVM_CALLGRAPH_EXPAND_FUNCTION llvm_c_expand_body
+
 #undef LANG_HOOKS_TYPE_FOR_MODE
 #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
 #undef LANG_HOOKS_TYPE_FOR_SIZE
@@ -136,6 +150,8 @@
 #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
 #undef LANG_HOOKS_TYPE_PROMOTES_TO
 #define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
+#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
 
 #undef LANG_HOOKS_WRITE_GLOBALS
 #define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations


Index: gcc-3.4/gcc/c-lex.c
diff -u gcc-3.4/gcc/c-lex.c:1.2 gcc-3.4/gcc/c-lex.c:1.3
--- gcc-3.4/gcc/c-lex.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-lex.c	Thu Feb  5 10:05:44 2004
@@ -200,8 +200,11 @@
    lexed token on the line.  Used for diagnostic line numbers.  */
 static void
 cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
-		int parsing_args ATTRIBUTE_UNUSED)
+		int parsing_args)
 {
+  if (token->type == CPP_EOF || parsing_args)
+    return;
+
   src_lineno = SOURCE_LINE (map, token->line);
 }
 
@@ -215,8 +218,6 @@
 void
 fe_file_change (const struct line_map *new_map)
 {
-  unsigned int to_line = SOURCE_LINE (new_map, new_map->to_line);
-
   if (new_map->reason == LC_ENTER)
     {
       /* Don't stack the main buffer on the input stack;
@@ -253,13 +254,13 @@
 #endif
       pop_srcloc ();
 
-      (*debug_hooks->end_source_file) (to_line);
+      (*debug_hooks->end_source_file) (new_map->to_line);
     }
 
   update_header_times (new_map->to_file);
   in_system_header = new_map->sysp != 0;
   input_filename = new_map->to_file;
-  input_line = to_line;
+  input_line = new_map->to_line;
   map = new_map;
 
   /* Hook for C++.  */


Index: gcc-3.4/gcc/c-pragma.c
diff -u gcc-3.4/gcc/c-pragma.c:1.3 gcc-3.4/gcc/c-pragma.c:1.4
--- gcc-3.4/gcc/c-pragma.c:1.3	Tue Jan 13 17:13:08 2004
+++ gcc-3.4/gcc/c-pragma.c	Thu Feb  5 10:05:44 2004
@@ -277,8 +277,8 @@
   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
       && !DECL_WEAK (decl) /* don't complain about a redundant #pragma */
       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
-    warning ("%Happlying #pragma weak '%D' after first use results "
-             "in unspecified behavior", &DECL_SOURCE_LOCATION (decl), decl);
+    warning ("%Japplying #pragma weak '%D' after first use results "
+             "in unspecified behavior", decl, decl);
 
   declare_weak (decl);
 }


Index: gcc-3.4/gcc/c-pretty-print.c
diff -u gcc-3.4/gcc/c-pretty-print.c:1.1.1.2 gcc-3.4/gcc/c-pretty-print.c:1.2
--- gcc-3.4/gcc/c-pretty-print.c:1.1.1.2	Tue Jan 13 10:48:59 2004
+++ gcc-3.4/gcc/c-pretty-print.c	Thu Feb  5 10:05:44 2004
@@ -27,6 +27,11 @@
 #include "c-pretty-print.h"
 #include "c-tree.h"
 
+#include "llvm-out.h"
+#ifdef EMIT_LLVM
+#include "assert.h"
+#endif
+
 /* The pretty-printer code is primarily designed to closely follow
    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
    codes we used to have in the past.  Following a structured
@@ -281,9 +286,16 @@
     case INTEGER_TYPE:
     case REAL_TYPE:
       if (TYPE_NAME (t))
+      {
         t = TYPE_NAME (t);
+      }
       else
+      {
         t = c_common_type_for_mode (TYPE_MODE (t), TREE_UNSIGNED (t));
+      }
+#ifdef EMIT_LLVM
+      assert ((t != NULL_TREE) && "t is equal to NULL_TREE");
+#endif
       pp_c_type_specifier (pp, t);
       break;
 


Index: gcc-3.4/gcc/c-semantics.c
diff -u gcc-3.4/gcc/c-semantics.c:1.2 gcc-3.4/gcc/c-semantics.c:1.3
--- gcc-3.4/gcc/c-semantics.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-semantics.c	Thu Feb  5 10:05:44 2004
@@ -648,6 +648,7 @@
 	  if (TREE_CODE (fn) == FUNCTION_DECL
 	      && DECL_CONTEXT (fn) == current_function_decl
 	      && DECL_SAVED_INSNS (fn)
+	      && DECL_SAVED_INSNS (fn)->saved_for_inline
 	      && !TREE_ASM_WRITTEN (fn)
 	      && TREE_ADDRESSABLE (fn))
 	    {


Index: gcc-3.4/gcc/c-typeck.c
diff -u gcc-3.4/gcc/c-typeck.c:1.2 gcc-3.4/gcc/c-typeck.c:1.3
--- gcc-3.4/gcc/c-typeck.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/c-typeck.c	Thu Feb  5 10:05:44 2004
@@ -51,6 +51,7 @@
 static int missing_braces_mentioned;
 
 static tree qualify_type (tree, tree);
+static int same_translation_unit_p (tree, tree);
 static int tagged_types_tu_compatible_p (tree, tree, int);
 static int comp_target_types (tree, tree, int);
 static int function_types_compatible_p (tree, tree, int);
@@ -565,7 +566,7 @@
 
     case ENUMERAL_TYPE:
     case UNION_TYPE:
-      if (val != 1 && (flags & COMPARE_DIFFERENT_TU))
+      if (val != 1 && !same_translation_unit_p (t1, t2))
 	val = tagged_types_tu_compatible_p (t1, t2, flags);
       break;
 
@@ -607,6 +608,34 @@
 
 /* Subroutines of `comptypes'.  */
 
+/* Determine whether two types derive from the same translation unit.
+   If the CONTEXT chain ends in a null, that type's context is still
+   being parsed, so if two types have context chains ending in null,
+   they're in the same translation unit.  */
+static int
+same_translation_unit_p (tree t1, tree t2)
+{
+  while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
+    switch (TREE_CODE_CLASS (TREE_CODE (t1)))
+      {
+      case 'd': t1 = DECL_CONTEXT (t1); break;
+      case 't': t1 = TYPE_CONTEXT (t1); break;
+      case 'b': t1 = BLOCK_SUPERCONTEXT (t1); break;
+      default: abort ();
+      }
+
+  while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
+    switch (TREE_CODE_CLASS (TREE_CODE (t2)))
+      {
+      case 'd': t2 = DECL_CONTEXT (t1); break;
+      case 't': t2 = TYPE_CONTEXT (t2); break;
+      case 'b': t2 = BLOCK_SUPERCONTEXT (t2); break;
+      default: abort ();
+      }
+
+  return t1 == t2;
+}
+
 /* The C standard says that two structures in different translation
    units are compatible with each other only if the types of their
    fields are compatible (among other things).  So, consider two copies
@@ -1553,7 +1582,7 @@
       /* Properly declared variable or function reference.  */
       if (!objc_ivar)
 	ref = decl;
-      else if (decl != objc_ivar && !C_DECL_FILE_SCOPE (decl))
+      else if (decl != objc_ivar && !DECL_FILE_SCOPE_P (decl))
 	{
 	  warning ("local declaration of `%s' hides instance variable",
 		   IDENTIFIER_POINTER (id));
@@ -1593,7 +1622,7 @@
       TREE_CONSTANT (ref) = 1;
     }
   else if (current_function_decl != 0
-	   && !C_DECL_FILE_SCOPE (current_function_decl)
+	   && !DECL_FILE_SCOPE_P (current_function_decl)
 	   && (TREE_CODE (ref) == VAR_DECL
 	       || TREE_CODE (ref) == PARM_DECL
 	       || TREE_CODE (ref) == FUNCTION_DECL))
@@ -1845,7 +1874,7 @@
 					        (char *) 0, /* arg passing  */
 						fundecl, name, parmnum + 1);
 
-	      if (PROMOTE_PROTOTYPES
+	      if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
 		  && INTEGRAL_TYPE_P (type)
 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
 		parmval = default_conversion (parmval);
@@ -2452,7 +2481,7 @@
 	   file-scope function counts as a constant.  */
 	if (staticp (arg)
 	    && ! (TREE_CODE (arg) == FUNCTION_DECL
-		  && !C_DECL_FILE_SCOPE (arg)))
+		  && !DECL_FILE_SCOPE_P (arg)))
 	  TREE_CONSTANT (addr) = 1;
 	return addr;
       }
@@ -3603,7 +3632,7 @@
   ret = convert_for_assignment (type, value,
 				(char *) 0 /* arg passing  */, fn,
 				DECL_NAME (fn), 0);
-  if (PROMOTE_PROTOTYPES
+  if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
       && INTEGRAL_TYPE_P (type)
       && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
     ret = default_conversion (ret);
@@ -6611,7 +6640,6 @@
       break;
 
     case BIT_AND_EXPR:
-    case BIT_ANDTC_EXPR:
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)


Index: gcc-3.4/gcc/calls.c
diff -u gcc-3.4/gcc/calls.c:1.2 gcc-3.4/gcc/calls.c:1.3
--- gcc-3.4/gcc/calls.c:1.2	Fri Jan  9 10:13:11 2004
+++ gcc-3.4/gcc/calls.c	Thu Feb  5 10:05:44 2004
@@ -1,5 +1,5 @@
 /* Convert function calls to rtl insns, for GNU C compiler.
-   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
+   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1184,9 +1184,8 @@
       mode = TYPE_MODE (type);
       unsignedp = TREE_UNSIGNED (type);
 
-#ifdef PROMOTE_FUNCTION_ARGS
-      mode = promote_mode (type, mode, &unsignedp, 1);
-#endif
+      if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0))
+	mode = promote_mode (type, mode, &unsignedp, 1);
 
       args[i].unsignedp = unsignedp;
       args[i].mode = mode;
@@ -1827,8 +1826,7 @@
   if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
       && optimize > 0 && !TREE_ADDRESSABLE (fndecl))
     {
-      warning ("%Hinlining failed in call to '%F'",
-               &DECL_SOURCE_LOCATION (fndecl), fndecl);
+      warning ("%Jinlining failed in call to '%F'", fndecl, fndecl);
       warning ("called from here");
     }
   (*lang_hooks.mark_addressable) (fndecl);
@@ -2067,6 +2065,7 @@
   /* Nonzero if called function returns an aggregate in memory PCC style,
      by returning the address of where to find it.  */
   int pcc_struct_value = 0;
+  rtx struct_value = 0;
 
   /* Number of actual parameters in this call, including struct value addr.  */
   int num_actuals;
@@ -2167,20 +2166,34 @@
 	  if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
 	      && optimize > 0)
 	    {
-	      warning ("%Hcan't inline call to '%F'",
-                       &DECL_SOURCE_LOCATION (fndecl), fndecl);
+	      warning ("%Jcan't inline call to '%F'", fndecl, fndecl);
 	      warning ("called from here");
 	    }
 	  (*lang_hooks.mark_addressable) (fndecl);
 	}
 
+      if (ignore
+	  && lookup_attribute ("warn_unused_result",
+			       TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+	warning ("ignoring return value of `%D', "
+		 "declared with attribute warn_unused_result", fndecl);
+
       flags |= flags_from_decl_or_type (fndecl);
     }
 
   /* If we don't have specific function to call, see if we have a
      attributes set in the type.  */
   else
-    flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
+    {
+      if (ignore
+	  && lookup_attribute ("warn_unused_result",
+			       TYPE_ATTRIBUTES (TREE_TYPE (TREE_TYPE (p)))))
+	warning ("ignoring return value of function "
+		 "declared with attribute warn_unused_result");
+      flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
+    }
+
+  struct_value = targetm.calls.struct_value_rtx (fndecl ? TREE_TYPE (fndecl) : 0, 0);
 
   /* Warn if this value is an aggregate type,
      regardless of which calling convention we are using for it.  */
@@ -2229,7 +2242,7 @@
   /* Set up a place to return a structure.  */
 
   /* Cater to broken compilers.  */
-  if (aggregate_value_p (exp))
+  if (aggregate_value_p (exp, fndecl))
     {
       /* This call returns a big structure.  */
       flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
@@ -2323,7 +2336,7 @@
 
   /* If struct_value_rtx is 0, it means pass the address
      as if it were an extra parameter.  */
-  if (structure_value_addr && struct_value_rtx == 0)
+  if (structure_value_addr && struct_value == 0)
     {
       /* If structure_value_addr is a REG other than
 	 virtual_outgoing_args_rtx, we can use always use it.  If it
@@ -2349,6 +2362,14 @@
   for (p = actparms, num_actuals = 0; p; p = TREE_CHAIN (p))
     num_actuals++;
 
+  /* Start updating where the next arg would go.
+
+     On some machines (such as the PA) indirect calls have a difuferent
+     calling convention than normal calls.  The last argument in
+     INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
+     or not.  */
+  INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl);
+
   /* Compute number of named args.
      Normally, don't include the last named arg if anonymous args follow.
      We do include the last named arg if STRICT_ARGUMENT_NAMING is nonzero.
@@ -2365,27 +2386,19 @@
      reliable way to pass unnamed args in registers, so we must force
      them into memory.  */
 
-  if ((STRICT_ARGUMENT_NAMING
-       || ! PRETEND_OUTGOING_VARARGS_NAMED)
+  if ((targetm.calls.strict_argument_naming (&args_so_far)
+       || ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
       && type_arg_types != 0)
     n_named_args
       = (list_length (type_arg_types)
 	 /* Don't include the last named arg.  */
-	 - (STRICT_ARGUMENT_NAMING ? 0 : 1)
+	 - (targetm.calls.strict_argument_naming (&args_so_far) ? 0 : 1)
 	 /* Count the struct value address, if it is passed as a parm.  */
 	 + structure_value_addr_parm);
   else
     /* If we know nothing, treat all args as named.  */
     n_named_args = num_actuals;
 
-  /* Start updating where the next arg would go.
-
-     On some machines (such as the PA) indirect calls have a different
-     calling convention than normal calls.  The last argument in
-     INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
-     or not.  */
-  INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl);
-
   /* Make a vector to hold all the information about each arg.  */
   args = alloca (num_actuals * sizeof (struct arg_data));
   memset (args, 0, num_actuals * sizeof (struct arg_data));
@@ -3018,18 +3031,15 @@
 	 structure value.  */
       if (pass != 0 && structure_value_addr && ! structure_value_addr_parm)
 	{
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (GET_MODE (structure_value_addr) != Pmode)
-	    structure_value_addr = convert_memory_address
-					(Pmode, structure_value_addr);
-#endif
-	  emit_move_insn (struct_value_rtx,
+	  structure_value_addr 
+	    = convert_memory_address (Pmode, structure_value_addr);
+	  emit_move_insn (struct_value,
 			  force_reg (Pmode,
 				     force_operand (structure_value_addr,
 						    NULL_RTX)));
 
-	  if (GET_CODE (struct_value_rtx) == REG)
-	    use_reg (&call_fusage, struct_value_rtx);
+	  if (GET_CODE (struct_value) == REG)
+	    use_reg (&call_fusage, struct_value);
 	}
 
       funexp = prepare_call_address (funexp, fndecl, &call_fusage,
@@ -3076,10 +3086,19 @@
       if (pass && (flags & ECF_LIBCALL_BLOCK))
 	{
 	  rtx insns;
+	  rtx insn;
+	  bool failed = valreg == 0 || GET_CODE (valreg) == PARALLEL;
 
-	  if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
+          insns = get_insns ();
+
+	  /* Expansion of block moves possibly introduced a loop that may
+	     not appear inside libcall block.  */
+	  for (insn = insns; insn; insn = NEXT_INSN (insn))
+	    if (GET_CODE (insn) == JUMP_INSN)
+	      failed = true;
+
+	  if (failed)
 	    {
-	      insns = get_insns ();
 	      end_sequence ();
 	      emit_insn (insns);
 	    }
@@ -3100,7 +3119,6 @@
 					  args[i].initial_value, note);
 	      note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
 
-	      insns = get_insns ();
 	      end_sequence ();
 
 	      if (flags & ECF_PURE)
@@ -3253,7 +3271,8 @@
       else
 	target = copy_to_reg (valreg);
 
-#ifdef PROMOTE_FUNCTION_RETURN
+      if (targetm.calls.promote_function_return(funtype))
+	{
       /* If we promoted this return value, make the proper SUBREG.  TARGET
 	 might be const0_rtx here, so be careful.  */
       if (GET_CODE (target) == REG
@@ -3284,7 +3303,7 @@
 	  SUBREG_PROMOTED_VAR_P (target) = 1;
 	  SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
 	}
-#endif
+	}
 
       /* If size of args is variable or this was a constructor call for a stack
 	 argument, restore saved stack-pointer value.  */
@@ -3593,6 +3612,8 @@
   int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
   char *initial_stack_usage_map = stack_usage_map;
 
+  rtx struct_value = targetm.calls.struct_value_rtx (0, 0);
+
 #ifdef REG_PARM_STACK_SPACE
 #ifdef MAYBE_REG_PARM_STACK_SPACE
   reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
@@ -3645,7 +3666,7 @@
   if (outmode != VOIDmode)
     {
       tfom = (*lang_hooks.types.type_for_mode) (outmode, 0);
-      if (aggregate_value_p (tfom))
+      if (aggregate_value_p (tfom, 0))
 	{
 #ifdef PCC_STATIC_STRUCT_RETURN
 	  rtx pointer_reg
@@ -3700,7 +3721,7 @@
 
   /* If there's a structure value address to be passed,
      either pass it in the special place, or pass it as an extra argument.  */
-  if (mem_value && struct_value_rtx == 0 && ! pcc_struct_value)
+  if (mem_value && struct_value == 0 && ! pcc_struct_value)
     {
       rtx addr = XEXP (mem_value, 0);
       nargs++;
@@ -4010,9 +4031,25 @@
 				     argvec[argnum].locate.offset.constant);
 		  rtx stack_area
 		    = gen_rtx_MEM (save_mode, memory_address (save_mode, adr));
-		  argvec[argnum].save_area = gen_reg_rtx (save_mode);
 
-		  emit_move_insn (argvec[argnum].save_area, stack_area);
+		  if (save_mode == BLKmode)
+		    {
+		      argvec[argnum].save_area
+			= assign_stack_temp (BLKmode,
+				             argvec[argnum].locate.size.constant,
+					     0);
+
+		      emit_block_move (validize_mem (argvec[argnum].save_area),
+			  	       stack_area,
+				       GEN_INT (argvec[argnum].locate.size.constant),
+				       BLOCK_OP_CALL_PARM);
+		    }
+		  else
+		    {
+		      argvec[argnum].save_area = gen_reg_rtx (save_mode);
+
+		      emit_move_insn (argvec[argnum].save_area, stack_area);
+		    }
 		}
 	    }
 
@@ -4075,14 +4112,14 @@
     }
 
   /* Pass the function the address in which to return a structure value.  */
-  if (mem_value != 0 && struct_value_rtx != 0 && ! pcc_struct_value)
+  if (mem_value != 0 && struct_value != 0 && ! pcc_struct_value)
     {
-      emit_move_insn (struct_value_rtx,
+      emit_move_insn (struct_value,
 		      force_reg (Pmode,
 				 force_operand (XEXP (mem_value, 0),
 						NULL_RTX)));
-      if (GET_CODE (struct_value_rtx) == REG)
-	use_reg (&call_fusage, struct_value_rtx);
+      if (GET_CODE (struct_value) == REG)
+	use_reg (&call_fusage, struct_value);
     }
 
   /* Don't allow popping to be deferred, since then
@@ -4231,7 +4268,13 @@
 	    rtx stack_area = gen_rtx_MEM (save_mode,
 					  memory_address (save_mode, adr));
 
-	    emit_move_insn (stack_area, argvec[count].save_area);
+	    if (save_mode == BLKmode)
+	      emit_block_move (stack_area,
+		  	       validize_mem (argvec[count].save_area),
+			       GEN_INT (argvec[count].locate.size.constant),
+			       BLOCK_OP_CALL_PARM);
+	    else
+	      emit_move_insn (stack_area, argvec[count].save_area);
 	  }
 
       highest_outgoing_arg_in_use = initial_highest_arg_in_use;


Index: gcc-3.4/gcc/cgraphunit.c
diff -u gcc-3.4/gcc/cgraphunit.c:1.1.1.3 gcc-3.4/gcc/cgraphunit.c:1.2
--- gcc-3.4/gcc/cgraphunit.c:1.1.1.3	Thu Jan 22 09:46:30 2004
+++ gcc-3.4/gcc/cgraphunit.c	Thu Feb  5 10:05:44 2004
@@ -39,6 +39,8 @@
 #include "fibheap.h"
 #include "c-common.h"
 
+#include "llvm-out.h"
+
 #define INSNS_PER_CALL 10
 
 static void cgraph_expand_all_functions (void);
@@ -71,6 +73,11 @@
 static bool
 decide_is_function_needed (struct cgraph_node *node, tree decl)
 {
+#if 0
+  if (EMIT_LLVM)
+    return true;
+#endif
+
   /* If we decided it was needed before, but at the time we didn't have
      the body of the function available, then it's still needed.  We have
      to go back and re-check its dependencies now.  */
@@ -110,6 +117,7 @@
   /* We want to emit COMDAT functions only when absolutely necessary.  */
   if (DECL_COMDAT (decl))
     return false;
+
   if (!DECL_INLINE (decl)
       || (!node->local.disregard_inline_limits
 	  /* When declared inline, defer even the uninlinable functions.
@@ -495,7 +503,14 @@
 
   /* Generate RTL for the body of DECL.  Nested functions are expanded
      via lang_expand_decl_stmt.  */
-  (*lang_hooks.callgraph.expand_function) (decl);
+  if (EMIT_LLVM)
+  {
+    (*lang_hooks.callgraph.llvm_expand_function) (decl);
+  }
+  else
+  {
+    (*lang_hooks.callgraph.expand_function) (decl);
+  }
 
   if (!flag_unit_at_a_time)
     {


Index: gcc-3.4/gcc/dwarf2out.c
diff -u gcc-3.4/gcc/dwarf2out.c:1.2 gcc-3.4/gcc/dwarf2out.c:1.3
--- gcc-3.4/gcc/dwarf2out.c:1.2	Fri Jan  9 10:54:24 2004
+++ gcc-3.4/gcc/dwarf2out.c	Thu Feb  5 10:05:44 2004
@@ -3812,14 +3812,10 @@
 #endif
 
 /* Section flags for .debug_str section.  */
-#ifdef HAVE_GAS_SHF_MERGE
 #define DEBUG_STR_SECTION_FLAGS \
-  (flag_merge_constants						\
+  (HAVE_GAS_SHF_MERGE && flag_merge_constants			\
    ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1	\
    : SECTION_DEBUG)
-#else
-#define DEBUG_STR_SECTION_FLAGS	SECTION_DEBUG
-#endif
 
 /* Labels we insert at beginning sections we can reference instead of
    the section names themselves.  */
@@ -10990,15 +10986,19 @@
 static void
 gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
 {
+  tree decl = block_ultimate_origin (stmt);
+
+  /* Emit info for the abstract instance first, if we haven't yet.  We
+     must emit this even if the block is abstract, otherwise when we
+     emit the block below (or elsewhere), we may end up trying to emit
+     a die whose origin die hasn't been emitted, and crashing.  */
+  dwarf2out_abstract_function (decl);
+
   if (! BLOCK_ABSTRACT (stmt))
     {
       dw_die_ref subr_die
 	= new_die (DW_TAG_inlined_subroutine, context_die, stmt);
-      tree decl = block_ultimate_origin (stmt);
       char label[MAX_ARTIFICIAL_LABEL_BYTES];
-
-      /* Emit info for the abstract instance first, if we haven't yet.  */
-      dwarf2out_abstract_function (decl);
 
       add_abstract_origin_attribute (subr_die, decl);
       ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,


Index: gcc-3.4/gcc/emit-rtl.c
diff -u gcc-3.4/gcc/emit-rtl.c:1.2 gcc-3.4/gcc/emit-rtl.c:1.3
--- gcc-3.4/gcc/emit-rtl.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/emit-rtl.c	Thu Feb  5 10:05:44 2004
@@ -111,9 +111,14 @@
 REAL_VALUE_TYPE dconst0;
 REAL_VALUE_TYPE dconst1;
 REAL_VALUE_TYPE dconst2;
+REAL_VALUE_TYPE dconst3;
+REAL_VALUE_TYPE dconst10;
 REAL_VALUE_TYPE dconstm1;
 REAL_VALUE_TYPE dconstm2;
 REAL_VALUE_TYPE dconsthalf;
+REAL_VALUE_TYPE dconstthird;
+REAL_VALUE_TYPE dconstpi;
+REAL_VALUE_TYPE dconste;
 
 /* All references to the following fixed hard registers go through
    these unique rtl objects.  On machines where the frame-pointer and
@@ -133,8 +138,6 @@
 
    In an inline procedure, the stack and frame pointer rtxs may not be
    used for anything else.  */
-rtx struct_value_rtx;		/* (REG:Pmode STRUCT_VALUE_REGNUM) */
-rtx struct_value_incoming_rtx;	/* (REG:Pmode STRUCT_VALUE_INCOMING_REGNUM) */
 rtx static_chain_rtx;		/* (REG:Pmode STATIC_CHAIN_REGNUM) */
 rtx static_chain_incoming_rtx;	/* (REG:Pmode STATIC_CHAIN_INCOMING_REGNUM) */
 rtx pic_offset_table_rtx;	/* (REG:Pmode PIC_OFFSET_TABLE_REGNUM) */
@@ -5419,13 +5422,24 @@
   REAL_VALUE_FROM_INT (dconst0,   0,  0, double_mode);
   REAL_VALUE_FROM_INT (dconst1,   1,  0, double_mode);
   REAL_VALUE_FROM_INT (dconst2,   2,  0, double_mode);
+  REAL_VALUE_FROM_INT (dconst3,   3,  0, double_mode);
+  REAL_VALUE_FROM_INT (dconst10, 10,  0, double_mode);
   REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
   REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);
 
   dconsthalf = dconst1;
   dconsthalf.exp--;
 
-  for (i = 0; i <= 2; i++)
+  real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3);
+
+  /* Initialize mathematical constants for constant folding builtins.
+     These constants need to be given to at least 160 bits precision.  */
+  real_from_string (&dconstpi,
+    "3.1415926535897932384626433832795028841971693993751058209749445923078");
+  real_from_string (&dconste,
+    "2.7182818284590452353602874713526624977572470936999595749669676277241");
+
+  for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)
     {
       REAL_VALUE_TYPE *r =
 	(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
@@ -5468,23 +5482,6 @@
 #ifdef RETURN_ADDRESS_POINTER_REGNUM
   return_address_pointer_rtx
     = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
-#endif
-
-#ifdef STRUCT_VALUE
-  struct_value_rtx = STRUCT_VALUE;
-#else
-  struct_value_rtx = gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM);
-#endif
-
-#ifdef STRUCT_VALUE_INCOMING
-  struct_value_incoming_rtx = STRUCT_VALUE_INCOMING;
-#else
-#ifdef STRUCT_VALUE_INCOMING_REGNUM
-  struct_value_incoming_rtx
-    = gen_rtx_REG (Pmode, STRUCT_VALUE_INCOMING_REGNUM);
-#else
-  struct_value_incoming_rtx = struct_value_rtx;
-#endif
 #endif
 
 #ifdef STATIC_CHAIN_REGNUM


Index: gcc-3.4/gcc/expr.c
diff -u gcc-3.4/gcc/expr.c:1.2 gcc-3.4/gcc/expr.c:1.3
--- gcc-3.4/gcc/expr.c:1.2	Thu Jan  8 17:03:26 2004
+++ gcc-3.4/gcc/expr.c	Thu Feb  5 10:05:44 2004
@@ -165,6 +165,8 @@
 
 static int is_aligning_offset (tree, tree);
 static rtx expand_increment (tree, int, int);
+static void expand_operands (tree, tree, rtx, rtx*, rtx*,
+			     enum expand_modifier);
 static rtx do_store_flag (tree, rtx, enum machine_mode, int);
 #ifdef PUSH_ROUNDING
 static void emit_single_push_insn (enum machine_mode, rtx, tree);
@@ -234,6 +236,9 @@
 /* This array records the insn_code of insns to perform block clears.  */
 enum insn_code clrstr_optab[NUM_MACHINE_MODES];
 
+/* Stack of EXPR_WITH_FILE_LOCATION nested expressions.  */
+struct file_stack *expr_wfl_stack;
+
 /* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow.  */
 
 #ifndef SLOW_UNALIGNED_ACCESS
@@ -339,15 +344,7 @@
 void
 init_expr (void)
 {
-  cfun->expr = ggc_alloc (sizeof (struct expr_status));
-
-  pending_chain = 0;
-  pending_stack_adjust = 0;
-  stack_pointer_delta = 0;
-  inhibit_defer_pop = 0;
-  saveregs_value = 0;
-  apply_args_value = 0;
-  forced_labels = 0;
+  cfun->expr = ggc_alloc_cleared (sizeof (struct expr_status));
 }
 
 /* Small sanity check that the queue is empty at the end of a function.  */
@@ -1961,10 +1958,8 @@
   dst_addr = copy_to_mode_reg (Pmode, XEXP (dst, 0));
   src_addr = copy_to_mode_reg (Pmode, XEXP (src, 0));
 
-#ifdef POINTERS_EXTEND_UNSIGNED
   dst_addr = convert_memory_address (ptr_mode, dst_addr);
   src_addr = convert_memory_address (ptr_mode, src_addr);
-#endif
 
   dst_tree = make_tree (ptr_type_node, dst_addr);
   src_tree = make_tree (ptr_type_node, src_addr);
@@ -4282,7 +4277,7 @@
      since it might be a promoted variable where the zero- or sign- extension
      needs to be done.  Handling this in the normal way is safe because no
      computation is done before the call.  */
-  if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
+  if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
       && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
       && ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
 	    && GET_CODE (DECL_RTL (to)) == REG))
@@ -4303,11 +4298,8 @@
 	emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
       else
 	{
-#ifdef POINTERS_EXTEND_UNSIGNED
-	  if (POINTER_TYPE_P (TREE_TYPE (to))
-	      && GET_MODE (to_rtx) != GET_MODE (value))
+	  if (POINTER_TYPE_P (TREE_TYPE (to)))
 	    value = convert_memory_address (GET_MODE (to_rtx), value);
-#endif
 	  emit_move_insn (to_rtx, value);
 	}
       preserve_temp_slots (to_rtx);
@@ -6532,6 +6524,30 @@
 
   return 0;
 }
+
+/* Subroutine of expand_expr.  Expand the two operands of a binary
+   expression EXP0 and EXP1 placing the results in OP0 and OP1.
+   The value may be stored in TARGET if TARGET is nonzero.  The
+   MODIFIER argument is as documented by expand_expr.  */
+
+static void
+expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
+		 enum expand_modifier modifier)
+{
+  if (! safe_from_p (target, exp1, 1))
+    target = 0;
+  if (operand_equal_p (exp0, exp1, 0))
+    {
+      *op0 = expand_expr (exp0, target, VOIDmode, modifier);
+      *op1 = copy_rtx (*op0);
+    }
+  else
+    {
+      *op0 = expand_expr (exp0, target, VOIDmode, modifier);
+      *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
+    }
+}
+
 
 /* expand_expr: generate code for computing expression EXP.
    An rtx for the computed value is returned.  The value is never null.
@@ -6576,7 +6592,8 @@
    emit_block_move will be flagged with BLOCK_OP_CALL_PARM.  */
 
 rtx
-expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier modifier)
+expand_expr (tree exp, rtx target, enum machine_mode tmode,
+	     enum expand_modifier modifier)
 {
   rtx op0, op1, temp;
   tree type = TREE_TYPE (exp);
@@ -6715,7 +6732,7 @@
   if (! cse_not_expected && mode != BLKmode && target
       && (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER)
       && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
-      && ! (code == CALL_EXPR && aggregate_value_p (exp)))
+      && ! (code == CALL_EXPR && aggregate_value_p (exp, exp)))
     target = 0;
 
   switch (code)
@@ -6743,8 +6760,7 @@
     case PARM_DECL:
       if (!DECL_RTL_SET_P (exp))
 	{
-	  error ("%Hprior parameter's size depends on '%D'",
-                 &DECL_SOURCE_LOCATION (exp), exp);
+	  error ("%Jprior parameter's size depends on '%D'", exp, exp);
 	  return CONST0_RTX (mode);
 	}
 
@@ -6943,14 +6959,23 @@
     case EXPR_WITH_FILE_LOCATION:
       {
 	rtx to_return;
-	location_t saved_loc = input_location;
+	struct file_stack fs;
+
+	fs.location = input_location;
+	fs.next = expr_wfl_stack;
 	input_filename = EXPR_WFL_FILENAME (exp);
 	input_line = EXPR_WFL_LINENO (exp);
+	expr_wfl_stack = &fs;
 	if (EXPR_WFL_EMIT_LINE_NOTE (exp))
 	  emit_line_note (input_location);
 	/* Possibly avoid switching back and forth here.  */
-	to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier);
-	input_location = saved_loc;
+	to_return = expand_expr (EXPR_WFL_NODE (exp),
+				 (ignore ? const0_rtx : target),
+				 tmode, modifier);
+	if (expr_wfl_stack != &fs)
+	  abort ();
+	input_location = fs.location;
+	expr_wfl_stack = fs.next;
 	return to_return;
       }
 
@@ -8121,11 +8146,11 @@
 		{
 		  op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
 				     VOIDmode, modifier);
-		  /* Don't go to both_summands if modifier
-		     says it's not right to return a PLUS.  */
-		  if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-		    goto binop2;
-		  goto both_summands;
+		  /* Return a PLUS if modifier says it's OK.  */
+		  if (modifier == EXPAND_SUM
+		      || modifier == EXPAND_INITIALIZER)
+		    return simplify_gen_binary (PLUS, mode, op0, op1);
+		  goto binop2;
 		}
 	      /* Use immed_double_const to ensure that the constant is
 		 truncated according to the mode of OP1, then sign extended
@@ -8152,12 +8177,8 @@
       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
 	  || mode != ptr_mode)
 	{
-	  op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-	  if (! operand_equal_p (TREE_OPERAND (exp, 0),
-				 TREE_OPERAND (exp, 1), 0))
-	    op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-	  else
-	    op1 = op0;
+	  expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+			   subtarget, &op0, &op1, 0);
 	  if (op0 == const0_rtx)
 	    return op1;
 	  if (op1 == const0_rtx)
@@ -8165,62 +8186,9 @@
 	  goto binop2;
 	}
 
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
-      if (! operand_equal_p (TREE_OPERAND (exp, 0),
-			     TREE_OPERAND (exp, 1), 0))
-	op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
-			   VOIDmode, modifier);
-      else
-	op1 = op0;
-
-      /* We come here from MINUS_EXPR when the second operand is a
-         constant.  */
-    both_summands:
-      /* Make sure any term that's a sum with a constant comes last.  */
-      if (GET_CODE (op0) == PLUS
-	  && CONSTANT_P (XEXP (op0, 1)))
-	{
-	  temp = op0;
-	  op0 = op1;
-	  op1 = temp;
-	}
-      /* If adding to a sum including a constant,
-	 associate it to put the constant outside.  */
-      if (GET_CODE (op1) == PLUS
-	  && CONSTANT_P (XEXP (op1, 1)))
-	{
-	  rtx constant_term = const0_rtx;
-
-	  temp = simplify_binary_operation (PLUS, mode, XEXP (op1, 0), op0);
-	  if (temp != 0)
-	    op0 = temp;
-	  /* Ensure that MULT comes first if there is one.  */
-	  else if (GET_CODE (op0) == MULT)
-	    op0 = gen_rtx_PLUS (mode, op0, XEXP (op1, 0));
-	  else
-	    op0 = gen_rtx_PLUS (mode, XEXP (op1, 0), op0);
-
-	  /* Let's also eliminate constants from op0 if possible.  */
-	  op0 = eliminate_constant_term (op0, &constant_term);
-
-	  /* CONSTANT_TERM and XEXP (op1, 1) are known to be constant, so
-	     their sum should be a constant.  Form it into OP1, since the
-	     result we want will then be OP0 + OP1.  */
-
-	  temp = simplify_binary_operation (PLUS, mode, constant_term,
-					    XEXP (op1, 1));
-	  if (temp != 0)
-	    op1 = temp;
-	  else
-	    op1 = gen_rtx_PLUS (mode, constant_term, XEXP (op1, 1));
-	}
-
-      /* Put a constant term last and put a multiplication first.  */
-      if (CONSTANT_P (op0) || GET_CODE (op1) == MULT)
-	temp = op1, op1 = op0, op0 = temp;
-
-      temp = simplify_binary_operation (PLUS, mode, op0, op1);
-      return temp ? temp : gen_rtx_PLUS (mode, op0, op1);
+      expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		       subtarget, &op0, &op1, modifier);
+      return simplify_gen_binary (PLUS, mode, op0, op1);
 
     case MINUS_EXPR:
       /* For initializers, we are allowed to return a MINUS of two
@@ -8232,10 +8200,8 @@
 	  && really_constant_p (TREE_OPERAND (exp, 0))
 	  && really_constant_p (TREE_OPERAND (exp, 1)))
 	{
-	  rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode,
-				 modifier);
-	  rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode,
-				 modifier);
+	  expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+			   NULL_RTX, &op0, &op1, modifier);
 
 	  /* If the last operand is a CONST_INT, use plus_constant of
 	     the negated constant.  Else make the MINUS.  */
@@ -8257,17 +8223,14 @@
 	  || 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, modifier);
-      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
+      expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		       subtarget, &op0, &op1, modifier);
 
       /* Convert A - const to A + (-const).  */
       if (GET_CODE (op1) == CONST_INT)
 	{
 	  op1 = negate_rtx (mode, op1);
-	  goto both_summands;
+	  return simplify_gen_binary (PLUS, mode, op0, op1);
 	}
 
       goto binop2;
@@ -8356,14 +8319,14 @@
 	    {
 	      if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
 		{
-		  op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-				     NULL_RTX, VOIDmode, 0);
 		  if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
-		    op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
-				       VOIDmode, 0);
+		    expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
+				     TREE_OPERAND (exp, 1),
+				     NULL_RTX, &op0, &op1, 0);
 		  else
-		    op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
-				       NULL_RTX, VOIDmode, 0);
+		    expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
+				     TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
+				     NULL_RTX, &op0, &op1, 0);
 		  goto binop2;
 		}
 	      else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
@@ -8392,12 +8355,8 @@
 		}
 	    }
 	}
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      if (! operand_equal_p (TREE_OPERAND (exp, 0),
-			     TREE_OPERAND (exp, 1), 0))
-	op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-      else
-	op1 = op0;
+      expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		       subtarget, &op0, &op1, 0);
       return expand_mult (mode, op0, op1, target, unsignedp);
 
     case TRUNC_DIV_EXPR:
@@ -8405,15 +8364,13 @@
     case CEIL_DIV_EXPR:
     case ROUND_DIV_EXPR:
     case EXACT_DIV_EXPR:
-      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-	subtarget = 0;
       if (modifier == EXPAND_STACK_PARM)
 	target = 0;
       /* Possible optimization: compute the dividend with EXPAND_SUM
 	 then if the divisor is constant can optimize the case
 	 where some terms of the dividend have coeffs divisible by it.  */
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+      expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		       subtarget, &op0, &op1, 0);
       return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
 
     case RDIV_EXPR:
@@ -8435,12 +8392,10 @@
     case FLOOR_MOD_EXPR:
     case CEIL_MOD_EXPR:
     case ROUND_MOD_EXPR:
-      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-	subtarget = 0;
       if (modifier == EXPAND_STACK_PARM)
 	target = 0;
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+      expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		       subtarget, &op0, &op1, 0);
       return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
 
     case FIX_ROUND_EXPR:
@@ -8509,8 +8464,8 @@
 	  || (GET_CODE (target) == REG
 	      && REGNO (target) < FIRST_PSEUDO_REGISTER))
 	target = gen_reg_rtx (mode);
-      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-      op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
+      expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		       target, &op0, &op1, 0);
 
       /* First try to do it with a special MIN or MAX instruction.
 	 If that does not win, use a conditional jump to select the proper
@@ -8567,43 +8522,6 @@
 	abort ();
       return temp;
 
-    case FFS_EXPR:
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      if (modifier == EXPAND_STACK_PARM)
-	target = 0;
-      temp = expand_unop (mode, ffs_optab, op0, target, 1);
-      if (temp == 0)
-	abort ();
-      return temp;
-
-    case CLZ_EXPR:
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      temp = expand_unop (mode, clz_optab, op0, target, 1);
-      if (temp == 0)
-	abort ();
-      return temp;
-
-    case CTZ_EXPR:
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      temp = expand_unop (mode, ctz_optab, op0, target, 1);
-      if (temp == 0)
-	abort ();
-      return temp;
-
-    case POPCOUNT_EXPR:
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      temp = expand_unop (mode, popcount_optab, op0, target, 1);
-      if (temp == 0)
-	abort ();
-      return temp;
-
-    case PARITY_EXPR:
-      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-      temp = expand_unop (mode, parity_optab, op0, target, 1);
-      if (temp == 0)
-	abort ();
-      return temp;
-
       /* ??? Can optimize bitwise operations with one arg constant.
 	 Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
 	 and (a bitwise1 b) bitwise2 b (etc)
@@ -9307,11 +9225,8 @@
 	  if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
 	    {
 	      op0 = XEXP (op0, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
-	      if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
-		  && mode == ptr_mode)
+	      if (GET_MODE (op0) == Pmode && mode == ptr_mode)
 		op0 = convert_memory_address (ptr_mode, op0);
-#endif
 	      return op0;
 	    }
 
@@ -9372,11 +9287,8 @@
 	  && ! REG_USERVAR_P (op0))
 	mark_reg_pointer (op0, TYPE_ALIGN (TREE_TYPE (type)));
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-      if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
-	  && mode == ptr_mode)
+      if (GET_MODE (op0) == Pmode && mode == ptr_mode)
 	op0 = convert_memory_address (ptr_mode, op0);
-#endif
 
       return op0;
 
@@ -9565,10 +9477,8 @@
   /* Here to do an ordinary binary operator, generating an instruction
      from the optab already placed in `this_optab'.  */
  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);
+  expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+		   subtarget, &op0, &op1, 0);
  binop2:
   if (modifier == EXPAND_STACK_PARM)
     target = 0;
@@ -10067,8 +9977,7 @@
       || ! safe_from_p (subtarget, arg1, 1))
     subtarget = 0;
 
-  op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
-  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+  expand_operands (arg0, arg1, subtarget, &op0, &op1, 0);
 
   if (target == 0)
     target = gen_reg_rtx (mode);


Index: gcc-3.4/gcc/fold-const.c
diff -u gcc-3.4/gcc/fold-const.c:1.2 gcc-3.4/gcc/fold-const.c:1.3
--- gcc-3.4/gcc/fold-const.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/fold-const.c	Thu Feb  5 10:05:44 2004
@@ -110,6 +110,7 @@
 static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
 				 tree, tree, tree);
 static tree fold_inf_compare (enum tree_code, tree, tree, tree);
+static bool tree_swap_operands_p (tree, tree);
 
 /* The following constants represent a bit based encoding of GCC's
    comparison operators.  This encoding simplifies transformations
@@ -1110,10 +1111,6 @@
       low = int1l & int2l, hi = int1h & int2h;
       break;
 
-    case BIT_ANDTC_EXPR:
-      low = int1l & ~int2l, hi = int1h & ~int2h;
-      break;
-
     case RSHIFT_EXPR:
       int2l = -int2l;
     case LSHIFT_EXPR:
@@ -1828,13 +1825,27 @@
 	  || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
 }
 
-/* Return nonzero if two operands are necessarily equal.
+/* Return nonzero if two operands (typically of the same tree node)
+   are necessarily equal.  If either argument has side-effects this
+   function returns zero.
+
    If ONLY_CONST is nonzero, only return nonzero for constants.
    This function tests whether the operands are indistinguishable;
    it does not test whether they are equal using C's == operation.
    The distinction is important for IEEE floating point, because
    (1) -0.0 and 0.0 are distinguishable, but -0.0==0.0, and
-   (2) two NaNs may be indistinguishable, but NaN!=NaN.  */
+   (2) two NaNs may be indistinguishable, but NaN!=NaN.
+
+   If ONLY_CONST is zero, a VAR_DECL is considered equal to itself
+   even though it may hold multiple values during a function.
+   This is because a GCC tree node guarantees that nothing else is
+   executed between the evaluation of its "operands" (which may often
+   be evaluated in arbitrary order).  Hence if the operands themselves
+   don't side-effect, the VAR_DECLs, PARM_DECLs etc... must hold the
+   same value in each operand/subexpression.  Hence a zero value for
+   ONLY_CONST assumes isochronic (or instantaneous) tree equivalence.
+   If comparing arbitrary expression trees, such as from different
+   statements, ONLY_CONST must usually be nonzero.  */
 
 int
 operand_equal_p (tree arg0, tree arg1, int only_const)
@@ -4971,6 +4982,49 @@
   return NULL_TREE;
 }
 
+/* Test whether it is preferable two swap two operands, ARG0 and
+   ARG1, for example because ARG0 is an integer constant and ARG1
+   isn't.  */
+
+static bool
+tree_swap_operands_p (tree arg0, tree arg1)
+{
+  STRIP_SIGN_NOPS (arg0);
+  STRIP_SIGN_NOPS (arg1);
+
+  if (TREE_CODE (arg1) == INTEGER_CST)
+    return 0;
+  if (TREE_CODE (arg0) == INTEGER_CST)
+    return 1;
+
+  if (TREE_CODE (arg1) == REAL_CST)
+    return 0;
+  if (TREE_CODE (arg0) == REAL_CST)
+    return 1;
+
+  if (TREE_CODE (arg1) == COMPLEX_CST)
+    return 0;
+  if (TREE_CODE (arg0) == COMPLEX_CST)
+    return 1;
+
+  if (TREE_CONSTANT (arg1))
+    return 0;
+  if (TREE_CONSTANT (arg0))
+    return 1;
+
+  if (DECL_P (arg1))
+    return 0;
+  if (DECL_P (arg0))
+    return 1;
+
+  if (TREE_CODE (arg1) == SAVE_EXPR)
+    return 0;
+  if (TREE_CODE (arg0) == SAVE_EXPR)
+    return 1;
+
+  return 0;
+}
+
 /* Perform constant folding and related simplification of EXPR.
    The related simplifications include x*1 => x, x*0 => 0, etc.,
    and application of the associative law.
@@ -5030,8 +5084,7 @@
 	subop = arg0;
 
       if (subop != 0 && TREE_CODE (subop) != INTEGER_CST
-	  && TREE_CODE (subop) != REAL_CST
-	  )
+	  && TREE_CODE (subop) != REAL_CST)
 	/* Note that TREE_CONSTANT isn't enough:
 	   static var addresses are constant but we can't
 	   do arithmetic on them.  */
@@ -5083,16 +5136,8 @@
   if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
        || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
        || code == BIT_AND_EXPR)
-      && ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) != INTEGER_CST)
-	  || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) != REAL_CST)))
-    {
-      tem = arg0; arg0 = arg1; arg1 = tem;
-
-      if (t == orig_t)
-	t = copy_node (t);
-      TREE_OPERAND (t, 0) = arg0;
-      TREE_OPERAND (t, 1) = arg1;
-    }
+      && tree_swap_operands_p (arg0, arg1))
+    return fold (build (code, type, arg1, arg0));
 
   /* Now WINS is set as described above,
      ARG0 is the first operand of EXPR,
@@ -6113,10 +6158,20 @@
 		  return build_function_call_expr (sqrtfn, arglist);
 		}
 
-	      /* Optimize exp(x)*exp(y) as exp(x+y).  */
-	      if ((fcode0 == BUILT_IN_EXP && fcode1 == BUILT_IN_EXP)
-		  || (fcode0 == BUILT_IN_EXPF && fcode1 == BUILT_IN_EXPF)
-		  || (fcode0 == BUILT_IN_EXPL && fcode1 == BUILT_IN_EXPL))
+	      /* Optimize expN(x)*expN(y) as expN(x+y).  */
+	      if (fcode0 == fcode1
+		  && (fcode0 == BUILT_IN_EXP
+		      || fcode0 == BUILT_IN_EXPF
+		      || fcode0 == BUILT_IN_EXPL
+		      || fcode0 == BUILT_IN_EXP2
+		      || fcode0 == BUILT_IN_EXP2F
+		      || fcode0 == BUILT_IN_EXP2L
+		      || fcode0 == BUILT_IN_EXP10
+		      || fcode0 == BUILT_IN_EXP10F
+		      || fcode0 == BUILT_IN_EXP10L
+		      || fcode0 == BUILT_IN_POW10
+		      || fcode0 == BUILT_IN_POW10F
+		      || fcode0 == BUILT_IN_POW10L))
 		{
 		  tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
 		  tree arg = build (PLUS_EXPR, type,
@@ -6329,7 +6384,6 @@
       goto bit_rotate;
 
     case BIT_AND_EXPR:
-    bit_and:
       if (integer_all_onesp (arg1))
 	return non_lvalue (convert (type, arg0));
       if (integer_zerop (arg1))
@@ -6367,19 +6421,6 @@
 
       goto associate;
 
-    case BIT_ANDTC_EXPR:
-      if (integer_all_onesp (arg0))
-	return non_lvalue (convert (type, arg1));
-      if (integer_zerop (arg0))
-	return omit_one_operand (type, arg0, arg1);
-      if (TREE_CODE (arg1) == INTEGER_CST)
-	{
-	  arg1 = fold (build1 (BIT_NOT_EXPR, type, arg1));
-	  code = BIT_AND_EXPR;
-	  goto bit_and;
-	}
-      goto binary;
-
     case RDIV_EXPR:
       /* Don't touch a floating-point divide by zero unless the mode
 	 of the constant can represent infinity.  */
@@ -6462,10 +6503,19 @@
       if (flag_unsafe_math_optimizations)
 	{
 	  enum built_in_function fcode = builtin_mathfn_code (arg1);
-	  /* Optimize x/exp(y) into x*exp(-y).  */
+	  /* Optimize x/expN(y) into x*expN(-y).  */
 	  if (fcode == BUILT_IN_EXP
 	      || fcode == BUILT_IN_EXPF
-	      || fcode == BUILT_IN_EXPL)
+	      || fcode == BUILT_IN_EXPL
+	      || fcode == BUILT_IN_EXP2
+	      || fcode == BUILT_IN_EXP2F
+	      || fcode == BUILT_IN_EXP2L
+	      || fcode == BUILT_IN_EXP10
+	      || fcode == BUILT_IN_EXP10F
+	      || fcode == BUILT_IN_EXP10L
+	      || fcode == BUILT_IN_POW10
+	      || fcode == BUILT_IN_POW10F
+	      || fcode == BUILT_IN_POW10L)
 	    {
 	      tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
 	      tree arg = build1 (NEGATE_EXPR, type,
@@ -6643,18 +6693,10 @@
 	 RROTATE_EXPR by a new constant.  */
       if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
 	{
-	  if (t == orig_t)
-	    t = copy_node (t);
-	  TREE_SET_CODE (t, RROTATE_EXPR);
-	  code = RROTATE_EXPR;
-	  TREE_OPERAND (t, 1) = arg1
-	    = const_binop
-	      (MINUS_EXPR,
-	       convert (TREE_TYPE (arg1),
-			build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0)),
-	       arg1, 0);
-	  if (tree_int_cst_sgn (arg1) < 0)
-	    return t;
+	  tree tem = build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0);
+	  tem = convert (TREE_TYPE (arg1), tem);
+	  tem = const_binop (MINUS_EXPR, tem, arg1, 0);
+	  return fold (build (RROTATE_EXPR, type, arg0, tem));
 	}
 
       /* If we have a rotate of a bit operation with the rotate count and
@@ -6662,7 +6704,6 @@
 	 permute the two operations.  */
       if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
 	  && (TREE_CODE (arg0) == BIT_AND_EXPR
-	      || TREE_CODE (arg0) == BIT_ANDTC_EXPR
 	      || TREE_CODE (arg0) == BIT_IOR_EXPR
 	      || TREE_CODE (arg0) == BIT_XOR_EXPR)
 	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
@@ -6852,20 +6893,8 @@
     case LE_EXPR:
     case GE_EXPR:
       /* If one arg is a real or integer constant, put it last.  */
-      if ((TREE_CODE (arg0) == INTEGER_CST
-	   && TREE_CODE (arg1) != INTEGER_CST)
-	  || (TREE_CODE (arg0) == REAL_CST
-	      && TREE_CODE (arg0) != REAL_CST))
-	{
-	  if (t == orig_t)
-	    t = copy_node (t);
-	  TREE_OPERAND (t, 0) = arg1;
-	  TREE_OPERAND (t, 1) = arg0;
-	  arg0 = TREE_OPERAND (t, 0);
-	  arg1 = TREE_OPERAND (t, 1);
-	  code = swap_tree_comparison (code);
-	  TREE_SET_CODE (t, code);
-	}
+      if (tree_swap_operands_p (arg0, arg1))
+	return fold (build (swap_tree_comparison (code), type, arg1, arg0));
 
       if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
 	{
@@ -7122,16 +7151,12 @@
 	  switch (code)
 	    {
 	    case GE_EXPR:
-	      code = GT_EXPR;
 	      arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-	      t = build (code, type, TREE_OPERAND (t, 0), arg1);
-	      break;
+	      return fold (build (GT_EXPR, type, arg0, arg1));
 
 	    case LT_EXPR:
-	      code = LE_EXPR;
 	      arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-	      t = build (code, type, TREE_OPERAND (t, 0), arg1);
-	      break;
+	      return fold (build (LE_EXPR, type, arg0, arg1));
 
 	    default:
 	      break;
@@ -7174,24 +7199,17 @@
 					   convert (type, integer_zero_node),
 					   arg0);
 		case GE_EXPR:
-		  code = EQ_EXPR;
-		  if (t == orig_t)
-		    t = copy_node (t);
-		  TREE_SET_CODE (t, EQ_EXPR);
-		  break;
+		  return fold (build (EQ_EXPR, type, arg0, arg1));
+
 		case LE_EXPR:
 		  return omit_one_operand (type,
 					   convert (type, integer_one_node),
 					   arg0);
 		case LT_EXPR:
-		  code = NE_EXPR;
-		  if (t == orig_t)
-		    t = copy_node (t);
-		  TREE_SET_CODE (t, NE_EXPR);
-		  break;
+		  return fold (build (NE_EXPR, type, arg0, arg1));
 
 		/* The GE_EXPR and LT_EXPR cases above are not normally
-		   reached because of  previous transformations.  */
+		   reached because of previous transformations.  */
 
 		default:
 		  break;
@@ -7201,15 +7219,11 @@
 	      switch (code)
 		{
 		case GT_EXPR:
-		  code = EQ_EXPR;
 		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
-		  t = build (code, type, TREE_OPERAND (t, 0), arg1);
-		  break;
+		  return fold (build (EQ_EXPR, type, arg0, arg1));
 		case LE_EXPR:
-		  code = NE_EXPR;
 		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
-		  t = build (code, type, TREE_OPERAND (t, 0), arg1);
-		  break;
+		  return fold (build (NE_EXPR, type, arg0, arg1));
 		default:
 		  break;
 		}
@@ -7222,22 +7236,14 @@
 					   convert (type, integer_zero_node),
 					   arg0);
 		case LE_EXPR:
-		  code = EQ_EXPR;
-		  if (t == orig_t)
-		    t = copy_node (t);
-		  TREE_SET_CODE (t, EQ_EXPR);
-		  break;
+		  return fold (build (EQ_EXPR, type, arg0, arg1));
 
 		case GE_EXPR:
 		  return omit_one_operand (type,
 					   convert (type, integer_one_node),
 					   arg0);
 		case GT_EXPR:
-		  code = NE_EXPR;
-		  if (t == orig_t)
-		    t = copy_node (t);
-		  TREE_SET_CODE (t, NE_EXPR);
-		  break;
+		  return fold (build (NE_EXPR, type, arg0, arg1));
 
 		default:
 		  break;
@@ -7247,15 +7253,11 @@
 	      switch (code)
 		{
 		case GE_EXPR:
-		  code = NE_EXPR;
 		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-		  t = build (code, type, TREE_OPERAND (t, 0), arg1);
-		  break;
+		  return fold (build (NE_EXPR, type, arg0, arg1));
 		case LT_EXPR:
-		  code = EQ_EXPR;
 		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-		  t = build (code, type, TREE_OPERAND (t, 0), arg1);
-		  break;
+		  return fold (build (EQ_EXPR, type, arg0, arg1));
 		default:
 		  break;
 		}
@@ -7431,8 +7433,11 @@
 	  && TREE_CODE (arg1) == INTEGER_CST
 	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
 	{
-	  tree dandnotc = fold (build (BIT_ANDTC_EXPR, TREE_TYPE (arg0),
-				       arg1, TREE_OPERAND (arg0, 1)));
+	  tree dandnotc
+	    = fold (build (BIT_AND_EXPR, TREE_TYPE (arg0),
+			   arg1, build1 (BIT_NOT_EXPR,
+					 TREE_TYPE (TREE_OPERAND (arg0, 1)),
+					 TREE_OPERAND (arg0, 1))));
 	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
 	  if (integer_nonzerop (dandnotc))
 	    return omit_one_operand (type, rslt, arg0);
@@ -7445,8 +7450,10 @@
 	  && TREE_CODE (arg1) == INTEGER_CST
 	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
 	{
-	  tree candnotd = fold (build (BIT_ANDTC_EXPR, TREE_TYPE (arg0),
-				       TREE_OPERAND (arg0, 1), arg1));
+	  tree candnotd
+	    = fold (build (BIT_AND_EXPR, TREE_TYPE (arg0),
+			   TREE_OPERAND (arg0, 1),
+			   build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1)));
 	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
 	  if (integer_nonzerop (candnotd))
 	    return omit_one_operand (type, rslt, arg0);
@@ -7483,16 +7490,17 @@
 	  switch (code)
 	    {
 	    case EQ_EXPR:
+	      if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
+		  || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
+		return constant_boolean_node (1, type);
+	      break;
+
 	    case GE_EXPR:
 	    case LE_EXPR:
 	      if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
 		  || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
 		return constant_boolean_node (1, type);
-	      code = EQ_EXPR;
-	      if (t == orig_t)
-		t = copy_node (t);
-	      TREE_SET_CODE (t, code);
-	      break;
+	      return fold (build (EQ_EXPR, type, arg0, arg1));
 
 	    case NE_EXPR:
 	      /* For NE, we can only do this simplification if integer
@@ -7773,34 +7781,6 @@
       else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
 	return pedantic_omit_one_operand (type, arg1, arg0);
 
-      /* If the second operand is zero, invert the comparison and swap
-	 the second and third operands.  Likewise if the second operand
-	 is constant and the third is not or if the third operand is
-	 equivalent to the first operand of the comparison.  */
-
-      if (integer_zerop (arg1)
-	  || (TREE_CONSTANT (arg1) && ! TREE_CONSTANT (TREE_OPERAND (t, 2)))
-	  || (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
-	      && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
-						 TREE_OPERAND (t, 2),
-						 TREE_OPERAND (arg0, 1))))
-	{
-	  /* See if this can be inverted.  If it can't, possibly because
-	     it was a floating-point inequality comparison, don't do
-	     anything.  */
-	  tem = invert_truthvalue (arg0);
-
-	  if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
-	    {
-	      t = build (code, type, tem,
-			 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1));
-	      arg0 = tem;
-	      /* arg1 should be the first argument of the new T.  */
-	      arg1 = TREE_OPERAND (t, 1);
-	      STRIP_NOPS (arg1);
-	    }
-	}
-
       /* If we have A op B ? A : C, we may be able to convert this to a
 	 simpler expression, depending on the operation and the values
 	 of B and C.  Signed zeros prevent all of these transformations,
@@ -7976,9 +7956,8 @@
 	      case EQ_EXPR:
 		/* We can replace A with C1 in this case.  */
 		arg1 = convert (type, TREE_OPERAND (arg0, 1));
-		t = build (code, type, TREE_OPERAND (t, 0), arg1,
-			   TREE_OPERAND (t, 2));
-		break;
+		return fold (build (code, type, TREE_OPERAND (t, 0), arg1,
+				    TREE_OPERAND (t, 2)));
 
 	      case LT_EXPR:
 		/* If C1 is C2 + 1, this is min(A, C2).  */
@@ -8028,11 +8007,7 @@
 
       /* If the second operand is simpler than the third, swap them
 	 since that produces better jump optimization results.  */
-      if ((TREE_CONSTANT (arg1) || DECL_P (arg1)
-	   || TREE_CODE (arg1) == SAVE_EXPR)
-	  && ! (TREE_CONSTANT (TREE_OPERAND (t, 2))
-		|| DECL_P (TREE_OPERAND (t, 2))
-		|| TREE_CODE (TREE_OPERAND (t, 2)) == SAVE_EXPR))
+      if (tree_swap_operands_p (TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)))
 	{
 	  /* See if this can be inverted.  If it can't, possibly because
 	     it was a floating-point inequality comparison, don't do
@@ -8040,14 +8015,8 @@
 	  tem = invert_truthvalue (arg0);
 
 	  if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
-	    {
-	      t = build (code, type, tem,
-			 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1));
-	      arg0 = tem;
-	      /* arg1 should be the first argument of the new T.  */
-	      arg1 = TREE_OPERAND (t, 1);
-	      STRIP_NOPS (arg1);
-	    }
+	    return fold (build (code, type, tem,
+			 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
 	}
 
       /* Convert A ? 1 : 0 to simply A.  */
@@ -8538,18 +8507,8 @@
   switch (TREE_CODE (t))
     {
     case ABS_EXPR:
-    case FFS_EXPR:
-    case POPCOUNT_EXPR:
-    case PARITY_EXPR:
       return 1;
 
-    case CLZ_EXPR:
-    case CTZ_EXPR:
-      /* These are undefined at zero.  This is true even if
-	 C[LT]Z_DEFINED_VALUE_AT_ZERO is set, since what we're
-	 computing here is a user-visible property.  */
-      return 0;
-
     case INTEGER_CST:
       return tree_int_cst_sgn (t) >= 0;
 
@@ -8687,9 +8646,27 @@
 	    case BUILT_IN_EXP:
 	    case BUILT_IN_EXPF:
 	    case BUILT_IN_EXPL:
+	    case BUILT_IN_EXP2:
+	    case BUILT_IN_EXP2F:
+	    case BUILT_IN_EXP2L:
+	    case BUILT_IN_EXP10:
+	    case BUILT_IN_EXP10F:
+	    case BUILT_IN_EXP10L:
 	    case BUILT_IN_FABS:
 	    case BUILT_IN_FABSF:
 	    case BUILT_IN_FABSL:
+	    case BUILT_IN_FFS:
+	    case BUILT_IN_FFSL:
+	    case BUILT_IN_FFSLL:
+	    case BUILT_IN_PARITY:
+	    case BUILT_IN_PARITYL:
+	    case BUILT_IN_PARITYLL:
+	    case BUILT_IN_POPCOUNT:
+	    case BUILT_IN_POPCOUNTL:
+	    case BUILT_IN_POPCOUNTLL:
+	    case BUILT_IN_POW10:
+	    case BUILT_IN_POW10F:
+	    case BUILT_IN_POW10L:
 	    case BUILT_IN_SQRT:
 	    case BUILT_IN_SQRTF:
 	    case BUILT_IN_SQRTL:


Index: gcc-3.4/gcc/function.c
diff -u gcc-3.4/gcc/function.c:1.2 gcc-3.4/gcc/function.c:1.3
--- gcc-3.4/gcc/function.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/function.c	Thu Feb  5 10:05:44 2004
@@ -62,6 +62,8 @@
 #include "tm_p.h"
 #include "integrate.h"
 #include "langhooks.h"
+#include "target.h"
+
 #include "llvm-out.h"
 
 #ifndef TRAMPOLINE_ALIGNMENT
@@ -76,6 +78,8 @@
 #define STACK_ALIGNMENT_NEEDED 1
 #endif
 
+#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
+
 /* Some systems use __main in a way incompatible with its use in gcc, in these
    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
    give the same symbol without quotes for an alternative entry point.  You
@@ -285,7 +289,7 @@
 static int insns_for_mem_comp (const void *, const void *);
 static int insns_for_mem_walk (rtx *, void *);
 static void compute_insns_for_mem (rtx, rtx, htab_t);
-static void prepare_function_start (void);
+static void prepare_function_start (tree);
 static void do_clobber_return_reg (rtx, void *);
 static void do_use_return_reg (rtx, void *);
 static void instantiate_virtual_regs_lossage (rtx);
@@ -878,8 +882,7 @@
       if (decl && size == -1
 	  && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
 	{
-	  error ("%Hsize of variable '%D' is too large",
-                 &DECL_SOURCE_LOCATION (decl), decl);
+	  error ("%Jsize of variable '%D' is too large", decl, decl);
 	  size = 1;
 	}
 
@@ -4178,16 +4181,37 @@
    EXP may be a type node or an expression (whose type is tested).  */
 
 int
-aggregate_value_p (tree exp)
+aggregate_value_p (tree exp, tree fntype)
 {
   int i, regno, nregs;
   rtx reg;
 
   tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
 
+  if (fntype)
+    switch (TREE_CODE (fntype))
+      {
+      case CALL_EXPR:
+	fntype = get_callee_fndecl (fntype);
+	fntype = fntype ? TREE_TYPE (fntype) : 0;
+	break;
+      case FUNCTION_DECL:
+	fntype = TREE_TYPE (fntype);
+	break;
+      case FUNCTION_TYPE:
+      case METHOD_TYPE:
+        break;
+      case IDENTIFIER_NODE:
+	fntype = 0;
+	break;
+      default:
+	/* We don't expect other rtl types here.  */
+	abort();
+      }
+
   if (TREE_CODE (type) == VOID_TYPE)
     return 0;
-  if (RETURN_IN_MEMORY (type))
+  if (targetm.calls.return_in_memory (type, fntype))
     return 1;
   /* Types that are TREE_ADDRESSABLE must be constructed in memory,
      and thus can't be returned in registers.  */
@@ -4231,9 +4255,7 @@
   /* This is a dummy PARM_DECL that we used for the function result if
      the function returns a structure.  */
   tree function_result_decl = 0;
-#ifdef SETUP_INCOMING_VARARGS
   int varargs_setup = 0;
-#endif
   int reg_parm_stack_space = 0;
   rtx conversion_insns = 0;
 
@@ -4266,9 +4288,9 @@
   stack_args_size.var = 0;
 
   /* If struct value address is treated as the first argument, make it so.  */
-  if (aggregate_value_p (DECL_RESULT (fndecl))
+  if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
       && ! current_function_returns_pcc_struct
-      && struct_value_incoming_rtx == 0)
+      && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
     {
       tree type = build_pointer_type (TREE_TYPE (fntype));
 
@@ -4320,6 +4342,7 @@
       int last_named = 0, named_arg;
       int in_regs;
       int partial = 0;
+      int pretend_bytes = 0;
 
       /* Set LAST_NAMED if this is last named arg before last
 	 anonymous args.  */
@@ -4337,7 +4360,7 @@
       /* Set NAMED_ARG if this arg should be treated as a named arg.  For
 	 most machines, if this is a varargs/stdarg function, then we treat
 	 the last named arg as if it were anonymous too.  */
-      named_arg = STRICT_ARGUMENT_NAMING ? 1 : ! last_named;
+      named_arg = targetm.calls.strict_argument_naming (&args_so_far) ? 1 : ! last_named;
 
       if (TREE_TYPE (parm) == error_mark_node
 	  /* This can happen after weird syntax errors
@@ -4402,11 +4425,12 @@
 
       promoted_mode = passed_mode;
 
-#ifdef PROMOTE_FUNCTION_ARGS
-      /* Compute the mode in which the arg is actually extended to.  */
-      unsignedp = TREE_UNSIGNED (passed_type);
-      promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
-#endif
+      if (targetm.calls.promote_function_args (TREE_TYPE (fndecl)))
+	{
+	  /* Compute the mode in which the arg is actually extended to.  */
+	  unsignedp = TREE_UNSIGNED (passed_type);
+	  promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
+	}
 
       /* Let machine desc say which reg (if any) the parm arrives in.
 	 0 means it arrives on the stack.  */
@@ -4421,7 +4445,6 @@
       if (entry_parm == 0)
 	promoted_mode = passed_mode;
 
-#ifdef SETUP_INCOMING_VARARGS
       /* If this is the last named parameter, do any required setup for
 	 varargs or stdargs.  We need to know about the case of this being an
 	 addressable type, in which case we skip the registers it
@@ -4434,11 +4457,18 @@
 	 Also, indicate when RTL generation is to be suppressed.  */
       if (last_named && !varargs_setup)
 	{
-	  SETUP_INCOMING_VARARGS (args_so_far, promoted_mode, passed_type,
-				  current_function_pretend_args_size, 0);
+	  int varargs_pretend_bytes = 0;
+	  targetm.calls.setup_incoming_varargs (&args_so_far, promoted_mode,
+						passed_type,
+						&varargs_pretend_bytes, 0);
 	  varargs_setup = 1;
+
+	  /* If the back-end has requested extra stack space, record how
+	     much is needed.  Do not change pretend_args_size otherwise
+	     since it may be nonzero from an earlier partial argument.  */
+	  if (varargs_pretend_bytes > 0)
+	    current_function_pretend_args_size = varargs_pretend_bytes;
 	}
-#endif
 
       /* Determine parm's home in the stack,
 	 in case it arrives in the stack or we should pretend it did.
@@ -4458,7 +4488,8 @@
 #endif
       if (!in_regs && !named_arg)
 	{
-	  int pretend_named = PRETEND_OUTGOING_VARARGS_NAMED;
+	  int pretend_named =
+	    targetm.calls.pretend_outgoing_varargs_named (&args_so_far);
 	  if (pretend_named)
 	    {
 #ifdef FUNCTION_INCOMING_ARG
@@ -4480,8 +4511,43 @@
 
 #ifdef FUNCTION_ARG_PARTIAL_NREGS
       if (entry_parm)
-	partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
-					      passed_type, named_arg);
+	{
+	  partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
+						passed_type, named_arg);
+	  if (partial
+#ifndef MAYBE_REG_PARM_STACK_SPACE
+	      /* The caller might already have allocated stack space
+		 for the register parameters.  */
+	      && reg_parm_stack_space == 0
+#endif
+	      )
+	    {
+	      /* Part of this argument is passed in registers and part
+		 is passed on the stack.  Ask the prologue code to extend
+		 the stack part so that we can recreate the full value.
+
+		 PRETEND_BYTES is the size of the registers we need to store.
+		 CURRENT_FUNCTION_PRETEND_ARGS_SIZE is the amount of extra
+		 stack space that the prologue should allocate.
+
+		 Internally, gcc assumes that the argument pointer is
+		 aligned to STACK_BOUNDARY bits.  This is used both for
+		 alignment optimisations (see init_emit) and to locate
+		 arguments that are aligned to more than PARM_BOUNDARY
+		 bits.  We must preserve this invariant by rounding
+		 CURRENT_FUNCTION_PRETEND_ARGS_SIZE up to a stack
+		 boundary.  */
+	      pretend_bytes = partial * UNITS_PER_WORD;
+	      current_function_pretend_args_size
+		= CEIL_ROUND (pretend_bytes, STACK_BYTES);
+
+	      /* If PRETEND_BYTES != CURRENT_FUNCTION_PRETEND_ARGS_SIZE,
+		 insert the padding before the start of the first pretend
+		 argument.  */
+	      stack_args_size.constant
+		= (current_function_pretend_args_size - pretend_bytes);
+	    }
+	}
 #endif
 
       memset (&locate, 0, sizeof (locate));
@@ -4526,17 +4592,6 @@
 
       if (partial)
 	{
-#ifndef MAYBE_REG_PARM_STACK_SPACE
-	  /* When REG_PARM_STACK_SPACE is nonzero, stack space for
-	     split parameters was allocated by our caller, so we
-	     won't be pushing it in the prolog.  */
-	  if (reg_parm_stack_space == 0)
-#endif
-	  current_function_pretend_args_size
-	    = (((partial * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
-	       / (PARM_BOUNDARY / BITS_PER_UNIT)
-	       * (PARM_BOUNDARY / BITS_PER_UNIT));
-
 	  /* Handle calls that pass values in multiple non-contiguous
 	     locations.  The Irix 6 ABI has examples of this.  */
 	  if (GET_CODE (entry_parm) == PARALLEL)
@@ -4580,10 +4635,7 @@
 #endif
 	  )
 	{
-	  stack_args_size.constant += locate.size.constant;
-	  /* locate.size doesn't include the part in regs.  */
-	  if (partial)
-	    stack_args_size.constant += current_function_pretend_args_size;
+	  stack_args_size.constant += pretend_bytes + locate.size.constant;
 	  if (locate.size.var)
 	    ADD_PARM_SIZE (stack_args_size, locate.size.var);
 	}
@@ -5131,11 +5183,7 @@
       rtx addr = DECL_RTL (function_result_decl);
       rtx x;
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-      if (GET_MODE (addr) != Pmode)
-	addr = convert_memory_address (Pmode, addr);
-#endif
-
+      addr = convert_memory_address (Pmode, addr);
       x = gen_rtx_MEM (DECL_MODE (result), addr);
       set_mem_attributes (x, result, 1);
       SET_DECL_RTL (result, x);
@@ -5155,8 +5203,6 @@
 #endif
 #endif
 
-#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
-
   current_function_args_size
     = ((current_function_args_size + STACK_BYTES - 1)
        / STACK_BYTES) * STACK_BYTES;
@@ -5276,8 +5322,6 @@
    that REGNO is promoted from and whether the promotion was signed or
    unsigned.  */
 
-#ifdef PROMOTE_FUNCTION_ARGS
-
 rtx
 promoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp)
 {
@@ -5305,7 +5349,6 @@
   return 0;
 }
 
-#endif
 
 /* Compute the size and offset from the start of the stacked arguments for a
    parm passed in mode PASSED_MODE and with type TYPE.
@@ -5568,15 +5611,15 @@
 	     if we want to warn.  */
 	  && (DECL_INITIAL (decl) == NULL_TREE || lang_hooks.decl_uninit (decl))
 	  && regno_uninitialized (REGNO (DECL_RTL (decl))))
-	warning ("%H'%D' might be used uninitialized in this function",
-                 &DECL_SOURCE_LOCATION (decl), decl);
+	warning ("%J'%D' might be used uninitialized in this function",
+		 decl, decl);
       if (extra_warnings
 	  && TREE_CODE (decl) == VAR_DECL
 	  && DECL_RTL (decl) != 0
 	  && GET_CODE (DECL_RTL (decl)) == REG
 	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
-	warning ("%Hvariable '%D' might be clobbered by `longjmp' or `vfork'",
-                 &DECL_SOURCE_LOCATION (decl), decl);
+	warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
+		 decl, decl);
     }
   for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
     uninitialized_vars_warning (sub);
@@ -5594,8 +5637,8 @@
     if (DECL_RTL (decl) != 0
 	&& GET_CODE (DECL_RTL (decl)) == REG
 	&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
-      warning ("%Hargument '%D' might be clobbered by `longjmp' or `vfork'",
-               &DECL_SOURCE_LOCATION (decl), decl);
+      warning ("%Jargument '%D' might be clobbered by `longjmp' or `vfork'",
+	       decl, decl);
 }
 
 /* If this function call setjmp, put all vars into the stack
@@ -6247,105 +6290,77 @@
   return NULL_TREE;
 }
 
-/* Allocate a function structure and reset its contents to the defaults.  */
+/* Allocate a function structure for FNDECL and set its contents
+   to the defaults.  */
 
-static void
-prepare_function_start (void)
+void
+allocate_struct_function (tree fndecl)
 {
-  cfun = ggc_alloc_cleared (sizeof (struct function));
-
-  init_stmt_for_function ();
-  init_eh_for_function ();
+  tree result;
 
-  cse_not_expected = ! optimize;
+  cfun = ggc_alloc_cleared (sizeof (struct function));
 
-  /* Caller save not needed yet.  */
-  caller_save_needed = 0;
+  max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
 
-  /* No stack slots have been made yet.  */
-  stack_slot_list = 0;
+  cfun->stack_alignment_needed = STACK_BOUNDARY;
+  cfun->preferred_stack_boundary = STACK_BOUNDARY;
 
-  current_function_has_nonlocal_label = 0;
-  current_function_has_nonlocal_goto = 0;
+  current_function_funcdef_no = funcdef_no++;
 
-  /* There is no stack slot for handling nonlocal gotos.  */
-  nonlocal_goto_handler_slots = 0;
-  nonlocal_goto_stack_level = 0;
+  cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
 
-  /* No labels have been declared for nonlocal use.  */
-  nonlocal_labels = 0;
-  nonlocal_goto_handler_labels = 0;
+  init_stmt_for_function ();
+  init_eh_for_function ();
+  init_emit ();
+  init_expr ();
+  init_varasm_status (cfun);
 
-  /* No function calls so far in this function.  */
-  function_call_count = 0;
+  (*lang_hooks.function.init) (cfun);
+  if (init_machine_status)
+    cfun->machine = (*init_machine_status) ();
 
-  /* No parm regs have been allocated.
-     (This is important for output_inline_function.)  */
-  max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
+  if (fndecl == NULL)
+    return;
 
-  /* Initialize the RTL mechanism.  */
-  if (!EMIT_LLVM)
-    init_emit ();
+  DECL_SAVED_INSNS (fndecl) = cfun;
+  cfun->decl = fndecl;
 
-  /* Initialize the queue of pending postincrement and postdecrements,
-     and some other info in expr.c.  */
-  init_expr ();
+  current_function_name = (*lang_hooks.decl_printable_name) (fndecl, 2);
 
-  /* We haven't done register allocation yet.  */
-  reg_renumber = 0;
-
-  if (!EMIT_LLVM)
-    init_varasm_status (cfun);
-
-  /* Clear out data used for inlining.  */
-  cfun->inlinable = 0;
-  cfun->original_decl_initial = 0;
-  cfun->original_arg_vector = 0;
+  result = DECL_RESULT (fndecl);
+  if (aggregate_value_p (result, fndecl))
+    {
+#ifdef PCC_STATIC_STRUCT_RETURN
+      current_function_returns_pcc_struct = 1;
+#endif
+      current_function_returns_struct = 1;
+    }
 
-  cfun->stack_alignment_needed = STACK_BOUNDARY;
-  cfun->preferred_stack_boundary = STACK_BOUNDARY;
+  current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result));
 
-  /* Set if a call to setjmp is seen.  */
-  current_function_calls_setjmp = 0;
+  current_function_needs_context
+    = (decl_function_context (current_function_decl) != 0
+       && ! DECL_NO_STATIC_CHAIN (current_function_decl));
+}
 
-  /* Set if a call to longjmp is seen.  */
-  current_function_calls_longjmp = 0;
+/* Reset cfun, and other non-struct-function variables to defaults as
+   appropriate for emiiting rtl at the start of a function.  */
 
-  current_function_calls_alloca = 0;
-  current_function_calls_eh_return = 0;
-  current_function_calls_constant_p = 0;
-  current_function_contains_functions = 0;
-  current_function_is_leaf = 0;
-  current_function_nothrow = 0;
-  current_function_sp_is_unchanging = 0;
-  current_function_uses_only_leaf_regs = 0;
-  current_function_has_computed_jump = 0;
-  current_function_is_thunk = 0;
-
-  current_function_returns_pcc_struct = 0;
-  current_function_returns_struct = 0;
-  current_function_epilogue_delay_list = 0;
-  current_function_uses_const_pool = 0;
-  current_function_uses_pic_offset_table = 0;
-  current_function_cannot_inline = 0;
-
-  /* We have not yet needed to make a label to jump to for tail-recursion.  */
-  tail_recursion_label = 0;
-
-  /* We haven't had a need to make a save area for ap yet.  */
-  arg_pointer_save_area = 0;
-
-  /* No stack slots allocated yet.  */
-  frame_offset = 0;
+static void
+prepare_function_start (tree fndecl)
+{
+  if (fndecl && DECL_SAVED_INSNS (fndecl))
+    cfun = DECL_SAVED_INSNS (fndecl);
+  else
+    allocate_struct_function (fndecl);
 
-  /* No SAVE_EXPRs in this function yet.  */
-  save_expr_regs = 0;
+  cse_not_expected = ! optimize;
 
-  /* No RTL_EXPRs in this function yet.  */
-  rtl_expr_chain = 0;
+  /* Caller save not needed yet.  */
+  caller_save_needed = 0;
 
-  /* Set up to allocate temporaries.  */
-  init_temp_slots ();
+  /* We haven't done register allocation yet.  */
+  reg_renumber = 0;
 
   /* Indicate that we need to distinguish between the return value of the
      present function and the return value of a function being called.  */
@@ -6359,27 +6374,6 @@
 
   /* Indicate we have no need of a frame pointer yet.  */
   frame_pointer_needed = 0;
-
-  /* By default assume not stdarg.  */
-  current_function_stdarg = 0;
-
-  /* We haven't made any trampolines for this function yet.  */
-  trampoline_list = 0;
-
-  init_pending_stack_adjust ();
-  inhibit_defer_pop = 0;
-
-  current_function_outgoing_args_size = 0;
-
-  current_function_funcdef_no = funcdef_no++;
-
-  cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
-
-  cfun->max_jumptable_ents = 0;
-
-  (*lang_hooks.function.init) (cfun);
-  if (init_machine_status)
-    cfun->machine = (*init_machine_status) ();
 }
 
 /* Initialize the rtl expansion mechanism so that we can do simple things
@@ -6388,7 +6382,7 @@
 void
 init_dummy_function_start (void)
 {
-  prepare_function_start ();
+  prepare_function_start (NULL);
 }
 
 /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
@@ -6398,51 +6392,30 @@
 void
 init_function_start (tree subr)
 {
-  prepare_function_start ();
-
-  current_function_name = (*lang_hooks.decl_printable_name) (subr, 2);
-  cfun->decl = subr;
-
-  /* Nonzero if this is a nested function that uses a static chain.  */
-
-  current_function_needs_context
-    = (decl_function_context (current_function_decl) != 0
-       && ! DECL_NO_STATIC_CHAIN (current_function_decl));
+  prepare_function_start (subr);
 
   if (!EMIT_LLVM) {
     /* Within function body, compute a type's size as soon it is laid out.  */
     immediate_size_expand++;
-
-    /* Prevent ever trying to delete the first instruction of a
-       function.  Also tell final how to output a linenum before the
-       function prologue.  Note linenums could be missing, e.g. when
-       compiling a Java .class file.  */
-    if (DECL_SOURCE_LINE (subr))
-      emit_line_note (DECL_SOURCE_LOCATION (subr));
-
-    /* Make sure first insn is a note even if we don't want linenums.
-       This makes sure the first insn will never be deleted.
-       Also, final expects a note to appear there.  */
-    emit_note (NOTE_INSN_DELETED);
   }
 
-  /* Set flags used by final.c.  */
-  if (aggregate_value_p (DECL_RESULT (subr)))
-    {
-#ifdef PCC_STATIC_STRUCT_RETURN
-      current_function_returns_pcc_struct = 1;
-#endif
-      current_function_returns_struct = 1;
-    }
-  
+  /* Prevent ever trying to delete the first instruction of a
+     function.  Also tell final how to output a linenum before the
+     function prologue.  Note linenums could be missing, e.g. when
+     compiling a Java .class file.  */
+  if (DECL_SOURCE_LINE (subr))
+    emit_line_note (DECL_SOURCE_LOCATION (subr));
+
+  /* Make sure first insn is a note even if we don't want linenums.
+     This makes sure the first insn will never be deleted.
+     Also, final expects a note to appear there.  */
+  emit_note (NOTE_INSN_DELETED);
+
   /* Warn if this value is an aggregate type,
      regardless of which calling convention we are using for it.  */
   if (warn_aggregate_return
       && AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
     warning ("function returns an aggregate");
-  
-  current_function_returns_pointer
-    = POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
 }
 
 /* Make sure all values used by the optimization passes have sane
@@ -6588,7 +6561,7 @@
      before any library calls that assign parms might generate.  */
 
   /* Decide whether to return the value in memory or in a register.  */
-  if (aggregate_value_p (DECL_RESULT (subr)))
+  if (aggregate_value_p (DECL_RESULT (subr), subr))
     {
       /* Returning something that won't go in a register.  */
       rtx value_address = 0;
@@ -6602,13 +6575,14 @@
       else
 #endif
 	{
+	  rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 1);
 	  /* Expect to be passed the address of a place to store the value.
 	     If it is passed as an argument, assign_parms will take care of
 	     it.  */
-	  if (struct_value_incoming_rtx)
+	  if (sv)
 	    {
 	      value_address = gen_reg_rtx (Pmode);
-	      emit_move_insn (value_address, struct_value_incoming_rtx);
+	      emit_move_insn (value_address, sv);
 	    }
 	}
       if (value_address)
@@ -6925,8 +6899,7 @@
 	   decl; decl = TREE_CHAIN (decl))
 	if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
 	    && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-          warning ("%Hunused parameter '%D'",
-                   &DECL_SOURCE_LOCATION (decl), decl);
+          warning ("%Junused parameter '%D'", decl, decl);
     }
 
   /* Delete handlers for nonlocal gotos if nothing uses them.  */
@@ -7048,10 +7021,9 @@
 	    {
 	      int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));
 
-#ifdef PROMOTE_FUNCTION_RETURN
-	      promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
-			    &unsignedp, 1);
-#endif
+	      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+		promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
+			      &unsignedp, 1);
 
 	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
 	    }
@@ -7097,12 +7069,9 @@
 	 assignment and USE below when inlining this function.  */
       REG_FUNCTION_VALUE_P (outgoing) = 1;
 
-#ifdef POINTERS_EXTEND_UNSIGNED
       /* The address may be ptr_mode and OUTGOING may be Pmode.  */
-      if (GET_MODE (outgoing) != GET_MODE (value_address))
-	value_address = convert_memory_address (GET_MODE (outgoing),
-						value_address);
-#endif
+      value_address = convert_memory_address (GET_MODE (outgoing),
+					      value_address);
 
       emit_move_insn (outgoing, value_address);
 


Index: gcc-3.4/gcc/gcc.c
diff -u gcc-3.4/gcc/gcc.c:1.2 gcc-3.4/gcc/gcc.c:1.3
--- gcc-3.4/gcc/gcc.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/gcc.c	Thu Feb  5 10:05:44 2004
@@ -1441,21 +1441,6 @@
 #define MD_STARTFILE_PREFIX_1 ""
 #endif
 
-/* Supply defaults for the standard prefixes.  */
-
-#ifndef STANDARD_EXEC_PREFIX
-#define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc/"
-#endif
-#ifndef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
-#endif
-#ifndef TOOLDIR_BASE_PREFIX
-#define TOOLDIR_BASE_PREFIX "/usr/local/"
-#endif
-#ifndef STANDARD_BINDIR_PREFIX
-#define STANDARD_BINDIR_PREFIX "/usr/local/bin"
-#endif
-
 static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
 static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
 static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
@@ -3245,7 +3230,7 @@
 	  if (IS_DIR_SEPARATOR (*temp)
 	      && strncmp (temp + 1, "lib", 3) == 0
 	      && IS_DIR_SEPARATOR (temp[4])
-	      && strncmp (temp + 5, "gcc", 7) == 0)
+	      && strncmp (temp + 5, "gcc", 3) == 0)
 	    len -= sizeof ("/lib/gcc/") - 1;
 	}
 
@@ -6165,12 +6150,15 @@
       /* If standard_startfile_prefix is relative, base it on
 	 standard_exec_prefix.  This lets us move the installed tree
 	 as a unit.  If GCC_EXEC_PREFIX is defined, base
-	 standard_startfile_prefix on that as well.  */
+	 standard_startfile_prefix on that as well.
+
+         If the prefix is relative, only search it for native compilers;
+         otherwise we will search a directory containing host libraries.  */
       if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
 	add_sysrooted_prefix (&startfile_prefixes,
 			      standard_startfile_prefix, "BINUTILS",
 			      PREFIX_PRIORITY_LAST, 0, NULL, 1);
-      else
+      else if (*cross_compile == '0')
 	{
 	  if (gcc_exec_prefix)
 	    add_prefix (&startfile_prefixes,


Index: gcc-3.4/gcc/integrate.c
diff -u gcc-3.4/gcc/integrate.c:1.2 gcc-3.4/gcc/integrate.c:1.3
--- gcc-3.4/gcc/integrate.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/integrate.c	Thu Feb  5 10:05:45 2004
@@ -493,7 +493,7 @@
     }
   cfun->original_decl_initial = DECL_INITIAL (fndecl);
   cfun->no_debugging_symbols = (write_symbols == NO_DEBUG);
-  DECL_SAVED_INSNS (fndecl) = cfun;
+  cfun->saved_for_inline = 1;
 
   /* Clean up.  */
   if (! flag_no_inline)
@@ -1029,7 +1029,7 @@
       else
 	{
 	  if (! structure_value_addr
-	      || ! aggregate_value_p (DECL_RESULT (fndecl)))
+	      || ! aggregate_value_p (DECL_RESULT (fndecl), fndecl))
 	    abort ();
 
 	  /* Pass the function the address in which to return a structure
@@ -1284,7 +1284,7 @@
      out of the temp register into a BLKmode memory object.  */
   if (target
       && TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
-      && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
+      && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl))
     target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
 
   if (structure_value_addr)
@@ -2158,11 +2158,7 @@
 #endif
 
 	      temp = XEXP (temp, 0);
-
-#ifdef POINTERS_EXTEND_UNSIGNED
-	      if (GET_MODE (temp) != GET_MODE (orig))
-		temp = convert_memory_address (GET_MODE (orig), temp);
-#endif
+	      temp = convert_memory_address (GET_MODE (orig), temp);
 	      return temp;
 	    }
 	  else if (GET_CODE (constant) == LABEL_REF)


Index: gcc-3.4/gcc/langhooks-def.h
diff -u gcc-3.4/gcc/langhooks-def.h:1.2 gcc-3.4/gcc/langhooks-def.h:1.3
--- gcc-3.4/gcc/langhooks-def.h:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/langhooks-def.h	Thu Feb  5 10:05:45 2004
@@ -24,6 +24,8 @@
 
 #include "hooks.h"
 
+#include "llvm-out.h"
+
 struct diagnostic_context;
 struct llvm_value;
 struct llvm_function;
@@ -49,7 +51,9 @@
 extern bool lhd_post_options (const char **);
 extern HOST_WIDE_INT lhd_get_alias_set (tree);
 extern tree lhd_return_tree (tree);
+extern tree lhd_return_null_tree_v (void);
 extern tree lhd_return_null_tree (tree);
+extern tree lhd_do_nothing_iii_return_null_tree (int, int, int);
 extern int lhd_safe_from_p (rtx, tree);
 extern int lhd_staticp (tree);
 extern int lhd_unsafe_for_reeval (tree);
@@ -71,6 +75,7 @@
 extern bool lhd_warn_unused_global_decl (tree);
 extern void lhd_incomplete_type_error (tree, tree);
 extern tree lhd_type_promotes_to (tree);
+extern void lhd_register_builtin_type (tree, const char *);
 extern bool lhd_decl_ok_for_sibcall (tree);
 extern tree lhd_expr_size (tree);
 extern bool lhd_decl_uninit (tree);
@@ -91,6 +96,8 @@
 extern void lhd_tree_inlining_end_inlining (tree);
 extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree);
 extern void lhd_initialize_diagnostics (struct diagnostic_context *);
+extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
+
 
 #define LANG_HOOKS_NAME			"GNU unknown"
 #define LANG_HOOKS_IDENTIFIER_SIZE	sizeof (struct lang_identifier)
@@ -137,6 +144,17 @@
 #define LANG_HOOKS_FUNCTION_ENTER_NESTED lhd_do_nothing_f
 #define LANG_HOOKS_FUNCTION_LEAVE_NESTED lhd_do_nothing_f
 
+#define LANG_HOOKS_RTL_EXPAND_START	lhd_do_nothing
+#define LANG_HOOKS_RTL_EXPAND_STMT	(void (*) (tree)) abort
+#define LANG_HOOKS_RTL_EXPAND_END	lhd_do_nothing
+
+#ifdef EMIT_LLVM
+/* LLVM Code Generation Hooks (akin to RTL Generation Hooks above) */
+#define LANG_HOOKS_LLVM_IR_EXPAND_START	lhd_do_nothing
+#define LANG_HOOKS_LLVM_IR_EXPAND_STMT	(void (*) (tree)) abort
+#define LANG_HOOKS_LLVM_IR_EXPAND_END	lhd_do_nothing
+#endif
+
 /* Attribute hooks.  */
 #define LANG_HOOKS_ATTRIBUTE_TABLE		NULL
 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE	NULL
@@ -183,15 +201,17 @@
   LANG_HOOKS_TREE_INLINING_END_INLINING, \
   LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING, \
   LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \
-} \
+}
 
-#define LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION NULL
+#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR lhd_callgraph_analyze_expr
 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION NULL
+#define LANG_HOOKS_LLVM_CALLGRAPH_EXPAND_FUNCTION abort
 
 #define LANG_HOOKS_CALLGRAPH_INITIALIZER { \
-  LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION, \
+  LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR, \
   LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, \
-} \
+  LANG_HOOKS_LLVM_CALLGRAPH_EXPAND_FUNCTION, \
+}
 
 #define LANG_HOOKS_FUNCTION_INITIALIZER {	\
   LANG_HOOKS_FUNCTION_INIT,			\
@@ -200,6 +220,20 @@
   LANG_HOOKS_FUNCTION_LEAVE_NESTED		\
 }
 
+#define LANG_HOOKS_RTL_EXPAND_INITIALIZER {	\
+  LANG_HOOKS_RTL_EXPAND_START,			\
+  LANG_HOOKS_RTL_EXPAND_STMT,			\
+  LANG_HOOKS_RTL_EXPAND_END			\
+}
+
+#ifdef EMIT_LLVM
+#define LANG_HOOKS_LLVM_EXPAND_INITIALIZER {	\
+  LANG_HOOKS_LLVM_IR_EXPAND_START,			\
+  LANG_HOOKS_LLVM_IR_EXPAND_STMT,			\
+  LANG_HOOKS_LLVM_IR_EXPAND_END			\
+}
+#endif
+
 /* Tree dump hooks.  */
 extern bool lhd_tree_dump_dump_tree (void *, tree);
 extern int lhd_tree_dump_type_quals (tree);
@@ -217,6 +251,7 @@
 #define LANG_HOOKS_MAKE_TYPE make_node
 #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
 #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
 
 #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
   LANG_HOOKS_MAKE_TYPE, \
@@ -226,6 +261,7 @@
   LANG_HOOKS_SIGNED_TYPE, \
   LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE, \
   LANG_HOOKS_TYPE_PROMOTES_TO, \
+  LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
   LANG_HOOKS_INCOMPLETE_TYPE_ERROR \
 }
 
@@ -237,6 +273,7 @@
 #define LANG_HOOKS_SET_BLOCK	set_block
 #define LANG_HOOKS_PUSHDECL	pushdecl
 #define LANG_HOOKS_GETDECLS	getdecls
+#define LANG_HOOKS_BUILTIN_TYPE_DECLS lhd_return_null_tree_v
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
 #define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
 #define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE NULL
@@ -250,6 +287,7 @@
   LANG_HOOKS_SET_BLOCK, \
   LANG_HOOKS_PUSHDECL, \
   LANG_HOOKS_GETDECLS, \
+  LANG_HOOKS_BUILTIN_TYPE_DECLS, \
   LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
   LANG_HOOKS_WRITE_GLOBALS, \
   LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE, \
@@ -307,7 +345,9 @@
   LANG_HOOKS_CALLGRAPH_INITIALIZER, \
   LANG_HOOKS_TREE_DUMP_INITIALIZER, \
   LANG_HOOKS_DECLS, \
-  LANG_HOOKS_FOR_TYPES_INITIALIZER \
+  LANG_HOOKS_FOR_TYPES_INITIALIZER, \
+  LANG_HOOKS_RTL_EXPAND_INITIALIZER, \
+  LANG_HOOKS_LLVM_EXPAND_INITIALIZER \
 }
 
 #endif /* GCC_LANG_HOOKS_DEF_H */


Index: gcc-3.4/gcc/langhooks.c
diff -u gcc-3.4/gcc/langhooks.c:1.2 gcc-3.4/gcc/langhooks.c:1.3
--- gcc-3.4/gcc/langhooks.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/langhooks.c	Thu Feb  5 10:05:45 2004
@@ -33,6 +33,7 @@
 #include "langhooks.h"
 #include "langhooks-def.h"
 #include "ggc.h"
+#include "diagnostic.h"
 
 /* Do nothing; in many cases the default hook.  */
 
@@ -55,6 +56,16 @@
 {
 }
 
+/* Do nothing (int, int, int).  Return NULL_TREE.  */
+
+tree
+lhd_do_nothing_iii_return_null_tree (int i ATTRIBUTE_UNUSED, 
+				     int j ATTRIBUTE_UNUSED,
+				     int k ATTRIBUTE_UNUSED)
+{
+  return NULL_TREE;
+}
+
 /* Do nothing (function).  */
 
 void
@@ -73,6 +84,14 @@
 /* Do nothing (return NULL_TREE).  */
 
 tree
+lhd_return_null_tree_v (void)
+{
+  return NULL_TREE;
+}
+
+/* Do nothing (return NULL_TREE).  */
+
+tree
 lhd_return_null_tree (tree t ATTRIBUTE_UNUSED)
 {
   return NULL_TREE;
@@ -207,6 +226,13 @@
   abort ();
 }
 
+/* Registration of machine- or os-specific builtin types.  */
+void
+lhd_register_builtin_type (tree type ATTRIBUTE_UNUSED, 
+			   const char* name ATTRIBUTE_UNUSED)
+{
+}
+
 /* Invalid use of an incomplete type.  */
 void
 lhd_incomplete_type_error (tree value ATTRIBUTE_UNUSED, tree type)
@@ -525,6 +551,48 @@
 void
 lhd_initialize_diagnostics (struct diagnostic_context *ctx ATTRIBUTE_UNUSED)
 {
+}
+
+/* The default function to print out name of current function that caused
+   an error.  */
+void
+lhd_print_error_function (diagnostic_context *context, const char *file)
+{
+  if (diagnostic_last_function_changed (context))
+    {
+      const char *old_prefix = context->printer->prefix;
+      char *new_prefix = file ? file_name_as_prefix (file) : NULL;
+
+      pp_set_prefix (context->printer, new_prefix);
+
+      if (current_function_decl == NULL)
+	pp_printf (context->printer, "At top level:");
+      else
+	{
+	  if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
+	    pp_printf
+	      (context->printer, "In member function `%s':",
+	       (*lang_hooks.decl_printable_name) (current_function_decl, 2));
+	  else
+	    pp_printf
+	      (context->printer, "In function `%s':",
+	       (*lang_hooks.decl_printable_name) (current_function_decl, 2));
+	}
+      pp_newline (context->printer);
+
+      diagnostic_set_last_function (context);
+      pp_flush (context->printer);
+      context->printer->prefix = old_prefix;
+      free ((char*) new_prefix);
+    }
+}
+
+tree
+lhd_callgraph_analyze_expr (tree *tp ATTRIBUTE_UNUSED,
+			    int *walk_subtrees ATTRIBUTE_UNUSED,
+			    tree decl ATTRIBUTE_UNUSED)
+{
+  return NULL;
 }
 
 #include "gt-langhooks.h"


Index: gcc-3.4/gcc/langhooks.h
diff -u gcc-3.4/gcc/langhooks.h:1.2 gcc-3.4/gcc/langhooks.h:1.3
--- gcc-3.4/gcc/langhooks.h:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/langhooks.h	Thu Feb  5 10:05:45 2004
@@ -23,6 +23,8 @@
 
 /* This file should be #include-d after tree.h.  */
 
+#include "llvm-representation.h"
+
 struct diagnostic_context;
 struct llvm_value;
 struct llvm_function;
@@ -56,11 +58,15 @@
 
 struct lang_hooks_for_callgraph
 {
-  /* Function passed as argument is needed and will be compiled.
-     Lower the representation so the calls are explicit.  */
-  void (*lower_function) (tree);
+  /* The node passed is a language-specific tree node.  If its contents
+     are relevant to use of other declarations, mark them.  */
+  tree (*analyze_expr) (tree *, int *, tree);
+
   /* Produce RTL for function passed as argument.  */
   void (*expand_function) (tree);
+
+  /* Produce LLVM bytecode for function passed as argument. */
+  void (*llvm_expand_function) (tree);
 };
 
 /* Lang hooks for management of language-specific data or status
@@ -80,6 +86,34 @@
   void (*leave_nested) (struct function *);
 };
 
+/* Lang hooks for rtl code generation.  */
+struct lang_hooks_for_rtl_expansion
+{
+  /* Called after expand_function_start, but before expanding the body.  */
+  void (*start) (void);
+
+  /* Called to expand each statement.  */
+  void (*stmt) (tree);
+
+  /* Called after expanding the body but before expand_function_end.  */
+  void (*end) (void);
+};
+
+/* Lang hooks for LLVM code generation
+ * (based off of lang_hooks_for_rtl_expansion)
+ */
+struct lang_hooks_for_llvm_expansion
+{
+  /* Called after expand_function_start, but before expanding the body.  */
+  void (*start) (void);
+
+  /* Called to expand each statement.  */
+  void (*stmt) (llvm_function *, tree);
+
+  /* Called after expanding the body but before expand_function_end.  */
+  void (*end) (void);
+};
+
 /* The following hooks are used by tree-dump.c.  */
 
 struct lang_hooks_for_tree_dump
@@ -126,6 +160,15 @@
      arguments.  The default hook aborts.  */
   tree (*type_promotes_to) (tree);
 
+  /* Register TYPE as a builtin type with the indicated NAME.  The
+     TYPE is placed in the outermost lexical scope.  The semantics
+     should be analogous to:
+
+       typedef TYPE NAME;
+
+     in C.  The default hook ignores the declaration.  */
+  void (*register_builtin_type) (tree, const char *);
+
   /* This routine is called in tree.c to print an error message for
      invalid use of an incomplete type.  VALUE is the expression that
      was used (or 0 if that isn't known) and TYPE is the type that was
@@ -169,6 +212,9 @@
   /* Returns the chain of decls so far in the current scope level.  */
   tree (*getdecls) (void);
 
+  /* Returns a chain of TYPE_DECLs for built-in types.  */
+  tree (*builtin_type_decls) (void);
+
   /* Returns true when we should warn for an unused global DECL.
      We will already have checked that it has static binding.  */
   bool (*warn_unused_global) (tree);
@@ -404,8 +450,12 @@
 
   struct lang_hooks_for_types types;
 
+  struct lang_hooks_for_rtl_expansion rtl_expand;
+
   /* Whenever you add entries here, make sure you adjust langhooks-def.h
      and langhooks.c accordingly.  */
+
+  struct lang_hooks_for_llvm_expansion llvm_expand;
 };
 
 /* Each front end provides its own.  */


Index: gcc-3.4/gcc/llvm-expand.c
diff -u gcc-3.4/gcc/llvm-expand.c:1.7 gcc-3.4/gcc/llvm-expand.c:1.8
--- gcc-3.4/gcc/llvm-expand.c:1.7	Tue Feb  3 12:29:24 2004
+++ gcc-3.4/gcc/llvm-expand.c	Thu Feb  5 10:05:45 2004
@@ -2848,8 +2848,16 @@
 
   /* Perform necessary processing */
   if ((fndecl = get_callee_fndecl (exp))) {
+    /*
+     * Mark the function decl so that we can take the address of it.
+     */
     (*lang_hooks.mark_addressable) (fndecl);
   
+    /*
+     * Mark the function as referenced.
+     */
+    mark_referenced (DECL_ASSEMBLER_NAME(fndecl));
+
     if (DECL_NAME(fndecl) && IDENTIFIER_POINTER(DECL_NAME(fndecl))) {
       const char *Name = IDENTIFIER_POINTER(DECL_NAME(fndecl));
       unsigned NameLen = IDENTIFIER_LENGTH(DECL_NAME(fndecl));
@@ -6205,7 +6213,6 @@
   return llvm_type_get_cannonical_function(BaseType);
 }
 
-
 /* Initialize the function, adding arguments to the function as appropriate.
    Set up parameters and prepare for return, for the function.  If subr is an
    external function, we just set up the arguments.
@@ -6262,14 +6269,17 @@
   Fn = (llvm_function*)DECL_LLVM(subr);
 
   /* No more processing for external functions. */
-  if (isExternal) return Fn;
+  if (isExternal) {
+    return Fn;
+  }
 
   /* If there is already a body for this function, it's a wierd error.  The only
    * case we allow is if the old function was linkonce.
-  */
+   */
   if (!llvm_ilist_empty(llvm_basicblock, Fn->BasicBlocks)) {
     assert(Fn->Linkage == L_LinkOnce &&
            "Cannot redefine non-linkonce functions!");
+    warning ("LLVM: LinkOnce function redefined to external!");
     llvm_ilist_clear(llvm_basicblock, Fn->BasicBlocks);
     llvm_ilist_clear(llvm_argument, Fn->Arguments);
     Fn->Linkage = L_External;
@@ -6726,3 +6736,9 @@
   llvm_type *ClassTy = llvm_type_get_from_tree(ty);
   return D2V(make_temporary_alloca(Fn, ClassTy));
 }
+
+const char *llvm_get_decl_name(llvm_value *V) {
+  assert ((V != NULL) && "llvm_get_decl_name: Null value!");
+  return V->Name;
+}
+


Index: gcc-3.4/gcc/llvm-out.c
diff -u gcc-3.4/gcc/llvm-out.c:1.1 gcc-3.4/gcc/llvm-out.c:1.2
--- gcc-3.4/gcc/llvm-out.c:1.1	Thu Jan  8 16:35:32 2004
+++ gcc-3.4/gcc/llvm-out.c	Thu Feb  5 10:05:45 2004
@@ -27,7 +27,8 @@
 #include "tree.h"
 #include "tree-inline.h"
 #include "flags.h"
-#include "c-tree.h"
+/* #include "c-tree.h" */
+#include "tree.h"
 #include "toplev.h"
 #include "ggc.h"
 #include "tm_p.h"
@@ -53,6 +54,7 @@
 void llvm_init_codegen() {
   flag_inline_functions = 0;
   flag_really_no_inline = 1;
+  flag_unit_at_a_time = 0;
   warn_inline = 0;
 
   llvm_InitializeProgram();
@@ -143,7 +145,7 @@
      to run global initializers, etc.  */
   if (DECL_NAME (fndecl)
       && MAIN_NAME_P (DECL_NAME (fndecl))
-      && C_DECL_FILE_SCOPE (fndecl))
+      && DECL_FILE_SCOPE_P (fndecl))
     llvm_expand_main_function (Func);
 
   /* Generate LLVM for this function body.  */


Index: gcc-3.4/gcc/llvm-out.h
diff -u gcc-3.4/gcc/llvm-out.h:1.2 gcc-3.4/gcc/llvm-out.h:1.3
--- gcc-3.4/gcc/llvm-out.h:1.2	Mon Feb  2 12:39:26 2004
+++ gcc-3.4/gcc/llvm-out.h	Thu Feb  5 10:05:45 2004
@@ -62,6 +62,9 @@
 void llvm_emit_final_program(const char *version);
 void llvm_program_print(FILE *);
 
+struct llvm_value;
+const char *llvm_get_decl_name(struct llvm_value*);
+
 #if EMIT_LLVM
 /* FIXME: We should eventually implement this for crtstuff.c! This is used for
    exception handling stuff... */


Index: gcc-3.4/gcc/loop.c
diff -u gcc-3.4/gcc/loop.c:1.2 gcc-3.4/gcc/loop.c:1.3
--- gcc-3.4/gcc/loop.c:1.2	Fri Jan  9 10:54:24 2004
+++ gcc-3.4/gcc/loop.c	Thu Feb  5 10:05:45 2004
@@ -22,8 +22,8 @@
 /* This is the loop optimization pass of the compiler.
    It finds invariant computations within loops and moves them
    to the beginning of the loop.  Then it identifies basic and
-   general induction variables.  
-   
+   general induction variables.
+
    Basic induction variables (BIVs) are a pseudo registers which are set within
    a loop only by incrementing or decrementing its value.  General induction
    variables (GIVs) are pseudo registers with a value which is a linear function
@@ -4231,7 +4231,6 @@
   return;
 }
 
-
 /* Communication with routines called via `note_stores'.  */
 
 static rtx note_insn;
@@ -7742,25 +7741,16 @@
 
   /* Update register info for alias analysis.  */
 
-  if (seq == NULL_RTX)
-    return;
-
-  if (INSN_P (seq))
+  insn = seq;
+  while (insn != NULL_RTX)
     {
-      insn = seq;
-      while (insn != NULL_RTX)
-	{
-	  rtx set = single_set (insn);
+      rtx set = single_set (insn);
 
-	  if (set && GET_CODE (SET_DEST (set)) == REG)
-	    record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
+      if (set && GET_CODE (SET_DEST (set)) == REG)
+	record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
 
-	  insn = NEXT_INSN (insn);
-	}
+      insn = NEXT_INSN (insn);
     }
-  else if (GET_CODE (seq) == SET
-	   && GET_CODE (SET_DEST (seq)) == REG)
-    record_base_value (REGNO (SET_DEST (seq)), SET_SRC (seq), 0);
 }
 
 
@@ -7990,7 +7980,7 @@
 
   /* Try to compute whether the compare/branch at the loop end is one or
      two instructions.  */
-  get_condition (jump, &first_compare);
+  get_condition (jump, &first_compare, false);
   if (first_compare == jump)
     compare_and_branch = 1;
   else if (first_compare == prev_nonnote_insn (jump))
@@ -9153,11 +9143,12 @@
 
    If WANT_REG is nonzero, we wish the condition to be relative to that
    register, if possible.  Therefore, do not canonicalize the condition
-   further.  */
+   further.  If ALLOW_CC_MODE is nonzero, allow the condition returned 
+   to be a compare to a CC mode register.  */
 
 rtx
 canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
-			rtx want_reg)
+			rtx want_reg, int allow_cc_mode)
 {
   enum rtx_code code;
   rtx prev = insn;
@@ -9336,14 +9327,16 @@
 
   /* If OP0 is the result of a comparison, we weren't able to find what
      was really being compared, so fail.  */
-  if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
+  if (!allow_cc_mode
+      && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
     return 0;
 
   /* Canonicalize any ordered comparison with integers involving equality
      if we can do computations in the relevant mode and we do not
      overflow.  */
 
-  if (GET_CODE (op1) == CONST_INT
+  if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
+      && GET_CODE (op1) == CONST_INT
       && GET_MODE (op0) != VOIDmode
       && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
     {
@@ -9398,10 +9391,13 @@
    If EARLIEST is nonzero, it is a pointer to a place where the earliest
    insn used in locating the condition was found.  If a replacement test
    of the condition is desired, it should be placed in front of that
-   insn and we will be sure that the inputs are still valid.  */
+   insn and we will be sure that the inputs are still valid.  
+
+   If ALLOW_CC_MODE is nonzero, allow the condition returned to be a
+   compare CC mode register.  */
 
 rtx
-get_condition (rtx jump, rtx *earliest)
+get_condition (rtx jump, rtx *earliest, int allow_cc_mode)
 {
   rtx cond;
   int reverse;
@@ -9421,7 +9417,8 @@
     = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
       && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump);
 
-  return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
+  return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
+				 allow_cc_mode);
 }
 
 /* Similar to above routine, except that we also put an invariant last
@@ -9430,7 +9427,7 @@
 rtx
 get_condition_for_loop (const struct loop *loop, rtx x)
 {
-  rtx comparison = get_condition (x, (rtx*) 0);
+  rtx comparison = get_condition (x, (rtx*) 0, false);
 
   if (comparison == 0
       || ! loop_invariant_p (loop, XEXP (comparison, 0))


Index: gcc-3.4/gcc/opts.c
diff -u gcc-3.4/gcc/opts.c:1.2 gcc-3.4/gcc/opts.c:1.3
--- gcc-3.4/gcc/opts.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/opts.c	Thu Feb  5 10:05:45 2004
@@ -558,6 +558,7 @@
       flag_delete_null_pointer_checks = 1;
       flag_reorder_blocks = 1;
       flag_reorder_functions = 1;
+      flag_unit_at_a_time = 1;
     }
 
   if (optimize >= 3)
@@ -565,8 +566,6 @@
       flag_inline_functions = 1;
       flag_rename_registers = 1;
       flag_unswitch_loops = 1;
-      if (!EMIT_LLVM)
-        flag_unit_at_a_time = 1;
     }
 
   if (optimize < 2 || optimize_size)
@@ -1223,8 +1222,12 @@
       flag_rerun_loop_opt = value;
       break;
 
+    case OPT_frounding_math:
+      flag_rounding_math = value;
+      break;
+
     case OPT_fsched_interblock:
-      flag_schedule_interblock= value;
+      flag_schedule_interblock = value;
       break;
 
     case OPT_fsched_spec:
@@ -1550,7 +1553,10 @@
   flag_finite_math_only = set;
   flag_errno_math = !set;
   if (set)
-    flag_signaling_nans = 0;
+    {
+      flag_signaling_nans = 0;
+      flag_rounding_math = 0;
+    }
 }
 
 /* Return true iff flags are set as if -ffast-math.  */


Index: gcc-3.4/gcc/stmt.c
diff -u gcc-3.4/gcc/stmt.c:1.2 gcc-3.4/gcc/stmt.c:1.3
--- gcc-3.4/gcc/stmt.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/stmt.c	Thu Feb  5 10:05:45 2004
@@ -57,6 +57,8 @@
 #include "langhooks.h"
 #include "predict.h"
 #include "optabs.h"
+#include "target.h"
+
 #include "llvm-out.h"
 
 /* Assume that case vectors are not pc-relative.  */
@@ -434,25 +436,7 @@
 void
 init_stmt_for_function (void)
 {
-  cfun->stmt =ggc_alloc (sizeof (struct stmt_status));
-
-  /* We are not currently within any block, conditional, loop or case.  */
-  block_stack = 0;
-  stack_block_stack = 0;
-  loop_stack = 0;
-  case_stack = 0;
-  cond_stack = 0;
-  nesting_stack = 0;
-  nesting_depth = 0;
-
-  current_block_start_count = 0;
-
-  /* No gotos have been expanded yet.  */
-  goto_fixup_chain = 0;
-
-  /* We are not processing a ({...}) grouping.  */
-  expr_stmts_for_value = 0;
-  clear_last_expr ();
+  cfun->stmt = ggc_alloc_cleared (sizeof (struct stmt_status));
 }
 
 /* Record the current file and line.  Called from emit_line_note.  */
@@ -538,10 +522,7 @@
 {
   rtx x = expand_expr (exp, NULL_RTX, VOIDmode, 0);
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  if (GET_MODE (x) != Pmode)
-    x = convert_memory_address (Pmode, x);
-#endif
+  x = convert_memory_address (Pmode, x);
 
   emit_queue ();
 
@@ -988,8 +969,8 @@
 	      && INSN_UID (first_insn) > INSN_UID (f->before_jump)
 	      && ! DECL_ERROR_ISSUED (f->target))
 	    {
-	      error ("%Hlabel '%D' used before containing binding contour",
-                     &DECL_SOURCE_LOCATION (f->target), f->target);
+	      error ("%Jlabel '%D' used before containing binding contour",
+		     f->target, f->target);
 	      /* Prevent multiple errors for one label.  */
 	      DECL_ERROR_ISSUED (f->target) = 1;
 	    }
@@ -2957,16 +2938,17 @@
   if (return_reg != val)
     {
       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
-#ifdef PROMOTE_FUNCTION_RETURN
-      int unsignedp = TREE_UNSIGNED (type);
-      enum machine_mode old_mode
-	= DECL_MODE (DECL_RESULT (current_function_decl));
-      enum machine_mode mode
-	= promote_mode (type, old_mode, &unsignedp, 1);
+      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+      {
+	int unsignedp = TREE_UNSIGNED (type);
+	enum machine_mode old_mode
+	  = DECL_MODE (DECL_RESULT (current_function_decl));
+	enum machine_mode mode
+	  = promote_mode (type, old_mode, &unsignedp, 1);
 
-      if (mode != old_mode)
-	val = convert_modes (mode, old_mode, val, unsignedp);
-#endif
+	if (mode != old_mode)
+	  val = convert_modes (mode, old_mode, val, unsignedp);
+      }
       if (GET_CODE (return_reg) == PARALLEL)
 	emit_group_load (return_reg, val, type, int_size_in_bytes (type));
       else
@@ -3652,7 +3634,7 @@
 	  && ! TREE_USED (decl)
 	  && ! DECL_IN_SYSTEM_HEADER (decl)
 	  && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-	warning ("%Hunused variable '%D'", &DECL_SOURCE_LOCATION (decl), decl);
+	warning ("%Junused variable '%D'", decl, decl);
 }
 
 /* Generate RTL code to terminate a binding contour.
@@ -3712,8 +3694,8 @@
 	     that must be an error, because gotos without fixups
 	     come from outside all saved stack-levels.  */
 	  if (TREE_ADDRESSABLE (chain->label))
-	    error ("%Hlabel '%D' used before containing binding contour",
-                   &DECL_SOURCE_LOCATION (chain->label), chain->label);
+	    error ("%Jlabel '%D' used before containing binding contour",
+		   chain->label, chain->label);
 	}
     }
 
@@ -5439,7 +5421,8 @@
 	 because we can optimize it.  */
 
       else if (count < case_values_threshold ()
-	       || compare_tree_int (range, 10 * count) > 0
+	       || compare_tree_int (range,
+				    (optimize_size ? 3 : 10) * count) > 0
 	       /* RANGE may be signed, and really large ranges will show up
 		  as negative numbers.  */
 	       || compare_tree_int (range, 0) < 0


Index: gcc-3.4/gcc/toplev.c
diff -u gcc-3.4/gcc/toplev.c:1.3 gcc-3.4/gcc/toplev.c:1.4
--- gcc-3.4/gcc/toplev.c:1.3	Fri Jan  9 16:30:48 2004
+++ gcc-3.4/gcc/toplev.c	Thu Feb  5 10:05:45 2004
@@ -635,6 +635,11 @@
 
 int flag_trapping_math = 1;
 
+/* Nonzero means disable transformations that assume default floating
+   point rounding behavior.  */
+
+int flag_rounding_math = 0;
+
 /* Nonzero means disable transformations observable by signaling NaNs.
    This option implies that any operation on an IEEE signaling NaN can
    generate a (user-visible) trap.  */
@@ -1115,6 +1120,7 @@
   { "guess-branch-probability", &flag_guess_branch_prob, 1 },
   {"math-errno", &flag_errno_math, 1 },
   {"trapping-math", &flag_trapping_math, 1 },
+  {"rounding-math", &flag_rounding_math, 1 },
   {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1 },
   {"signaling-nans", &flag_signaling_nans, 1 },
   {"bounds-check", &flag_bounds_check, 1 },
@@ -1201,6 +1207,23 @@
    return src_pwd;
 }
 
+/* Called when the start of a function definition is parsed,
+   this function prints on stderr the name of the function.  */
+void
+announce_function (tree decl)
+{
+  if (!quiet_flag)
+    {
+      if (rtl_dump_and_exit)
+	verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
+      else
+	verbatim (" %s", (*lang_hooks.decl_printable_name) (decl, 2));
+      fflush (stderr);
+      pp_needs_newline (global_dc->printer) = true;
+      diagnostic_set_last_function (global_dc);
+    }
+}
+
 /* Set up a default flag_random_seed and local_tick, unless the user
    already specified one.  */
 
@@ -1567,7 +1590,7 @@
 	      if (flag_unit_at_a_time
 		  && cgraph_varpool_node (decl)->finalized)
 		needed = 0;
-	      else if (flag_unit_at_a_time
+	      else if ((flag_unit_at_a_time && !cgraph_global_info_ready)
 		       && (TREE_USED (decl)
 			   || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
 		/* needed */;
@@ -1590,6 +1613,7 @@
 	  if (TREE_CODE (decl) == FUNCTION_DECL
 	      && DECL_INITIAL (decl) != 0
 	      && DECL_SAVED_INSNS (decl) != 0
+	      && DECL_SAVED_INSNS (decl)->saved_for_inline
 	      && (flag_keep_inline_functions
 		  || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
 		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
@@ -1641,11 +1665,9 @@
 	  && ! TREE_PUBLIC (decl))
 	{
 	  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
-	    pedwarn ("%H'%F' used but never defined",
-                     &DECL_SOURCE_LOCATION (decl), decl);
+	    pedwarn ("%J'%F' used but never defined", decl, decl);
 	  else
-	    warning ("%H'%F' declared `static' but never defined",
-                     &DECL_SOURCE_LOCATION (decl), decl);
+	    warning ("%J'%F' declared `static' but never defined", decl, decl);
 	  /* This symbol is effectively an "extern" declaration now.  */
 	  TREE_PUBLIC (decl) = 1;
 	  assemble_external (decl);
@@ -1666,8 +1688,7 @@
 	  && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
 	  /* Otherwise, ask the language.  */
 	  && (*lang_hooks.decls.warn_unused_global) (decl))
-	warning ("%H'%D' defined but not used",
-                 &DECL_SOURCE_LOCATION (decl), decl);
+	warning ("%J'%D' defined but not used", decl, decl);
 
       /* Avoid confusing the debug information machinery when there are
 	 errors.  */
@@ -1680,6 +1701,44 @@
     }
 }
 
+/* Warn about a use of an identifier which was marked deprecated.  */
+void
+warn_deprecated_use (tree node)
+{
+  if (node == 0 || !warn_deprecated_decl)
+    return;
+
+  if (DECL_P (node))
+    warning ("`%s' is deprecated (declared at %s:%d)",
+	     IDENTIFIER_POINTER (DECL_NAME (node)),
+	     DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
+  else if (TYPE_P (node))
+    {
+      const char *what = NULL;
+      tree decl = TYPE_STUB_DECL (node);
+
+      if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
+	what = IDENTIFIER_POINTER (TYPE_NAME (node));
+      else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
+	       && DECL_NAME (TYPE_NAME (node)))
+	what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
+
+      if (what)
+	{
+	  if (decl)
+	    warning ("`%s' is deprecated (declared at %s:%d)", what,
+		     DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+	  else
+	    warning ("`%s' is deprecated", what);
+	}
+      else if (decl)
+	warning ("type is deprecated (declared at %s:%d)",
+		 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+      else
+	warning ("type is deprecated");
+    }
+}
+
 /* Save the current INPUT_LOCATION on the top entry in the
    INPUT_FILE_STACK.  Push a new entry for FILE and LINE, and set the
    INPUT_LOCATION accordingly.  */
@@ -1856,7 +1915,7 @@
 
       /* Don't output anything when a tentative file-scope definition
 	 is seen.  But at end of compilation, do output code for them.  */
-      if (at_end || !DECL_DEFER_OUTPUT (decl))
+      if ((at_end || !DECL_DEFER_OUTPUT (decl)) && !DECL_EXTERNAL (decl))
 	{
 	  if (flag_unit_at_a_time && !cgraph_global_info_ready
 	      && TREE_CODE (decl) != FUNCTION_DECL && top_level)
@@ -1976,14 +2035,33 @@
     /* Get the function's name, as described by its RTL.  This may be
        different from the DECL_NAME name used in the source file.  */
 
-    x = DECL_RTL (decl);
-    if (GET_CODE (x) != MEM)
-      abort ();
-    x = XEXP (x, 0);
-    if (GET_CODE (x) != SYMBOL_REF)
-      abort ();
-    fnname = XSTR (x, 0);
+    if (EMIT_LLVM)
+    {
+      struct llvm_value * LLVMDecl = DECL_LLVM (decl);
+#if 0
+      fnname = ((LLVMDecl==NULL)?NULL:xstrdup(llvm_get_decl_name(LLVMDecl)));
+#endif
+    }
+    else
+    {
+      x = DECL_RTL (decl);
+      if (GET_CODE (x) != MEM)
+        abort ();
+      x = XEXP (x, 0);
+      if (GET_CODE (x) != SYMBOL_REF)
+        abort ();
+      fnname = XSTR (x, 0);
+    }
 
+    if (EMIT_LLVM)
+    {
+#if 0
+      assemble_start_function (decl, fnname);
+      final_start_function (NULL, asm_out_file, optimize);
+#endif
+      final (insns, stderr, optimize, 0);
+      return;
+    }
     assemble_start_function (decl, fnname);
     final_start_function (insns, asm_out_file, optimize);
     final (insns, asm_out_file, optimize, 0);
@@ -2041,6 +2119,23 @@
 static void
 rest_of_handle_stack_regs (tree decl, rtx insns)
 {
+#if defined (HAVE_ATTR_length)
+  /* If flow2 creates new instructions which need splitting
+     and scheduling after reload is not done, they might not be
+     splitten until final which doesn't allow splitting
+     if HAVE_ATTR_length.  */
+#ifdef INSN_SCHEDULING
+  if (optimize && !flag_schedule_insns_after_reload)
+#else
+  if (optimize)
+#endif
+    {
+      timevar_push (TV_SHORTEN_BRANCH);
+      split_all_insns (1);
+      timevar_pop (TV_SHORTEN_BRANCH);
+    }
+#endif
+
   timevar_push (TV_REG_STACK);
   open_dump_file (DFI_stack, decl);
 
@@ -2485,8 +2580,9 @@
 
   /* If we are reconsidering an inline function at the end of
      compilation, skip the stuff for making it inline.  */
-  if (DECL_SAVED_INSNS (decl) != 0)
+  if (cfun->rtl_inline_init)
     return 0;
+  cfun->rtl_inline_init = 1;
 
   /* If this is nested inside an inlined external function, pretend
      it was only declared.  Since we cannot inline such functions,
@@ -2516,11 +2612,8 @@
 	{
 	  if (warn_inline && lose && DECL_INLINE (decl))
             {
-              char *msg = xmalloc (2 + strlen (lose) + 1);
-              msg[0] = '%';
-              msg[1] = 'H';
-              strcpy(msg + 2, lose);
-              warning (msg, &DECL_SOURCE_LOCATION (decl));
+              char *msg = concat ("%J", lose, NULL);
+              warning (msg, decl);
               free (msg);
             }
 	  DECL_ABSTRACT_ORIGIN (decl) = 0;
@@ -2543,7 +2636,7 @@
 
   if (open_dump_file (DFI_rtl, decl))
     {
-      if (DECL_SAVED_INSNS (decl))
+      if (DECL_SAVED_INSNS (decl) && DECL_SAVED_INSNS (decl)->saved_for_inline)
 	fprintf (rtl_dump_file, ";; (integrable)\n\n");
       close_dump_file (DFI_rtl, print_rtl, insns);
     }
@@ -2787,7 +2880,8 @@
   tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
   if (tem)
     rebuild_jump_labels (insns);
-  purge_all_dead_edges (0);
+  if (purge_all_dead_edges (0))
+    delete_unreachable_blocks ();
 
   delete_trivially_dead_insns (insns, max_reg_num ());
 
@@ -3011,6 +3105,12 @@
   rtx insns;
   int rebuild_label_notes_after_reload;
 
+  if (EMIT_LLVM)
+  {
+    rest_of_handle_final (decl, insns);
+    return;
+  }
+
   timevar_push (TV_REST_OF_COMPILATION);
 
   /* Register rtl specific functions for cfg.  */
@@ -3574,9 +3674,6 @@
   if (! DECL_DEFER_OUTPUT (decl))
     {
       free_after_compilation (cfun);
-
-      /* Clear integrate.c's pointer to the cfun structure we just
-	 destroyed.  */
       DECL_SAVED_INSNS (decl) = 0;
     }
   cfun = 0;
@@ -4283,8 +4380,6 @@
 #endif
 		    || flag_test_coverage
 		    || warn_notreached);
-
-  if (EMIT_LLVM) return;   /* LLVM must call init_emit_once */
 
   init_regs ();
   init_fake_stack_mems ();


Index: gcc-3.4/gcc/tree-optimize.c
diff -u gcc-3.4/gcc/tree-optimize.c:1.1.1.1 gcc-3.4/gcc/tree-optimize.c:1.2
--- gcc-3.4/gcc/tree-optimize.c:1.1.1.1	Tue Jan 13 10:49:09 2004
+++ gcc-3.4/gcc/tree-optimize.c	Thu Feb  5 10:05:45 2004
@@ -32,6 +32,8 @@
 #include "function.h"
 #include "ggc.h"
 
+#include "llvm-out.h"
+#include "llvm-internals.h"
 
 /* Called to move the SAVE_EXPRs for parameter declarations in a
    nested function into the nested function.  DATA is really the
@@ -96,6 +98,9 @@
 tree_rest_of_compilation (tree fndecl, bool nested_p)
 {
   location_t saved_loc;
+#ifdef EMIT_LLVM
+  struct llvm_function *LLVMFn;
+#endif
 
   timevar_push (TV_EXPAND);
 
@@ -128,20 +133,50 @@
 	       NULL);
 
   /* Set up parameters and prepare for return, for the function.  */
-  expand_function_start (fndecl, 0);
+  if (EMIT_LLVM)
+  {
+    LLVMFn = llvm_expand_function_start (fndecl, 0);
+  }
+  else
+  {
+    expand_function_start (fndecl, 0);
+  }
 
   /* Allow language dialects to perform special processing.  */
-  (*lang_hooks.rtl_expand.start) ();
+  if (EMIT_LLVM)
+  {
+    (*lang_hooks.llvm_expand.start) ();
+  }
+  else
+  {
+    (*lang_hooks.rtl_expand.start) ();
+  }
 
   /* If this function is `main', emit a call to `__main'
      to run global initializers, etc.  */
   if (DECL_NAME (fndecl)
       && MAIN_NAME_P (DECL_NAME (fndecl))
       && DECL_FILE_SCOPE_P (fndecl))
-    expand_main_function ();
+  {
+    if (EMIT_LLVM)
+    {
+      llvm_expand_main_function (LLVMFn);
+    }
+    else
+    {
+      expand_main_function ();
+    }
+  }
 
   /* Generate the RTL for this function.  */
-  (*lang_hooks.rtl_expand.stmt) (DECL_SAVED_TREE (fndecl));
+  if (EMIT_LLVM)
+  {
+    (*lang_hooks.llvm_expand.stmt) (LLVMFn, DECL_SAVED_TREE (fndecl));
+  }
+  else
+  {
+    (*lang_hooks.rtl_expand.stmt) (DECL_SAVED_TREE (fndecl));
+  }
 
   /* We hard-wired immediate_size_expand to zero above.
      expand_function_end will decrement this variable.  So, we set the
@@ -150,10 +185,26 @@
   immediate_size_expand = 1;
 
   /* Allow language dialects to perform special processing.  */
-  (*lang_hooks.rtl_expand.end) ();
+#if 0
+  if (EMIT_LLVM)
+  {
+    (*lang_hooks.llvm_expand.end) ();
+  }
+  else
+#endif
+  {
+    (*lang_hooks.rtl_expand.end) ();
+  }
 
   /* Generate rtl for function exit.  */
-  expand_function_end ();
+  if (EMIT_LLVM)
+  {
+    llvm_expand_function_end (LLVMFn, fndecl, 0);
+  }
+  else
+  {
+    expand_function_end ();
+  }
 
   /* If this is a nested function, protect the local variables in the stack
      above us from being collected while we're compiling this function.  */
@@ -165,7 +216,15 @@
   DECL_DEFER_OUTPUT (fndecl) = 0;
 
   /* Run the optimizers and output the assembler code for this function.  */
+#if EMIT_LLVM
+  if (EMIT_CODE_INCREMENTALLY)
+  {
+    llvm_function_print (LLVMFn, llvm_out_file);
+  }
+  cfun = 0;
+#else
   rest_of_compilation (fndecl);
+#endif
 
   /* Undo the GC context switch.  */
   if (nested_p)


Index: gcc-3.4/gcc/tree.c
diff -u gcc-3.4/gcc/tree.c:1.2 gcc-3.4/gcc/tree.c:1.3
--- gcc-3.4/gcc/tree.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/tree.c	Thu Feb  5 10:05:45 2004
@@ -4868,6 +4868,11 @@
   TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
   layout_type (long_double_type_node);
 
+  float_ptr_type_node = build_pointer_type (float_type_node);
+  double_ptr_type_node = build_pointer_type (double_type_node);
+  long_double_ptr_type_node = build_pointer_type (long_double_type_node);
+  integer_ptr_type_node = build_pointer_type (integer_type_node);
+
   complex_integer_type_node = make_node (COMPLEX_TYPE);
   TREE_TYPE (complex_integer_type_node) = integer_type_node;
   layout_type (complex_integer_type_node);


Index: gcc-3.4/gcc/tree.def
diff -u gcc-3.4/gcc/tree.def:1.2 gcc-3.4/gcc/tree.def:1.3
--- gcc-3.4/gcc/tree.def:1.2	Fri Jan  9 10:54:24 2004
+++ gcc-3.4/gcc/tree.def	Thu Feb  5 10:05:45 2004
@@ -615,13 +615,6 @@
    operand of the ABS_EXPR must have the same type.  */
 DEFTREECODE (ABS_EXPR, "abs_expr", '1', 1)
 
-/* Bit scanning and counting.  */
-DEFTREECODE (FFS_EXPR, "ffs_expr", '1', 1)
-DEFTREECODE (CLZ_EXPR, "clz_expr", '1', 1)
-DEFTREECODE (CTZ_EXPR, "ctz_expr", '1', 1)
-DEFTREECODE (POPCOUNT_EXPR, "popcount_expr", '1', 1)
-DEFTREECODE (PARITY_EXPR, "parity_expr", '1', 1)
-
 /* Shift operations for shift and rotate.
    Shift means logical shift if done on an
    unsigned type, arithmetic shift if done on a signed type.
@@ -638,7 +631,6 @@
 DEFTREECODE (BIT_IOR_EXPR, "bit_ior_expr", '2', 2)
 DEFTREECODE (BIT_XOR_EXPR, "bit_xor_expr", '2', 2)
 DEFTREECODE (BIT_AND_EXPR, "bit_and_expr", '2', 2)
-DEFTREECODE (BIT_ANDTC_EXPR, "bit_andtc_expr", '2', 2)
 DEFTREECODE (BIT_NOT_EXPR, "bit_not_expr", '1', 1)
 
 /* ANDIF and ORIF allow the second operand not to be computed if the


Index: gcc-3.4/gcc/tree.h
diff -u gcc-3.4/gcc/tree.h:1.2 gcc-3.4/gcc/tree.h:1.3
--- gcc-3.4/gcc/tree.h:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/tree.h	Thu Feb  5 10:05:45 2004
@@ -1654,6 +1654,11 @@
 #define DECL_ESTIMATED_INSNS(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
 
+/* Nonzero for a decl which is at file scope.  */
+#define DECL_FILE_SCOPE_P(EXP) 					\
+  (! DECL_CONTEXT (EXP)						\
+   || TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
+
 struct function;
 
 struct tree_decl GTY(())
@@ -1840,6 +1845,11 @@
   TI_DOUBLE_TYPE,
   TI_LONG_DOUBLE_TYPE,
 
+  TI_FLOAT_PTR_TYPE,
+  TI_DOUBLE_PTR_TYPE,
+  TI_LONG_DOUBLE_PTR_TYPE,
+  TI_INTEGER_PTR_TYPE,
+
   TI_VOID_TYPE,
   TI_PTR_TYPE,
   TI_CONST_PTR_TYPE,
@@ -1918,6 +1928,11 @@
 #define double_type_node		global_trees[TI_DOUBLE_TYPE]
 #define long_double_type_node		global_trees[TI_LONG_DOUBLE_TYPE]
 
+#define float_ptr_type_node		global_trees[TI_FLOAT_PTR_TYPE]
+#define double_ptr_type_node		global_trees[TI_DOUBLE_PTR_TYPE]
+#define long_double_ptr_type_node	global_trees[TI_LONG_DOUBLE_PTR_TYPE]
+#define integer_ptr_type_node		global_trees[TI_INTEGER_PTR_TYPE]
+
 #define complex_integer_type_node	global_trees[TI_COMPLEX_INTEGER_TYPE]
 #define complex_float_type_node		global_trees[TI_COMPLEX_FLOAT_TYPE]
 #define complex_double_type_node	global_trees[TI_COMPLEX_DOUBLE_TYPE]
@@ -2872,6 +2887,7 @@
 extern void init_dummy_function_start (void);
 extern void expand_dummy_function_end (void);
 extern void init_function_for_compilation (void);
+extern void allocate_struct_function (tree);
 extern void init_function_start (tree);
 extern void assign_parms (tree);
 extern void put_var_into_stack (tree, int);
@@ -2886,7 +2902,7 @@
 extern void push_temp_slots (void);
 extern void preserve_temp_slots (rtx);
 extern void preserve_rtl_expr_temps (tree);
-extern int aggregate_value_p (tree);
+extern int aggregate_value_p (tree, tree);
 extern void free_temps_for_rtl_expr (tree);
 extern void instantiate_virtual_regs (tree, rtx);
 extern void unshare_all_rtl (tree, rtx);


Index: gcc-3.4/gcc/varasm.c
diff -u gcc-3.4/gcc/varasm.c:1.2 gcc-3.4/gcc/varasm.c:1.3
--- gcc-3.4/gcc/varasm.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/varasm.c	Thu Feb  5 10:05:45 2004
@@ -434,8 +434,7 @@
     {
       flags = get_named_section_flags (name);
       if ((flags & SECTION_OVERRIDE) == 0)
-	error ("%H%D causes a section type conflict",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%J%D causes a section type conflict", decl, decl);
     }
 
   named_section_flags (name, flags);
@@ -564,8 +563,7 @@
 			  unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
 			  unsigned int flags ATTRIBUTE_UNUSED)
 {
-#ifdef HAVE_GAS_SHF_MERGE
-  if (flag_merge_constants
+  if (HAVE_GAS_SHF_MERGE && flag_merge_constants
       && TREE_CODE (decl) == STRING_CST
       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
       && align <= 256
@@ -627,7 +625,7 @@
 	    }
 	}
     }
-#endif
+
   readonly_data_section ();
 }
 
@@ -638,10 +636,9 @@
 			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
 			    unsigned int flags ATTRIBUTE_UNUSED)
 {
-#ifdef HAVE_GAS_SHF_MERGE
   unsigned int modesize = GET_MODE_BITSIZE (mode);
 
-  if (flag_merge_constants
+  if (HAVE_GAS_SHF_MERGE && flag_merge_constants
       && mode != VOIDmode
       && mode != BLKmode
       && modesize <= align
@@ -656,7 +653,7 @@
       named_section_flags (name, flags);
       return;
     }
-#endif
+
   readonly_data_section ();
 }
 
@@ -752,6 +749,9 @@
   int reg_number;
   rtx x;
 
+#ifdef abort
+#undef abort
+#endif
   LLVM_SHOULD_NOT_CALL();
 
   /* Check that we are not being given an automatic variable.  */
@@ -807,17 +807,15 @@
     {
       /* First detect errors in declaring global registers.  */
       if (reg_number == -1)
-	error ("%Hregister name not specified for '%D'",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%Jregister name not specified for '%D'", decl, decl);
       else if (reg_number < 0)
-	error ("%Hinvalid register name for '%D'",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%Jinvalid register name for '%D'", decl, decl);
       else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
-	error ("%Hdata type of '%D' isn't suitable for a register",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%Jdata type of '%D' isn't suitable for a register",
+	       decl, decl);
       else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
-	error ("%Hregister specified for '%D' isn't suitable for data type",
-               &DECL_SOURCE_LOCATION (decl), decl);
+	error ("%Jregister specified for '%D' isn't suitable for data type",
+               decl, decl);
       /* Now handle properly declared static register variables.  */
       else
 	{
@@ -861,8 +859,7 @@
      Also handle vars declared register invalidly.  */
 
   if (reg_number >= 0 || reg_number == -3)
-    error ("%Hregister name given for non-register variable '%D'",
-           &DECL_SOURCE_LOCATION (decl), decl);
+    error ("%Jregister name given for non-register variable '%D'", decl, decl);
 
   /* Specifying a section attribute on a variable forces it into a
      non-.bss section, and thus it cannot be common.  */
@@ -1061,18 +1058,23 @@
 notice_global_symbol (tree decl)
 {
   if ((!first_global_object_name || !weak_global_object_name)
-      && TREE_PUBLIC (decl)
+      && TREE_PUBLIC (decl) && !DECL_COMMON (decl)
       && (TREE_CODE (decl) == FUNCTION_DECL
-	  || ! (DECL_COMMON (decl)
-	    	&& (DECL_INITIAL (decl) == 0
-		    || DECL_INITIAL (decl) == error_mark_node))))
+	  || (TREE_CODE (decl) == VAR_DECL
+	      && (DECL_INITIAL (decl) != 0
+		  && DECL_INITIAL (decl) != error_mark_node))))
     {
       const char *p;
       char *name;
-      rtx decl_rtl = DECL_RTL (decl);
+      if (EMIT_LLVM) {
+        struct llvm_value* LLVMDecl = DECL_LLVM(decl);
+        name = ((LLVMDecl==NULL)?NULL:xstrdup(llvm_get_decl_name(LLVMDecl)));
+      } else {
+        rtx decl_rtl = DECL_RTL (decl);
 
-      p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0));
-      name = xstrdup (p);
+        p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0));
+        name = xstrdup (p);
+      }
 
       if (! DECL_WEAK (decl) && ! DECL_ONE_ONLY (decl))
 	first_global_object_name = name;
@@ -1393,9 +1395,7 @@
 
   if (!dont_output_data && DECL_SIZE (decl) == 0)
     {
-      error ("%Hstorage size of `%s' isn't known",
-             &DECL_SOURCE_LOCATION (decl),
-             IDENTIFIER_POINTER (DECL_NAME (decl)));
+      error ("%Jstorage size of `%D' isn't known", decl, decl);
       TREE_ASM_WRITTEN (decl) = 1;
       return;
     }
@@ -1428,8 +1428,7 @@
   if (! dont_output_data
       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
     {
-      error ("%Hsize of variable '%D' is too large",
-             &DECL_SOURCE_LOCATION (decl), decl);
+      error ("%Jsize of variable '%D' is too large", decl, decl);
       return;
     }
 
@@ -1455,9 +1454,9 @@
 #endif
   if (align > MAX_OFILE_ALIGNMENT)
     {
-      warning ("%Halignment of '%D' is greater than maximum object "
-               "file alignment.  Using %d", &DECL_SOURCE_LOCATION (decl),
-               decl, MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
+      warning ("%Jalignment of '%D' is greater than maximum object "
+               "file alignment.  Using %d", decl, decl,
+	       MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
       align = MAX_OFILE_ALIGNMENT;
     }
 
@@ -1523,9 +1522,8 @@
 
 #if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
       if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
-	warning ("%Hrequested alignment for '%D' is greater than "
-                 "implemented alignment of %d", &DECL_SOURCE_LOCATION (decl),
-                 decl, rounded);
+	warning ("%Jrequested alignment for '%D' is greater than "
+                 "implemented alignment of %d", decl, decl, rounded);
 #endif
 
       /* If the target cannot output uninitialized but not common global data
@@ -1653,16 +1651,14 @@
 /* Similar, for calling a library function FUN.  */
 
 void
-assemble_external_libcall (rtx fun ATTRIBUTE_UNUSED)
+assemble_external_libcall (rtx fun)
 {
-#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
   /* Declare library function name external when first used, if nec.  */
   if (! SYMBOL_REF_USED (fun))
     {
       SYMBOL_REF_USED (fun) = 1;
-      ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
+      (*targetm.asm_out.external_libcall) (fun);
     }
-#endif
 }
 
 /* Assemble a label named NAME.  */
@@ -1686,7 +1682,7 @@
 	{
 	  node = cgraph_node_for_identifier (id);
 	  if (node)
-	    cgraph_mark_needed_node (node, 1);
+	    cgraph_mark_needed_node (node);
 	}
 
       vnode = cgraph_varpool_node_for_identifier (id);
@@ -3500,11 +3496,27 @@
 	   || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
 	  && TREE_CONSTANT (value)
 	  && CONSTRUCTOR_ELTS (value))
-	return
-	  initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
-					endtype);
+	{
+	  tree elt;
+	  bool absolute = true;
+
+	  for (elt = CONSTRUCTOR_ELTS (value); elt; elt = TREE_CHAIN (elt))
+	    {
+	      tree reloc;
+	      value = TREE_VALUE (elt);
+	      reloc = initializer_constant_valid_p (value, TREE_TYPE (value));
+	      if (!reloc)
+		return NULL_TREE;
+	      if (reloc != null_pointer_node)
+		absolute = false;
+	    }
+	  /* For a non-absolute relocation, there is no single
+	     variable that can be "the variable that determines the
+	     relocation."  */
+	  return absolute ? null_pointer_node : error_mark_node;
+	}
 
-      return TREE_STATIC (value) ? null_pointer_node : 0;
+      return TREE_STATIC (value) ? null_pointer_node : NULL_TREE;
 
     case INTEGER_CST:
     case VECTOR_CST:
@@ -4221,17 +4233,16 @@
 	 declare_weak because the NEWDECL and OLDDECL was not yet
 	 been merged; therefore, TREE_ASM_WRITTEN was not set.  */
       if (TREE_ASM_WRITTEN (olddecl))
-	error ("%Hweak declaration of '%D' must precede definition",
-               &DECL_SOURCE_LOCATION (newdecl), newdecl);
+	error ("%Jweak declaration of '%D' must precede definition",
+	       newdecl, newdecl);
 
       /* If we've already generated rtl referencing OLDDECL, we may
 	 have done so in a way that will not function properly with
 	 a weak symbol.  */
       else if (TREE_USED (olddecl)
 	       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
-	warning ("%Hweak declaration of '%D' after first use results "
-                 "in unspecified behavior",
-                 &DECL_SOURCE_LOCATION (newdecl), newdecl);
+	warning ("%Jweak declaration of '%D' after first use results "
+                 "in unspecified behavior", newdecl, newdecl);
 
       if (SUPPORTS_WEAK)
 	{
@@ -4264,19 +4275,16 @@
 declare_weak (tree decl)
 {
   if (! TREE_PUBLIC (decl))
-    error ("%Hweak declaration of '%D' must be public",
-           &DECL_SOURCE_LOCATION (decl), decl);
+    error ("%Jweak declaration of '%D' must be public", decl, decl);
   else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
-    error ("%Hweak declaration of '%D' must precede definition",
-           &DECL_SOURCE_LOCATION (decl), decl);
+    error ("%Jweak declaration of '%D' must precede definition", decl, decl);
   else if (SUPPORTS_WEAK)
     {
       if (! DECL_WEAK (decl))
 	weak_decls = tree_cons (NULL, decl, weak_decls);
     }
   else
-    warning ("%Hweak declaration of '%D' not supported",
-             &DECL_SOURCE_LOCATION (decl), decl);
+    warning ("%Jweak declaration of '%D' not supported", decl, decl);
 
   mark_weak (decl);
 }


Index: gcc-3.4/gcc/version.c
diff -u gcc-3.4/gcc/version.c:1.2 gcc-3.4/gcc/version.c:1.3
--- gcc-3.4/gcc/version.c:1.2	Thu Jan  8 17:03:27 2004
+++ gcc-3.4/gcc/version.c	Thu Feb  5 10:05:45 2004
@@ -5,7 +5,7 @@
    please modify this string to indicate that, e.g. by putting your
    organization's name in parentheses at the end of the string.  */
 
-const char version_string[] = "3.4-llvm 20030827 (experimental)";
+const char version_string[] = "3.4-llvm 20030924 (experimental)";
 
 /* This is the location of the online document giving instructions for
    reporting bugs.  If you distribute a modified version of GCC,





More information about the llvm-commits mailing list